const videoview = document.getElementById("remoteview"); const config = { iceServers: [{ urls: "stun:localhost" }] }; const polite = true; const signaler = new SignalingChannel(); const pc = new RTCPeerConnection(config); const constraints = { audio: false, video: true }; pc.ontrack = ({ track, streams }) => { track.onunmute = () => { if (remoteview.srcObject) { return; } remoteview.srcObject = streams[0]; }; }; let makingOffer = false; pc.onnegotionationneeded = async () => { try { makingOffer = true; await pc.setLocalDescription(); signaler.send({ description: pc.localDescription }); } catch (err) { console.error(err); } finally { makingOffer = false; } }; pc.onicecandidate = ({ candidate }) => signaler.send({ candidate }); pc.oniceconnectionstatechange = () => { if (pc.iceConnectionState === "failed") { pc.restartIce(); } }; let ignoreOffer = false; signaler.onmessage = async ({ data: { description, candidate } }) => { try { if (description) { const offerCollision = description.type === "offer" && (makingOffer || pc.signalingState !== "stable"); ignoreOffer = !polite && offerCollision; if (ignoreOffer) { return; } await pc.setRemoteDescription(description); if (description.type === "offer") { await pc.setLocalDescription(); signaler.send({ description: pc.localDescription }); } } else if (candidate) { try { await pc.addIceCandidate(candidate); } catch (err) { if (!ignoreOffer) { throw err; } } } } catch (err) { console.error(err); } }; async function start_rtc_connection() { }