在Angular中提取视频帧时如何获取上传视频的总帧数
视频上传时获取总帧数的实现方法
你可以通过创建临时HTMLVideoElement加载视频元数据的方式,在上传阶段直接拿到准确的总帧数,不需要手动预估,具体实现逻辑如下:
- 监听文件上传的change事件,拿到选中的视频File对象
- 创建临时video元素,绑定元数据加载完成的回调
- 从加载完成的元数据中读取总帧数
对应的Angular代码示例:
// 上传文件change事件回调 onVideoUpload(event: Event) { const input = event.target as HTMLInputElement; if (!input.files?.length) return; const videoFile = input.files[0]; // 创建临时video元素加载元数据 const tempVideo = document.createElement('video'); tempVideo.preload = 'metadata'; tempVideo.src = URL.createObjectURL(videoFile); tempVideo.onloadedmetadata = () => { // 方式1:直接读取视频轨道的总帧数(兼容性较好,支持大部分现代浏览器) const totalFrames = tempVideo.videoTracks?.[0]?.numberOfFrames; // 方式2:如果方式1返回undefined,可以用视频时长*帧率计算(适用于固定帧率视频) const frameRate = tempVideo.videoTracks?.[0]?.frameRate ?? 30; // 无帧率返回时默认取30 const calculatedFrames = Math.round(tempVideo.duration * frameRate); const finalTotalFrames = totalFrames ?? calculatedFrames; console.log('视频总帧数:', finalTotalFrames); // 拿到总帧数后再调用帧提取方法即可 this.loadImages(finalTotalFrames); // 释放临时URL,避免内存泄漏 URL.revokeObjectURL(tempVideo.src); }; } // 调整原有提取方法,接收总帧数作为参数 loadImages(totalFrames: number) { this.loading = true; this.video.getFrames('/assets/ForBiggerBlazes.mp4', totalFrames, VideoToFramesMethod.totalFrames).then((frames) => { console.log(frames); frames.forEach((frame) => { const canvas = document.createElement('canvas'); canvas.width = frame.width; canvas.height = frame.height; canvas.getContext('2d')?.putImageData(frame, 0, 0); document.getElementsByTagName('div')[0].appendChild(canvas); }); this.loading = false; }); }
注意事项
- 部分老旧浏览器可能不支持
videoTracks属性,这种情况优先选用时长乘帧率的计算方式;如果对帧数精度要求极高,也可以结合requestVideoFrameCallbackAPI逐帧统计得到精准帧数 - 临时video元素不需要挂载到DOM上即可完成元数据加载,不会影响页面视图
内容的提问来源于stack exchange,提问作者naoval luthfi
相关产品推荐
相关产品推荐

