You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为MediaRecorder生成的Blob转视频文件添加时长信息?

解决MediaRecorder录制MP4无时长信息的问题

问题原因

MediaRecorder生成的MP4文件默认采用流式写入,存储时长、轨道信息等关键元数据的moov块会被放在文件末尾。大部分播放器需要先读取moov块才能识别时长,因此会出现音画播放正常但无法读取时长的情况。另外,直接合并不同来源的音视频轨道时,MediaRecorder可能未正确同步轨道的时间戳元数据,也会导致时长识别失败。

解决方案

方案一:用FFmpeg.wasm在前端修复MP4元数据

这是最可靠的前端解决方案,通过FFmpeg重新封装MP4文件,将moov块移至文件开头,并补全标准的时长元数据,且不会重新编码视频(速度快)。

示例代码:

// 先在HTML中引入FFmpeg.wasm库
// <script src="https://unpkg.com/@ffmpeg/ffmpeg@0.12.6/dist/ffmpeg.min.js"></script>
const { createFFmpeg, fetchFile } = FFmpeg;
const ffmpeg = createFFmpeg({ log: true });

mediaRecorder.ondataavailable = async (ev) => {
  // 等待FFmpeg加载完成
  if (!ffmpeg.isLoaded()) await ffmpeg.load();

  // 将录制得到的Blob写入FFmpeg虚拟文件系统
  ffmpeg.FS('writeFile', 'input.mp4', await fetchFile(ev.data));

  // 执行重新封装命令:复制原音视频流,生成moov前置的标准MP4
  await ffmpeg.run('-i', 'input.mp4', '-c', 'copy', '-movflags', 'faststart', 'output.mp4');

  // 读取修复后的文件
  const data = ffmpeg.FS('readFile', 'output.mp4');
  const fixedFile = new File([data.buffer], 'fixed-video.mp4', { type: 'video/mp4' });

  // 触发下载
  const link = document.createElement('a');
  link.href = URL.createObjectURL(fixedFile);
  link.download = 'fixed-video.mp4';
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
};

方案二:优化MediaRecorder录制参数(兼容性有限)

部分现代浏览器支持通过指定带参数的mimeType,强制生成符合标准的MP4文件,但该方法兼容性较差,仅在部分环境生效:

// 指定编码格式并要求生成moov前置的MP4
const mediaRecorder = new MediaRecorder(videoStream, {
  mimeType: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"',
  videoBitsPerSecond: 2500000,
  audioBitsPerSecond: 128000
});

额外注意事项

  • 你的原始代码存在拼写错误:vidoStream应改为videoStream,需先修正避免录制失败
  • 录制停止时,确保音频、视频轨道均正常结束,避免元数据缺失
  • 使用FFmpeg.wasm时,需注意浏览器的CORS限制,建议使用同源CDN或本地部署库

内容的提问来源于stack exchange,提问作者Shahid Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 23:20:39