小视频去水印原理及其代码?

使用uview框架及其微信小程序云开发 仅供学习和交流,

小视频去水印原理及其代码?_第1张图片

首先讲一下原理 具体看下边

https://www.cnblogs.com/raicho/p/16025522.html

这个还是比较简单的,如果自己会一点后端,根据上面的步骤慢慢来,我这里为了省事,使用了云函数基于nodejs作为后端 并且调用了第三方api。

为什么要使用微信云开发 性能非常慢,加上时间原因就没自己写后端, 而且用到了微信云存储,为什么?如果你为了图方便你可以在微信小程序的后台管理 页面把所有的视频去水印白名单给写上 目前我所知道的有将近两百个如果你单纯是纯粹去水印的话 ,不需要云存储云开发也是可以的,直接添加将近两百个域名白名单,这样极大节省流量及其费用,因为前端返回去水印链接需要添加上域名白名单这样用户才可以自主下载,否则因为跨域限制无法下载,那么接下来就需要用到自己的微信云函数了。在后台将这些链接处理好 并上传到云存储 再将云存储的每个id传递给用户 让用户下载 这样就不涉及跨域了,

为什么我写到后台就是因为域名白名单限制并且不仅仅做的这一个功能。虽然只是随手写写的,下个月就到期了。。。。。。

下面是前端代码 样式及其页面


            
            
                
                    
                        
                            
                                
                                    
                                
                            
                            
                                
                                    获取
                                
                            
                        
                    
                    
                
        
                
                
                    
                    
                
            

export default {
    data() {
        return {
            //加载框
            jiazai: [
                {
                    type: 'loading',
                    message: '正在解析',
                    duration: '6000'
                }
            ],
            inputRadioUrl: '',
            radioUrl: '',
            //文案内容
            textContent: '',
            imgUrl: '',
            links: '',

            srcs: ''
        };
    },

    methods: {
        //加载框
        showToast(params) {
            let that = this;
            this.$refs.uToast.show({
                ...params
            });
            that.getRadio();  //获取后端的数据 去水印的连接
        },

这里的原理是这样的,先从后端获取到去水印的链接及其文案内容, 跳转页面链接后顺便将链接将传递到后台,为什么要这么做,一方面是为了便于当前页面可以添加广告 另外一方面也是为了节省服务器流量,后面请听我说
        getRadio() {
            let that = this;
            const regex = /https?:\/\/v\.douyin\.com\/\w+\//; // 匹配链接
            this.links = this.inputRadioUrl.match(regex) || [];
            // console.log(this.links)
            if (this.inputRadioUrl.length === 0 && !this.inputRadioUrl.includes('http://') && !this.inputRadioUrl.includes('https://')) {
                uni.showToast({
                    title: '去除失败,请稍后重试',
                    icon: 'none'
                });
                console.log(this.inputRadioUrl);
            } else {
                wx.cloud.callFunction({
                    name: 'dy',
                    data: {
                        functionName: 'dyUrl',
                        url: that.links[0]
                    },
                    success: function(res) {
                        if (res.result.code == 200) {
                            if (res.result.data.type == 1) {
                                that.textContent = res.result.data.title;
                                that.radioUrl = res.result.data.video_url;
                                that.$refs.uToast.hide();
                                uni.navigateTo({
                                    url: '/pages/tool/dy/dyhandle?textContent=' + that.textContent + '&radioUrl=' + that.radioUrl
                                });
                            } else if (res.result.data.type == 2) {
                                that.imgUrl = res.result.data.imgs;
                                that.textContent = res.result.data.title;
                                let imgs = JSON.stringify(that.imgUrl);
                                that.$refs.uToast.hide();
                                uni.navigateTo({
                                    url: '/pages/tool/dy/dyhandle?imgUrl=' + imgs + '&textContent=' + that.textContent
                                });
                            }else{
                                uni.showToast({
                                    title: '解析失败,稍后重试',
                                    icon: 'none'
                                });
                            }
                        }else{
                            uni.showToast({
                                title: '后台解析失败,稍后重试',
                                icon: 'none'
                            });
                        }
                
                    },
                    fail: function(err) {
                        uni.showToast({
                            title: '解析失败,稍后重试',
                            icon: 'none'
                        });
                        that.$refs.uToast.hide();
                    }
                });
            }
        }
    }
};

