前言
我之前分享过一篇文章 【音视频处理】纯js实现上传视频,截取关键帧作为封面,上传后端保存 ,这个文章可以获取视频第一帧作为封面图,但是视频第一帧有时候是黑的,怎么办呢?今天介绍一个获取视频任何一帧的方法。
方法
其实原理都是一样的,都是用canvas绘制
代码如下:
const handleGetVideoThumb = function (url, options = {}) {
if (typeof url != 'string') {
return;
}
// 默认参数
const defaults = {
seekTime :1,
onLoading: () => {},
onLoaded: () => {},
onFinish: (thumbData) => {},
};
const params = Object.assign({}, defaults, options);
// 基于视频元素绘制缩略图,而非解码视频
const video = document.createElement('video');
// 静音
video.muted = true;
// 绘制缩略图的canvas画布元素
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d', {
willReadFrequently: true,
});
// 绘制缩略图的标志量
let isTimeUpdated = false;
// 几个视频事件
// 1. 获取视频尺寸
video.addEventListener('loadedmetadata', () => {
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
// 开始执行绘制
draw();
});
// 2. 触发绘制监控
video.addEventListener('timeupdate', () => {
isTimeUpdated = true;
});
// 获取视频数据
params.onLoading();
// 请求视频地址,如果是本地文件,直接执行
if (/^blob:|base64,/i.test(url)) {
video.src = url;
} else {
fetch(url)
.then((res) => res.blob())
.then((blob) => {
params.onLoaded();
// 赋予视频
video.src = URL.createObjectURL(blob);
});
}
// 绘制方法
const draw = () => {
const thumbData = [];
const duration = video.duration;
video.currentTime = params.seekTime;
const onSeeked = () => {
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(video, 0, 0, canvas.width, canvas.height);
canvas.toBlob((blob) => {
thumbData.push(URL.createObjectURL(blob));
params.onFinish(thumbData);
}, 'image/jpeg');
};
video.addEventListener('seeked', onSeeked);
};
};
使用
handleGetVideoThumb ('xxx.haorooms.com/video.mp4',{
seekTime :5,// 截取第5s视频
onFinish:(data)=>{
// 图片数据,可以上传
}
})
这样就完成了,简单记录一下。