使用MediaRecorder录制后Chrome红色录制图标仍不消失问题求助
问题产生原因
- 执行顺序错误:你当前的停止逻辑先调用了
track.stop()释放轨道,再执行mediaRecorder.stop(),MediaRecorder实例未提前终止时仍会持有媒体流的底层引用,导致Chrome判定资源仍在被占用,不会熄灭录制图标。 - 残留引用未清理:你将流对象挂载到了
window.stream和React的useRef实例上,同时如果页面中存在<video>元素绑定了该流作为srcObject,所有相关引用未手动清空时,浏览器GC未及时回收资源也会导致图标残留。 - 重复申请流未释放:如果业务逻辑中存在重复调用
getUserMedia的场景,旧的流对象没有被正确存储并释放,仅停止了最后一次生成的流轨道,也会导致图标不消失。 - 异步逻辑持有引用:
ondataavailable回调中执行的uploadRecordedAnswer如果是异步逻辑,且持有recordedBlobs或流的相关引用,未执行完成前也会导致资源未完全释放。
解决方法
- 调整停止操作的执行顺序,优先终止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
相关产品推荐
相关产品推荐

