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

如何从网页端MediaRecorder获取按大小而非时间切割的流数据

MediaRecorder按指定大小分片实现方案

单MediaRecorder最优实现

你之前提到的“无法事后合并多个分片”是误区:同一个MediaRecorder实例在单次录制过程中输出的所有分片编码参数完全一致,直接通过Blob构造函数合并即可得到正常可播放的分片块,完全满足需求。
核心实现逻辑如下:

  • 启动录制时传入较小的时间片参数(建议100~1000ms),让录制器持续输出小尺寸分片
  • 维护本地缓冲区累积小分片,累计大小达到阈值后合并缓冲区输出完整分片,再清空缓冲区重新累积

实现代码:

// 目标分片大小,示例为5MB
const TARGET_CHUNK_SIZE = 5 * 1024 * 1024;
// 分片缓冲区
let chunkBuffer = [];
// 当前缓冲区累计大小
let currentBufferSize = 0;

navigator.mediaDevices
  .getUserMedia({ audio: true, video: true })
  .then((stream) => {
    // 可根据需求指定MIME类型,默认浏览器会用支持的最优格式
    const mediaRecorder = new MediaRecorder(stream);
    // 传入100ms时间片,控制分片精度
    mediaRecorder.start(100);

    mediaRecorder.ondataavailable = (blobEvent) => {
      const chunk = blobEvent.data;
      chunkBuffer.push(chunk);
      currentBufferSize += chunk.size;

      // 累计大小达到阈值时输出分片
      if (currentBufferSize >= TARGET_CHUNK_SIZE) {
        // 合并缓冲区内容为完整分片
        const completeChunk = new Blob(chunkBuffer, { type: mediaRecorder.mimeType });
        console.log('生成目标大小分片,实际大小:', completeChunk.size);
        // 此处可添加分片上传、存储等逻辑

        // 重置缓冲区
        chunkBuffer = [];
        currentBufferSize = 0;
      }
    };

    // 录制结束时处理剩余不足阈值的内容
    mediaRecorder.onstop = () => {
      if (chunkBuffer.length > 0) {
        const lastChunk = new Blob(chunkBuffer, { type: mediaRecorder.mimeType });
        console.log('生成最后一个分片,大小:', lastChunk.size);
      }
    };
  });

该方案分片误差仅为你设置的时间片对应的流数据大小,远低于常规分片阈值,精度远高于双MediaRecorder方案,且不需要处理多实例同步问题,性能开销最低。

双MediaRecorder方案性能说明

如果因为特殊场景必须使用双MediaRecorder方案,也无需过度担心性能问题:MediaRecorder为浏览器底层实现,支持硬件编码加速,同一个媒体流绑定多个录制器时,浏览器通常会复用编码通道,额外性能开销仅在10%以内,普通PC、中端以上移动端设备运行1080P 30帧的双录制也不会出现卡顿、掉帧问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 11:48:04