云函数代码


const cloud = require('wx-server-sdk')
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境
const axios = require('axios')

//解析链接 返回给前端
async function dyUrl(url) {
  const token = '点兵点将'
  const apiUrl = '直接找个第三方api吧'
  const params = { token, url };
  try {
    const response = await axios.get(apiUrl, { params }); // 发送 HTTP 请求
    const data = response.data;
    if (data.code === 200) {
      return data;
    } else {
      return data.msg;
    }
  } catch (err) {
    console.error(err);
    return err;
  }
};

//当用户点击保存视频时 前端获取到上一个方法返回的连接,上传到本地云存储返回云存储连接后给用户下载
async function uploadDy(Video_url) {
  try {
      const { data: videoData } = await axios.get(Video_url, { responseType: 'arraybuffer' })
      const fileSize = videoData.byteLength/1024/1024 // 计算视频大小
      if (fileSize > 100) { // 判断是否超过100M
        return { type: 'error', msg: '上传的视频超过100M' }
      }
      const { fileID } = await cloud.uploadFile({
        cloudPath: `videos/${Date.now()}.mp4`,
        fileContent: videoData,
      })
      
      return { type: 'video', Video_urls: fileID}
  } catch (error) {
    console.error(error)
    return error
  }
}
//当用户点击保存图片时 前端获取到上一个方法返回的连接,上传到本地云存储返回云存储连接后给用户下载
async function uploadDyTupian(tupian_url) {

  try {
         const pictureIds = []
         const tasks = []
         let pictureSize = 0 // 总图片大小
         for (let i = 0; i < tupian_url.length; i++) {
           tasks.push(
             (async () => {
               try {
                 const { data: imageData } = await axios.get(tupian_url[i], { responseType: 'arraybuffer' })
                 const fileSize = imageData.byteLength/1024/1024 // 计算单张图片大小
                 pictureSize += fileSize
                 if (pictureSize > 20) { // 判断是否超过20M
                   return { type: 'error', msg: '上传的图片总大小超过20M' }
                 }
                 const { fileID } = await cloud.uploadFile({
                   cloudPath: `dyPicture/${Date.now()}/${i + 1}.jpg`,
                   fileContent: imageData,
                 })
                 pictureIds.push(fileID)
                 console.log('上传成功', fileID)
                 // return pictureIds // 返回数组
               } catch (error) {
                 console.error('上传失败', error)
               }
             })()
           )
         }
         await Promise.all(tasks)
         return { type: 'picture', imgs_url: pictureIds} // 将返回值放在异步任务的外部
   
  } catch (error) {
    console.error(error)
    return error
  }
}




// 云函数入口函数
exports.main = async (event, context) => {
  const { functionName, url} = event
  try {
    if (functionName === 'dyUrl') {
      return await dyUrl(url)
    } else if (functionName === 'uploadDy') {
      return await uploadDy(url)
    } else if(functionName==='uploadDyTupian'){
          return await uploadDyTupian(url)
    }
    else {
      return { type: 'error', msg: '无效的函数名' }
    }
  } catch (error) {
    console.error(error)
    return { type: 'error', msg: error.message }
  }
}
小视频去水印原理及其代码?_第2张图片

处理页面






只是讲一下大概原理。有些地方写的还不是特别好,多多交流

小程序demo效果,可以试一试

小视频去水印原理及其代码?_第3张图片

你可能感兴趣的:(uni-app,微信小程序,前端,javascript,vue.js)