赞
踩
在这样一个图像化极其重要的时代,从视频中提取精彩瞬间,即视频帧截图的技术,已成为前端开发中的一个亮点。JavaScript作为网页动态效果和交互的主力军,其在视频处理领域能力逐渐被挖掘和重视,尤其是视频帧截图技术的应用,为网站和应用程序提供了更为丰富和直观的用户体验。
在一些媒体网站上传作品后,通常都会让你选择视频中的某个画面作为封面,这个封面可以吸引观众的注意力,让他们对你的视频产生兴趣。那么,如何实现视频帧截图呢?本文将介绍如何使用JavaScript来实现这一功能。
大体为以下流程:
选择本地视频文件
<input type="file">
const input = document.querySelector('input');
input.onchange = async (e) => {
const file = e.target.files[0];
console.log(file);
}
创建一个video标签,把视频文件放到video标签中。使用 createObjectURL 方法把视频文件对象转为一个url。
const video = document.createElement("video");
video.src = URL.createObjectURL(file);
// 设置视频自动播放
video.autoplay = true;
// 设置视频播放的时间点
video.currentTime = 10;
使用 createObjectURL
创建的URL是一个blob:开头的临时路径,这个路径可以在浏览器中直接访问,访问到的内容就是上传的视频文件。当页面关闭后,此路径也随之失效。
通过 currentTime
设置需要截图的时间点,由于创建的video标签未加到页面中,所以这里设置了自动播放后,不会继续播放10s后的内容,而是停留在10s的位置。
现在视频停留在了指定帧的位置,接下来就通过 canvas来绘制当前帧。
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = vdo.videoWidth;
canvas.height = vdo.videoHeight;
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
document.body.appendChild(canvas);
将canvas内容转为一个可用img标签展示的url地址,这个过程需要两步:
toBlob
方法创造一个Blob对象createObjectURL
方法把对象转为可访问的URLfunction drawVideo(vdo) {
return new Promise((resolve) => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = vdo.videoWidth;
canvas.height = vdo.videoHeight;
ctx.drawImage(vdo, 0, 0, canvas.width, canvas.height);
canvas.toBlob((blob) => {
resolve({
blob,
url: URL.createObjectURL(blob)
});
})
})
}
由于 toBlob 是采用回调函数的方式调用,所以封装drawVideo 方法返回为一个promise。
从上图可以看到抖音平台下面展示的预览图同样也是以blob:开头的临时地址。
当video标签设置url后,不能马上截图,视频加载需要一个过程,要等视频可以播放后再截图。
video.oncanplay = async () => {
const frame = await drawVideo(video);
}
封装完整的截图方法,由于oncanplay
同样是一个异步方法,这里也需要返回一个promise
function captureFrame(file, time) {
return new Promise((resolve) => {
const video = document.createElement("video");
video.autoplay = true;
video.currentTime = time;
video.src = URL.createObjectURL(file);
video.oncanplay = async () => {
const frame = await drawVideo(video);
resolve(frame);
}
})
}
获取视频时长,按照每1秒的间隔截一张图
const video = document.createElement("video");
video.src = URL.createObjectURL(file);
// 视频加载完成后,才能获取到视频的时长
video.onloadedmetadata = async () => {
for (let index = 0; index < video.duration; index++) {
const frame = await captureFrame(file, index);
// 将截图加入到页面中展示
const img = document.createElement("img");
img.src = frame.url;
img.style.width = "100px";
document.body.appendChild(img);
}
};
尽管视频帧截图技术带来了许多便利,但在实际应用过程中也面临着一些挑战:
随着前端技术的不断进步,未来视频帧截图技术将变得更加高效和用户友好。Web Assembly和FFmpeg等技术的发展有望进一步提升前端处理视频的能力,使得视频帧截图更加迅速和精确。
关注公众号【前端筱园】,回复“视频帧截图”获取本案例源码及素材
欢迎访问我的个人网站:www.dengzhanyong.com
欢迎加入前端筱园交流群:
关注我的公众号【前端筱园】,不错过每一篇推送
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。