Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google chrome 如何在WebRTC呼叫后释放摄像头和麦克风?_Google Chrome_Webrtc_Html5 Video_Html5 Audio - Fatal编程技术网

Google chrome 如何在WebRTC呼叫后释放摄像头和麦克风?

Google chrome 如何在WebRTC呼叫后释放摄像头和麦克风?,google-chrome,webrtc,html5-video,html5-audio,Google Chrome,Webrtc,Html5 Video,Html5 Audio,在我结束一个WebRTC呼叫后,我似乎什么也不做就会删除浏览器选项卡上的红色图标,该图标表示相机或麦克风正在使用 我迭代来自videoElement.srcObject.getTracks()的曲目,并对每个曲目调用track.stop()。然后我从DOM中删除了videoElement,但仍然有红色图标。(BroadcastChannel无法与堆栈溢出片段一起使用,因此请使用代码笔提供示例代码) (我确认了在Chrome和Firefox上的操作) 在多个选项卡中打开链接,通过单击任意一侧的Cn

在我结束一个WebRTC呼叫后,我似乎什么也不做就会删除浏览器选项卡上的红色图标,该图标表示相机或麦克风正在使用

我迭代来自
videoElement.srcObject.getTracks()
的曲目,并对每个曲目调用
track.stop()
。然后我从DOM中删除了videoElement,但仍然有红色图标。

(BroadcastChannel无法与堆栈溢出片段一起使用,因此请使用代码笔提供示例代码) (我确认了在Chrome和Firefox上的操作) 在多个选项卡中打开链接,通过单击任意一侧的Cnnect按钮检查WebRTC连接,然后切换到Close按钮,因此单击Close按钮释放Cam

//打开此页面的两个选项卡
const signalingChannel=新广播频道(“signalingChannel”);
设pc=null;
signalingChannel.onmessage=异步evt=>{
const msg=JSON.parse(evt.data);
如果(消息关闭){
释放流();
返回;
}
如果(!pc)
等待设置PC();
如果(msg.sdp){
log(`Receive${msg.type}`);
等待pc.setRemoteDescription(msg);
如果(msg.type==='offer'){
const answer=等待pc.createAnswer();
等待pc.setLocalDescription(应答);
发送信号(应答);
}
}else if(msg.candidate){
log(`receivecandidate`);
等待pc.addIceCandidate(msg);
}
}
异步函数设置PC(isCaller){
pc=新的RTPeerConnection();
pc.onconnectionstatechange=evt=>{
console.log(pc.connectionState);
如果(pc.connectionState===‘断开’)
{  
释放流();
}
}
pc.onicecandidate=evt=>{
if(执行副总裁候选人)
发送信令(evt.候选者);
}
pc.ontrack=evt=>{
vidRemote.srcObject=evt.streams[0];
}
const stream=await navigator.mediaDevices.getUserMedia({video:true});
stream.getTracks().forEach(track=>pc.addTrack(track,stream));
vidLocal.srcObject=流;
if(isCaller){
const offer=等待pc.createOffer();
等待pc.setLocalDescription(报价);
发送信号(报价);
}
}
(异步=>{
const stream=await navigator.mediaDevices.getUserMedia({video:true});
vidLocal.srcObject=流;
});
btnConnect.onclick=evt=>{
如果(btnConnect.textContent==='Connect'){
btnConnect.textContent='Close';
setupPC(真);
}否则{
btnConnect.textContent='Connect';
pc.close();
pc=null;
释放流();
发送信令({close:true});
}
}
功能发送信令(数据){
signalingChannel.postMessage(JSON.stringify(data));
}
函数releaseStream(){
[vidLocal,vidRemote].forEach(vid=>{
如果(!vid.srcObject)返回;
让stream=vid.src对象;
参阅暂停();
vid.srcObject=null;
stream.getTracks().forEach(track=>track.stop());
流=空;
});
}
视频{
宽度:360px;
高度:240px;
}
连接

在我的例子中,问题是由于我对WebRTC和getUserMedia()的误解导致代码中的错误造成的。我实际上调用了getUserMedia()两次,一次用于本地
元素,第二次用于添加到RTPeerConnection


修复方法当然是只调用getuserMedia()一次,并在两个位置使用返回的流。

简单地停止应该足够了,在
document.querySelector(“video”).srcObject.getTracks().forEach(t=>t.stop())
如果这不能使红色图标消失,那将是一个浏览器错误。如果红色图标消失,但在代码搜索实例时保持不变,则流或曲目上的clone()调用。@PhilippHancke我已经尝试过您的代码,甚至包括
音频
元素,但红点不肯消失。请详细谈谈你对克隆()的评论好吗?我从JsSIP获得RTCConnections,所以我想知道是否有隐藏的克隆()正在进行。