如何从网页端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
相关产品推荐
相关产品推荐

