做视频处理时,会有截屏的场景,也称视频快照。今天介绍一下多张快照和单点快照。
视频快照
- 支持单点快照,即视频播放到某个时间点,获取快照
- 多张快照,即从某个时间点开始,间隔一定时间,批量生成多张快照
- 可定制快照张数
- 可定制快照时间间隔
- 快照可下载
代码实现
- canvas绘制截屏
// 截图
function captureScreenshot() {
const {width,height} = mediaInfo;
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d')!;
// 设置画布尺寸为视频原始分辨率
canvas.width = width;
canvas.height = height;
// 绘制视频帧到画布
ctx.drawImage(videoRef.current!, 0, 0, canvas.width, canvas.height);
const url = canvas.toDataURL('image/png');
return url;
}
- 多张快照
// batch 批量生成快照
const batchCreateShots = async(count:number) => {
if (!file) {
alert('请先选择文件');
};
setloading(true);
setList([]);
// 获取当前视频时间点
const cur_time = videoRef.current!.currentTime;
for (let i = 0; i < count i const video='videoRef.current;' ifvideo return const time='+(cur_time' i intervaltime.tofixed2 const currenttime='Math.min(time,mediaInfo.duration);' videoref.current.currenttime='currentTime;' await new> {
// 监听视频帧绘制完成事件
videoRef.current!.addEventListener('seeked', async()=>{
resolve(true);
}, { once: true });
});
console.log('videoRef.current!.currentTime===', videoRef.current!.currentTime);
const url = captureScreenshot();
setList(pre=>[...pre,url]);
await sleep(100);
}
setloading(false);
}
- 获取音视频的信息
/**
* 获取音视频文件的元数据信息
* @param file - 音视频文件对象
* @returns 包含文件名、大小、时长、分辨率、类型等信息的Promise对象
*/
export async function getMediaInfo(file: File): Promise<{ name: string size: number duration: number width: number height: number type: string> {
return new Promise((resolve, reject) => {
const video = document.createElement('video');
video.preload = 'metadata';
video.src = URL.createObjectURL(file);
video.onloadedmetadata = () => {
resolve({
name: file.name,
size: file.size,
type: file.type,
duration: video.duration,
width: video.videoWidth,
height: video.videoHeight
});
URL.revokeObjectURL(video.src); // 释放内存
};
video.onerror = (error) => {
URL.revokeObjectURL(video.src);
reject(new Error('无法解析媒体文件'));
};
});
}
- 设置多张快照时,注意监听视频的seeked事件,该事件是视频播放位置变化时的回调函数,可用于video.currentTime = xx时的,去调用快照方法。
- 完整代码在next-demo: next-demo,感兴趣的朋友可以看看