You need to enable JavaScript to run this app. 每400毫秒录制播放摄像头时出现blob媒体资源无法解码错误
优惠活动
大模型
产品
解决方案
定价
更多

每400毫秒录制播放摄像头时出现blob媒体资源无法解码错误

错误原因分析

你遇到的解码错误核心原因是:MediaRecorder 输出的分片 WebM 数据,仅第一个分片包含完整的文件头、编码参数等元数据,后续所有分片都只包含音视频帧裸数据,无法作为独立的媒体文件单独解码播放,所以第一个分片能正常播放,后续分片直接赋值给 video.src 就会抛出元数据错误。
除此之外你的代码还存在以下问题:

  • playStream、blob 变量未声明,成为隐式全局变量,容易引发不可预期的错误
  • 每次创建 URL.createObjectURL 后未释放旧的 URL,会造成内存泄漏
  • autoplay 重复赋值无意义,不需要每次播放前设置

解决方案

场景1:仅需要实时播放摄像头画面,无分片存储需求

这是最推荐的方案,直接把摄像头流赋值给 video 元素的 srcObject 属性,无需录制再播放,延迟更低、性能更好:

async function playCamera() {
  try {
    const mediaStream = await navigator.mediaDevices.getUserMedia({audio: true, video: true});
    const video = document.querySelector('video');
    video.srcObject = mediaStream;
    video.autoplay = true;
  } catch (err) {
    console.error('获取摄像头权限失败:', err);
  }
}

场景2:需要同时实现每400毫秒分片存储+实时播放

这种场景需要用 MediaSource Extensions (MSE) 来实现流式播放,把分片数据按顺序喂给 MediaSource 实例,保证元数据和帧数据的连续性:

async function recordAndPlayCamera() {
  try {
    const mediaStream = await navigator.mediaDevices.getUserMedia({audio: true, video: true});
    const video = document.querySelector('video');
    const mime = 'video/webm; codecs="vp8, opus"';
    
    // 提前校验当前浏览器是否支持对应编码格式
    if (!MediaSource.isTypeSupported(mime)) {
      throw new Error('当前浏览器不支持指定的媒体编码格式');
    }
    
    // 初始化MediaSource
    const mediaSource = new MediaSource();
    video.src = URL.createObjectURL(mediaSource);
    let sourceBuffer;
    
    mediaSource.addEventListener('sourceopen', () => {
      sourceBuffer = mediaSource.addSourceBuffer(mime);
      // 初始化MediaRecorder
      const mediaRecorder = new MediaRecorder(mediaStream, {mimeType: mime});
      mediaRecorder.start(400);
      
      mediaRecorder.ondataavailable = (e) => {
        if (e.data.size > 0 && sourceBuffer && !sourceBuffer.updating) {
          sourceBuffer.appendBuffer(e.data);
        }
        // 此处可添加自定义逻辑,将e.data存入分片列表实现分片存储
      };
    });
  } catch (err) {
    console.error('初始化失败:', err);
  }
}

注意事项

  • 播放过程中如果 SourceBuffer 缓存过多,可以在合适的时机调用 sourceBuffer.remove() 清理旧的缓存,避免内存占用过高
  • 不同浏览器支持的编码格式有差异,可根据实际场景调整 mime 字段的编码配置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 03:06:02