简述
背景:用户在Web页面进行视频文件的上传操作,前端在进行原视频文件上传的同时,需要额外做两件事情:
- 获取视频的宽高尺寸、大小,判断是否符合上传要求
- 截取视频的第一帧作为视频的缩略展示图,与原视频文件一并上传
流程示意图如下:
后台预加载
使用video标签对象加载视频文件(此处我们并不需要视频文件完全加载,第一帧数据可用即可)。
// file为视频的文件对象,可使用 input[file] 进行获取
loadVideo = function(file) {
return new Promise(function(resolve, reject) {
const videoElem = document.createElement('video')
const dataUrl = URL.createObjectURL(file)
// 当前帧的数据是可用的
videoElem.onloadeddata = function() {
resolve(videoElem)
}
videoElem.onerror = function() {
reject('video 后台加载失败')
}
// 设置 auto 预加载数据, 否则会出现截图为黑色图片的情况
videoElem.setAttribute('preload', 'auto')
videoElem.src = dataUrl
})
}
获取视频的尺寸,播放时长
在上一节的video标签对象加载视频文件完后,即可直接通过video标签对像来获取尺寸和播放时长等信息。
//获取视频时长, 尺寸
loadVideo(file).then(video => {
// 时长
const duration = video.duration
// 宽
const width = video.videoWidth
// 高
const height = videoHeight
})
获取视频的第一帧图片
在第一步加载视频文件的基础上,通过canvas对象来绘制视频的第一帧信息,并将该绘制结果导出成图片文件(即为第一帧图片)。
loadVideo(file).then(video => {
const canvasElem = document.createElement('canvas')
const { videoWidth, videoHeight } = videoElem
canvasElem.width = videoWidth
canvasElem.height = videoHeight
canvasElem.getContext('2d').drawImage(videoElem, 0, 0, videoWidth, videoHeight)
// 导出成blob文件
canvasElem.toBlob(blob => {
// 将blob文件转换成png文件
const thumbFile = toThumbFile(blob)
}, 'image/png')
})
其中,toThumbFile
的作用是将blob文件转成file文件
const toThumbFile = blob => new File([blob], 'thumb__img.png')
附:onloadeddata
当当前帧的数据已加载,但没有足够的数据来播放指定音频/视频的下一帧时,会发生 loadeddata 事件。 当音频/视频处于加载过程中时,会依次发生以下事件:
- loadstart
- durationchange
- loadedmetadata
- loadeddata
- progress
- canplay
- canplaythrough