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

使用MediaRecorder录制后Chrome红色录制图标仍不消失问题求助

问题产生原因
  • 执行顺序错误:你当前的停止逻辑先调用了track.stop()释放轨道,再执行mediaRecorder.stop(),MediaRecorder实例未提前终止时仍会持有媒体流的底层引用,导致Chrome判定资源仍在被占用,不会熄灭录制图标。
  • 残留引用未清理:你将流对象挂载到了window.stream和React的useRef实例上,同时如果页面中存在<video>元素绑定了该流作为srcObject,所有相关引用未手动清空时,浏览器GC未及时回收资源也会导致图标残留。
  • 重复申请流未释放:如果业务逻辑中存在重复调用getUserMedia的场景,旧的流对象没有被正确存储并释放,仅停止了最后一次生成的流轨道,也会导致图标不消失。
  • 异步逻辑持有引用:ondataavailable回调中执行的uploadRecordedAnswer如果是异步逻辑,且持有recordedBlobs或流的相关引用,未执行完成前也会导致资源未完全释放。
解决方法
  1. 调整停止操作的执行顺序,优先终止MediaRecorder实例,再释放所有媒体轨道,稳妥起见可以在MediaRecorder的onstop回调中执行轨道释放操作,正确代码示例如下:
// 先停止录制器
if (mediaRecorder.current && mediaRecorder.current.state !== 'inactive') {
  // 监听录制器停止事件后再释放轨道
  mediaRecorder.current.onstop = () => {
    // 释放所有流轨道
    stream.current?.getTracks().forEach(track => {
      track.stop();
      console.log(track.kind, track.readyState) // 可验证track状态是否变为ended
    });
    window.stream?.getTracks().forEach(track => track.stop());

    // 清空所有引用
    stream.current = null;
    window.stream = null;
    mediaRecorder.current = null;
    recordedBlobs.current = [];
    
    // 如果有绑定流的video元素,也要清空srcObject
    // videoRef.current && (videoRef.current.srcObject = null);
  }
  mediaRecorder.current.stop();
}
  • 排查业务逻辑中所有getUserMedia的调用入口,每次申请新流前先检查是否存在未释放的旧流,先释放旧流再申请新流。
  • 如果uploadRecordedAnswer是异步上传逻辑,不要直接在ondataavailable触发时就调用,可以在录制完全停止、所有轨道释放完成后再统一处理录制的Blob数据,避免异步逻辑持有引用导致资源残留。

内容的提问来源于stack exchange,提问作者Ming Kang Siow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 05:36:04