diff --git a/web/static/js/viewer.js b/web/static/js/viewer.js index d3388aa..a81e988 100644 --- a/web/static/js/viewer.js +++ b/web/static/js/viewer.js @@ -1,70 +1,85 @@ -// Init peer connection -peerConnection = new RTCPeerConnection({ - iceServers: [ - { - // FIXME: let admin customize the stun server - urls: 'stun:stun.l.google.com:19302' +let peerConnection; + +startPeerConnection = () => { + // Init peer connection + peerConnection = new RTCPeerConnection({ + iceServers: [ + { + // FIXME: let admin customize the stun server + urls: 'stun:stun.l.google.com:19302' + } + ] + }) + + // On connection change, change indicator color + // if connection failed, restart peer connection + peerConnection.oniceconnectionstatechange = e => { + switch (peerConnection.iceConnectionState) { + case "disconnected": + console.log(peerConnection.iceConnectionState) + 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 + startPeerConnection() + break + default: + console.log(peerConnection.iceConnectionState) + break } - ] -}) + } -// On connection change, inform user -peerConnection.oniceconnectionstatechange = e => { - console.log(peerConnection.iceConnectionState) + // We want to receive audio and video + peerConnection.addTransceiver('video', { 'direction': 'sendrecv' }) + peerConnection.addTransceiver('audio', { 'direction': 'sendrecv' }) - switch (peerConnection.iceConnectionState) { - case "closed": - case "failed": - console.log("FIXME Failed"); - break; - case "disconnected": - console.log("temp network issue") - break; - case "connected": - console.log("temp network issue resolved!") - break; + // 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 know the stream name from the url + // The server replies with its description + // After setRemoteDescription, the browser will fire ontrack events + console.log("Sending session description to server") + fetch(window.location.href, { + method: 'POST', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify(peerConnection.localDescription) + }) + .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] + } } } -// 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 know the stream name from the url - // The server replies with its description - // After setRemoteDescription, the browser will fire ontrack events - fetch(window.location.href, { - method: 'POST', - headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json' - }, - body: JSON.stringify(peerConnection.localDescription) - }) - .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) { - if (event.track.kind === "video") { - const viewer = document.getElementById('viewer') - viewer.srcObject = event.streams[0] - viewer.autoplay = true - viewer.controls = true - viewer.muted = true - } -} +// Start +startPeerConnection() diff --git a/web/template/viewer.html b/web/template/viewer.html index 1db8a3a..2d62cf1 100644 --- a/web/template/viewer.html +++ b/web/template/viewer.html @@ -3,7 +3,7 @@
- +
@@ -16,6 +16,13 @@ d="M14.354 1.646a.5.5 0 0 1 0 .708l-8 8a.5.5 0 0 1-.708-.708l8-8a.5.5 0 0 1 .708 0z" /> rtmps://{{.Cfg.Hostname}}:1935/play/{{.Path}}--> + + + + + + + ยป