录制视频后无需重新加载即可获取总时长的实现方案
解决录制视频后获取时长的问题
客户端方案(无需重新加载文件)
问题根源
你的代码存在两个关键问题:
dataavailable事件中创建Blob时指定了video/mp4类型,但实际录制的是video/webm格式,类型不匹配会导致视频元数据解析异常。- 使用
loadeddata事件获取时长不准确,该事件仅表示第一帧加载完成,视频时长等核心元数据需要等待loadedmetadata事件触发才能获取。
修正后的代码
HTML部分:
<video id="videoRecorded" controls></video> <button id="start">Start</button> <button id="stop">Stop</button>
JavaScript部分:
async function main() { const videoRecorded = document.getElementById('videoRecorded'); const buttonStart = document.querySelector('#start'); const buttonStop = document.querySelector('#stop'); let recordedBlob = null; const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true, }); videoRecorded.srcObject = stream; if (!MediaRecorder.isTypeSupported('video/webm')) { console.warn('video/webm is not supported'); } const mediaRecorder = new MediaRecorder(stream, { mimeType: 'video/webm', }); buttonStart.addEventListener('click', () => { mediaRecorder.start(); buttonStart.classList.add('hidden'); buttonStop.classList.remove('hidden'); }); buttonStop.addEventListener('click', () => { mediaRecorder.stop(); }); mediaRecorder.addEventListener('dataavailable', (event) => { recordedBlob = new Blob([event.data], { type: 'video/webm' }); // 修正MIME类型与录制格式一致 videoRecorded.src = URL.createObjectURL(recordedBlob); // 监听loadedmetadata事件获取准确时长 videoRecorded.addEventListener('loadedmetadata', () => { const duration = videoRecorded.duration; // 转换为时分秒格式 const minutes = Math.floor(duration / 60); const seconds = Math.floor(duration % 60); console.log(`${minutes}m:${seconds.toString().padStart(2, '0')}s`); }, { once: true }); // 仅监听一次,避免重复触发 }); } main();
额外说明
- 添加
{ once: true }参数确保事件只执行一次,避免后续操作重复触发时长计算。 - 若部分浏览器仍无法获取时长,可在设置
src后调用videoRecorded.load()强制触发元数据解析,这不属于"重新加载文件"范畴,只是触发视频元素的内部解析流程。
服务端方案(可选)
如果客户端方案存在兼容性问题,可将录制的Blob上传到服务端,使用媒体处理工具解析时长:
以Node.js为例,使用fluent-ffmpeg库:
const ffmpeg = require('fluent-ffmpeg'); const fs = require('fs'); ffmpeg.ffprobe('recorded_video.webm', (err, metadata) => { if (!err) { const duration = metadata.format.duration; const minutes = Math.floor(duration / 60); const seconds = Math.floor(duration % 60); console.log(`${minutes}m:${seconds.toString().padStart(2, '0')}s`); } });
其他语言可使用对应工具,比如Python的ffprobe-python、Java的Xuggler等。
内容的提问来源于stack exchange,提问作者Jeet Bhatt
相关产品推荐
相关产品推荐

