JavaScript实现读取上传视频文件的时长和第一帧画面过程讲解

来自:网络
时间:2023-05-17
阅读:
目录

前言

当我们做一个后台系统的音频管理模块时,通常需要将我们上传的视频做一个前端的提前处理。首先是我们对于文件的大小要限制,文件类型做限制,然后还会有些特定的要求,比如自动去读取文件的一些信息,传递给后端。当然这些可以在后端进行完成,但是相对而言,将资源的消耗放在前端这一块是会相对减轻后端压力的。这里主要介绍要如何获取前端的第一帧画面和视频的时长,画面可以辅助我们设置新建信息的视频封面图,时长能让用户更直观地感觉到文件的准确性和大小。

获取视频时长

获取时长比第一帧画面的获取相对容易一些,但是两者有一个共同的需要,那就是需要在我们的html代码中添加video标签,并且将我们想要获取信息的视频地址放到标签的链接中。

获取时长的话,只需要给视频element添加一个监听事件,loadedmetadata。在这个监听事件中我们可以获取到audioElement对象,在该对象中便有视频时长的参数。

getVideoDuration(file) {
  var url = URL.createObjectURL(file);
  var audioElement = new Audio(url);
  var self = this;
  var result;
  audioElement.addEventListener("loadedmetadata", function() {
    // 视频时长值的获取要等到这个匿名函数执行完毕才产生
    result = audioElement.duration; //得到时长为秒,小数,182.36
    self.ruleForm.videoDuration = parseInt(result); //转为int值
  });
}

获取第一帧画面

首先我们需要明白,视频在我们的页面是如何去运作的。前端目前我所知道的想要跟视频产生联系的方式就是video标签,所以我们需要有一个video标签,然后将视频地址添加进去,才有办法获得该视频的一些信息。

①第一步需要将用户上传的文件转化为blob地址,当然有一些情况我们是可以直接获取到后端传递过来的地址的,但是当我们需要将视频和表单一起提交时,就没办法做到这样有一个先后的顺序。所以我们要自食其力,把视频转为地址,加载到音频标签中。

const file = '.....'
const a = new FileReader();
a.readAsDataURL(file);
a.onload = (e) => {
	const blob = new Blob([e.target.result], { type: file.type }) // 如果发现乱码检查一下type赋值的对不对
}

②第二步,众所周知,如果视频加载成功了,那我们的video正确加载了,是会显示视频的第一帧画面的,所以这个时候我们就可以用canvas去截图,将第一帧的画面截下来,再转成base64,当然最后如果需要把封面一同上传,我们可以将base64转file。

findvideocover() {
        let size = 160
        // 获取video节点
        const video = document.getElementById("videoPlay");
        video.width = size
        video.height = size
        video.currentTime = 1 // 第一帧
        //创建canvas对象
        const canvas = document.createElement("canvas")
        canvas.width = size
        canvas.height = size
        this.$nextTick(()=>{
          // 利用canvas对象方法绘图
          canvas.getContext("2d").drawImage(video, 0, 0, canvas.width, canvas.height);
          // 转换成base64形式
          const img = canvas.toDataURL("image/jpeg") // 这个就是图片的base64
          this.coverUrl = img
        })
      }

base64转file

const arr = base64.split(',')
const type = arr[0].match(/:(.*?);/)[1]
const size = window.atob(arr[1])
let n = size.length
const u8arr = new Uint8Array(n)
while (n--) {
  u8arr[n] = size.charCodeAt(n)
}
const file = new File([u8arr], name, { type })

结语

这两个功能并不复杂,只要理解其中的原理和流程就可以很简单的达到效果。主要是将视频从file转为blob是否能够正常加载到video中,如若不能,则需要请求后端的帮助,先将视频传递上去后获取到文件的地址,再去执行这一读取第一帧画面作为封面的功能。

返回顶部
顶部