diff --git a/web/js/MonitorStream.js b/web/js/MonitorStream.js index c6193b1960..eb75de52fe 100644 --- a/web/js/MonitorStream.js +++ b/web/js/MonitorStream.js @@ -11,6 +11,7 @@ function MonitorStream(monitorData) { this.height = monitorData.height; this.RTSP2WebEnabled = monitorData.RTSP2WebEnabled; this.RTSP2WebType = monitorData.RTSP2WebType; + this.webrtc = null; this.mseStreamingStarted = false; this.mseQueue = []; this.mseSourceBuffer = null; @@ -291,7 +292,7 @@ function MonitorStream(monitorData) { } else if (this.RTSP2WebType == 'WebRTC') { const webrtcUrl = rtsp2webModUrl; webrtcUrl.pathname = "/stream/" + this.id + "/channel/0/webrtc"; - startRTSP2WebPlay(videoEl, webrtcUrl.href); + startRTSP2WebPlay(videoEl, webrtcUrl.href, this); } this.statusCmdTimer = setInterval(this.statusCmdQuery.bind(this), statusRefreshTimeout); this.started = true; @@ -344,6 +345,10 @@ function MonitorStream(monitorData) { this.statusCmdTimer = clearInterval(this.statusCmdTimer); this.streamCmdTimer = clearInterval(this.streamCmdTimer); this.started = false; + if (this.webrtc) { + this.webrtc.close(); + this.webrtc = null; + } }; this.kill = function() { @@ -976,27 +981,27 @@ const waitUntil = (condition) => { }); }; -function startRTSP2WebPlay(videoEl, url) { - const webrtc = new RTCPeerConnection({ +function startRTSP2WebPlay(videoEl, url, stream) { + stream.webrtc = new RTCPeerConnection({ iceServers: [{ urls: ['stun:stun.l.google.com:19302'] }], sdpSemantics: 'unified-plan' }); - webrtc.ontrack = function(event) { + stream.webrtc.ontrack = function(event) { console.log(event.streams.length + ' track is delivered'); videoEl.srcObject = event.streams[0]; videoEl.play(); }; - webrtc.addTransceiver('video', {direction: 'sendrecv'}); - webrtc.onnegotiationneeded = async function handleNegotiationNeeded() { - const offer = await webrtc.createOffer(); + stream.webrtc.addTransceiver('video', {direction: 'sendrecv'}); + stream.webrtc.onnegotiationneeded = async function handleNegotiationNeeded() { + const offer = await stream.webrtc.createOffer(); - await webrtc.setLocalDescription(offer); + await stream.webrtc.setLocalDescription(offer); fetch(url, { method: 'POST', - body: new URLSearchParams({data: btoa(webrtc.localDescription.sdp)}) + body: new URLSearchParams({data: btoa(stream.webrtc.localDescription.sdp)}) }) .catch((rejected) => { console.log(rejected); @@ -1004,7 +1009,7 @@ function startRTSP2WebPlay(videoEl, url) { .then((response) => response.text()) .then((data) => { try { - webrtc.setRemoteDescription( + stream.webrtc.setRemoteDescription( new RTCSessionDescription({type: 'answer', sdp: atob(data)}) ); } catch (e) { @@ -1013,14 +1018,16 @@ function startRTSP2WebPlay(videoEl, url) { }); }; - const webrtcSendChannel = webrtc.createDataChannel('rtsptowebSendChannel'); + const webrtcSendChannel = stream.webrtc.createDataChannel('rtsptowebSendChannel'); webrtcSendChannel.onopen = (event) => { console.log(`${webrtcSendChannel.label} has opened`); webrtcSendChannel.send('ping'); }; webrtcSendChannel.onclose = (_event) => { console.log(`${webrtcSendChannel.label} has closed`); - startRTSP2WebPlay(videoEl, url); + if (stream.started) { + startRTSP2WebPlay(videoEl, url, stream); + } }; webrtcSendChannel.onmessage = (event) => console.log(event.data); }