可通过监听MediaRecorder.ondataavailable事件分段录制视频并上传,需控制录制节奏、正确拼接Blob、保证上传顺序与完整性。

可以通过监听 MediaRecorder.ondataavailable 事件,将视频流按时间或数据量切分为多个 Blob 片段,再逐个上传到服务器。关键在于控制录制节奏、正确拼接 Blob 并处理上传顺序与完整性。
1. 初始化 MediaRecorder 并设置分段逻辑
创建 MediaRecorder 实例时,通过 timeslice 参数触发周期性 dataavailable 事件,或手动调用 stop() + start() 实现显式分段:
- 使用
timeslice: 5000(毫秒)可每 5 秒触发一次事件,适合稳定分段 - 若需更灵活控制(如按文件大小),建议关闭
timeslice,改用recorder.requestData()主动截取当前数据 - 注意:Chrome 支持
timeslice,Firefox 需依赖requestData()模拟分段
2. 在 dataavailable 中收集并暂存 Blob
每次事件触发时,event.data 是一个包含该段媒体数据的 Blob。应立即保存并标记序号,避免因异步上传导致乱序:
- 用数组或 Map 存储
{ blob, index, timestamp },例如:segments.push({ blob: event.data, index: segmentIndex++ }) - 不建议直接上传
event.data,因为后续可能被 GC 或复用;务必用new Blob([event.data])创建独立引用 - 可选:在 Blob 上附加自定义属性(如
blob.segmentIndex = i),但注意部分浏览器会忽略非标准属性,推荐用外部结构管理
3. 分段上传并保证服务端可合并
上传每个 Blob 时需携带上下文信息,让后端能按序还原完整视频:
立即学习“前端免费学习笔记(深入)”;
- HTTP 请求中添加 headers,如
X-Segment-Index: 0、X-Total-Segments: 5、X-Session-ID: abc123 - 使用
FormData提交时,将 Blob 作为字段值,并附带隐藏字段传递索引:formData.append('segment', blob); formData.append('index', i) - 服务端收到所有分段后,按
index排序,用二进制流拼接(如 Node.js 的Buffer.concat()),再写入 MP4 文件(注意:MP4 有头部信息,纯拼接可能损坏;更稳妥方式是服务端用 FFmpeg 合并或录制为 WebM 后转封装)
4. 处理异常与完整性校验
分段上传易受网络波动影响,需增强鲁棒性:
- 上传失败时记录失败索引,支持断点续传(服务端返回已接收的
receivedIndices,前端跳过重传) - 客户端可在上传前计算 Blob 的
size和type,上传后比对服务端返回的receivedSize,防止传输截断 - 全部上传完成后,发起合并请求(如
POST /merge?session=abc123),服务端校验总长度、MD5 或生成最终播放 URL



















