(BroadcastChannel无法与堆栈溢出代码段一起使用,因此请使用代码笔提供示例代码)
在多个选项卡中打开链接,通过单击任意一侧的Cnnect按钮检查WebRTC连接,然后切换到Close按钮,因此单击Close按钮释放Cam
https://codepen.io/gtk2k/pen/NWxzgKo?editors=1111
// open 2 tabs this page
const signalingChannel = new BroadcastChannel('signalingChannel');
let pc = null;
signalingChannel.onmessage = async evt => {
const msg = JSON.parse(evt.data);
if(msg.close) {
releaseStream();
return;
}
if(!pc)
await setupPC();
if(msg.sdp) {
console.log(`Receive ${msg.type}`);
await pc.setRemoteDescription(msg);
if(msg.type === 'offer') {
const answer = await pc.createAnswer();
await pc.setLocalDescription(answer);
sendSignaling(answer);
}
} else if(msg.candidate) {
console.log(`Receive candidate`);
await pc.addIceCandidate(msg);
}
}
async function setupPC(isCaller) {
pc = new RTCPeerConnection();
pc.onconnectionstatechange = evt => {
console.log(pc.connectionState);
if(pc.connectionState === 'disconnected')
{
releaseStream();
}
}
pc.onicecandidate = evt => {
if(evt.candidate)
sendSignaling(evt.candidate);
}
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 = stream;
if(isCaller) {
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
sendSignaling(offer);
}
}
(async _ => {
const stream = await navigator.mediaDevices.getUserMedia({video:true});
vidLocal.srcObject = stream;
});
btnConnect.onclick = evt => {
if(btnConnect.textContent === 'Connect') {
btnConnect.textContent = 'Close';
setupPC(true);
} else {
btnConnect.textContent = 'Connect';
pc.close();
pc = null;
releaseStream();
sendSignaling({close: true});
}
}
function sendSignaling(data) {
signalingChannel.postMessage(JSON.stringify(data));
}
function releaseStream() {
[vidLocal, vidRemote].forEach(vid => {
if(!vid.srcObject) return;
let stream = vid.srcObject;
vid.pause();
vid.srcObject = null;
stream.getTracks().forEach(track => track.stop());
stream = null;
});
}
video {
width: 360px;
height: 240px;
}
<button id="btnConnect">Connect</button>
<div>
<video id="vidLocal" muted autoplay></video>
<video id="vidRemote" muted autoplay></video>
</div>