let peerConnection; let streamPath = window.location.href; let stream = streamPath; let quality = "source"; const startPeerConnection = () => { // Init peer connection peerConnection = new RTCPeerConnection({ iceServers: [{ urls: stunServers }] }); // On connection change, change indicator color // if connection failed, restart peer connection peerConnection.oniceconnectionstatechange = e => { console.log("ICE connection state changed, " + peerConnection.iceConnectionState); switch (peerConnection.iceConnectionState) { case "disconnected": document.getElementById("connectionIndicator").style.fill = "#dc3545"; break; case "checking": document.getElementById("connectionIndicator").style.fill = "#ffc107"; break; case "connected": document.getElementById("connectionIndicator").style.fill = "#28a745"; break; case "closed": case "failed": console.log("Connection failed, restarting..."); peerConnection.close(); peerConnection = null; setTimeout(startPeerConnection, 1000); break; } }; // We want to receive audio and video peerConnection.addTransceiver("video", { "direction": "sendrecv" }); peerConnection.addTransceiver("audio", { "direction": "sendrecv" }); // Create offer and set local description peerConnection.createOffer().then(offer => { // After setLocalDescription, the browser will fire onicecandidate events peerConnection.setLocalDescription(offer); }).catch(console.log); // When candidate is null, ICE layer has run out of potential configurations to suggest // so let's send the offer to the server peerConnection.onicecandidate = event => { if (event.candidate === null) { // Send offer to server // The server replies with its description // After setRemoteDescription, the browser will fire ontrack events console.log("Sending session description to server"); fetch(streamPath, { method: "POST", headers: { "Accept": "application/json", "Content-Type": "application/json" }, body: JSON.stringify({ "webRtcSdp": peerConnection.localDescription, "stream": stream, "quality": quality }) }) .then(response => response.json()) .then((data) => peerConnection.setRemoteDescription(new RTCSessionDescription(data))) .catch(console.log); } }; // When video track is received, configure player peerConnection.ontrack = function (event) { console.log(`New ${event.track.kind} track`); if (event.track.kind === "video") { const viewer = document.getElementById("viewer"); viewer.srcObject = event.streams[0]; } }; };