Windows下Firefox重复调用getUserMedia后视频流异常求助
问题根源分析
Firefox对媒体轨道的释放与<video>元素的关联处理存在特殊时序限制:
- 调用
track.stop()后,Firefox内部可能仍保留对原轨道的引用,此时直接将srcObject设为undefined并置空stream,无法彻底清除<video>与旧轨道的绑定关系。 - 第二次获取新流时,
<video>元素未能正确初始化新轨道的渲染流程,导致轨道状态合法但视频画面无法显示。
针对Firefox的特殊处理方案
可通过以下几种方式调整代码来解决问题:
1. 优化流的释放顺序
先解绑<video>与旧流的关联,再停止媒体轨道,确保元素与旧资源彻底切割:
let stream; try { document.getElementById('record').onclick = async () => { stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true}); document.getElementById('video').srcObject = stream; }; document.getElementById('stop').onclick = () => { // 先解绑video与旧流 document.getElementById('video').srcObject = null; // 再停止所有轨道 stream.getTracks().forEach(track => track.stop()); stream = null; }; } catch (e) { console.error(e); }
2. 强制重置video元素状态
若上述方法无效,可在停止操作后调用load()方法强制刷新<video>元素状态:
let stream; try { document.getElementById('record').onclick = async () => { stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true}); document.getElementById('video').srcObject = stream; }; document.getElementById('stop').onclick = () => { const videoEl = document.getElementById('video'); videoEl.srcObject = null; stream.getTracks().forEach(track => track.stop()); stream = null; // 强制重置video元素 videoEl.load(); }; } catch (e) { console.error(e); }
3. 提前清理残留流
在每次启动新流前,检查并清理可能存在的未释放旧流,避免资源冲突:
let stream; try { document.getElementById('record').onclick = async () => { // 清理残留的旧流 if (stream) { stream.getTracks().forEach(track => track.stop()); document.getElementById('video').srcObject = null; } stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true}); document.getElementById('video').srcObject = stream; }; document.getElementById('stop').onclick = () => { const videoEl = document.getElementById('video'); videoEl.srcObject = null; stream.getTracks().forEach(track => track.stop()); stream = null; videoEl.load(); }; } catch (e) { console.error(e); }
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

