媒体数据流错误恢复依赖前置防御而非事后抢救,通过timeslice分片、轨道事件监听、按错误类型响应及及时清理资源来保障可靠性。

媒体数据流的错误恢复不是“出错后抢救”,而是靠前置防御、分段捕获和状态预判来减少损失。关键不在于等 error 事件发生,而是在它发生前就留好可用片段。
用 timeslice 主动分片,避免单点失效
MediaRecorder 的 error 事件本身不携带有效媒体数据,也无法回溯已丢失帧。真正能保住的数据,来自你主动设置的分片机制:
- 初始化时传入
{ timeslice: 2000 }(例如每 2 秒触发一次dataavailable) - 每次回调中立即将
event.data推入数组:chunks.push(event.data) - 即使录制中途报错,已有多个 Blob 仍可上传或拼接,比最后才调
stop()得到一个大 Blob 更可靠
监听轨道事件,提前感知设备异常
很多底层错误(如麦克风被禁用、摄像头被占用)会先触发轨道级事件,早于 MediaRecorder.error:
- 为每个 track 绑定
track.onmute = () => { /* 提示用户检查设备 */ } - 遇到
track.onended时,说明流已不可用,应立即停止 recorder 并请求新流 -
track.enabled = false后尝试设回true,有时能自动恢复采集
按 error 类型做差异化响应
mediaRecorder.onerror 的事件对象没有标准 code 字段,但可通过 event.error.name 和 message 判断大致原因:
立即学习“前端免费学习笔记(深入)”;
-
InvalidStateError:常见于非recording状态下调用stop(),操作前加if (recorder.state === 'recording')判断 -
NotFoundError或NotAllowedError:多因权限变更或设备断开,需引导用户重授或刷新页面 -
SecurityError:通常发生在非 HTTPS 环境下调用getUserMedia,必须确保协议合规
出错后及时清理,防止资源泄漏
error 触发后,MediaRecorder 通常已进入 inactive 或 ended 状态,继续调 stop() 可能无效甚至报错:
- 在 error handler 中先判断状态:
if (recorder.state !== 'inactive') recorder.stop() - 手动停止所有轨道:
stream.getTracks().forEach(t => t.stop()) - 清空
ondataavailable回调中可能残留的 Blob 引用,避免内存堆积



















