IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 微信小程序裁剪视频部分内容导出 -> 正文阅读

[移动开发]微信小程序裁剪视频部分内容导出

如果是单纯的想裁剪视频的话,微信小程序提供了一个非常便捷的API openVideoEditor
如果要更换音频轨道,或者在为视频增加什么样式,就会分别获取到视频的视频轨道和音频轨道和视频的每一帧
首先是获取视频的每一帧

1·获取视频的帧

微信小程序提供了 createVideoDecoder API用来解析视频的帧数,虽然我用的时候总是感觉丢帧,但目前也没找到别的办法

步骤
要获取视频的帧,首先要知道一个视频有多少帧
通过wx.getVideoInfo获取到视频信息包括fps和duration
我们可以通过上面获取的信息获取视频总共有多少帧数(fps*duration)

下面我们来获取视频的帧,并生成每一帧的图片,会用到 createOffscreenCanvas这个API用来创建一个离屏画布

首先如果是选择视频的话可以直接获取到视频信息,如果是网络链接的要通过 wx.downloadFile 把视频下拉获取到本地的临时链接
可以是网络视频 也可以是自己的视频,下面的案例是我本地的视频,视频时长不宜太长,不然小程序容易崩掉

关键逻辑处理在getFrameData这个方法中,大致意思:获取的帧的数据是一个数组里面存储着图片的像素值

如果是1px*1px的图像那这个数组的长度就为4[0,0,0,255]代表着一个黑色不透明的像素点,图像就是由这么一个一个的像素组成,我们可以通过canvasAPI把这些像素绘制出来并且导出

需要注意的是,如果导入像素点的数量和画布实际的绘制大小有出入会导致错误,就像上面说的一样,如果你要把[0,0,0,255]绘制到两个像素这明显是不合理的

 Page({
 // 链接可能会过期换成自己的就行
	data:{
	    "audioUrl": "https://dl.stream.qqmusic.qq.com/C4000026gMkr1L9tKN.m4a?guid=7840612806&vkey=4696DBD6111F38EC3D75D0F4FDF769B3736068A795CF585BA18DF3A4BCD8F83D0662B54D70F64934AF74A34C9A354AFF0AA4660CCE4C66F0&uin=&fromtag=120032",
    videoUrl: "https://yun-live.oss-cn-shanghai.aliyuncs.com/video/20201225/2EbJdXN5ZG.mp4",
    videoInfo: {},
    canvasWidth: 0,
    canvasHeight: 0,
    fps: 0,
    duration: 0,
    imageList: []
	 },
	  onLoad() {
	    this.videoDecoderStart()
	  },
	   async videoDecoderStart() {
	   // 自己选择视频
    var {tempFilePath} = await wx.chooseVideo()
    console.log(tempFilePath)
     // 网络视频
    // wx.showLoading({
    //   title: '加载中...',
    // })
    // var {
    //   tempFilePath
    // } = await this.getTempPath(this.data.videoUrl)
    // wx.hideLoading()
    var videoInfo = await wx.getVideoInfo({
      src: tempFilePath,
    })
    this.setData({
      videoInfo: videoInfo,
      canvasWidth: videoInfo.width,
      canvasHeight: videoInfo.height,
      duration: videoInfo.duration,
      fps: videoInfo.fps
    }, () => {
      // 创建视频解析器
      this.videoDecoder = wx.createVideoDecoder()
      const {
        canvas,
        context
      } = this.initOffscreenCanvas(this.data.canvasWidth, this.data.canvasWidth)
      this.videoDecoder.on("start", () => {
        this.videoDecoder.seek(0)
        this.timer = setInterval(() => {
          this.getFrameData(canvas, context)
        }, 300);
      })
      this.videoDecoder.on("seek", () => {})
      this.videoDecoder.on("stop", () => {})
      this.videoDecoder.start({
        source: tempFilePath
      })
    })
  },
  getFrameData(canvas, context) {
    var func = (() => {
      var imageVideoData = this.videoDecoder.getFrameData()
      if (imageVideoData) {
        if (this.timer) {
          clearInterval(this.timer)
          this.timer = null
        }
        context.clearRect(0, 0, this.data.canvasWidth, this.data.canvasHeight)
        var imgData = context.createImageData(this.data.canvasWidth, this.data.canvasHeight)
        var clampedArray = new Uint8ClampedArray(imageVideoData.data)
        for (var i = 0; i < clampedArray.length; i++) {
          imgData.data[i] = clampedArray[i];
        }
        context.putImageData(imgData, 0, 0)
        this.data.imageList.push(canvas.toDataURL())
        this.setData({
          imageList: this.data.imageList
        }, () => {
          canvas.requestAnimationFrame(func)
        })
      }
    })
    func()

  },
 	getTempPath(url){
   	 return new Promise((r,j) => {
      wx.downloadFile({
        url: url,
        success:r,
        fail:j
      })
    })
  },
  // 创建一个离屏画布,因为只是单纯的绘制图片,就不要预览了只需要看
   initOffscreenCanvas(canvasWidth,canvasHeight){
    const canvas = wx.createOffscreenCanvas({
      type: '2d',
      width: canvasWidth,
      height: canvasHeight
    })
   return {
      canvas,
      context: canvas.getContext('2d')
    }
  },
})
 

2·展示视频的帧

获取到视频的帧之后,当然就要展示出来,下面是我展示的一些样式以及代码

请添加图片描述
代码部分

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:34:46  更:2022-07-17 16:35:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 4:07:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码