diff --git a/src/components/ha-web-rtc-player.ts b/src/components/ha-web-rtc-player.ts index 99faf1953f..b31b2c0a7d 100644 --- a/src/components/ha-web-rtc-player.ts +++ b/src/components/ha-web-rtc-player.ts @@ -39,6 +39,10 @@ class HaWebRtcPlayer extends LitElement { // don't cache this, as we remove it on disconnects @query("#remote-stream") private _videoEl!: HTMLVideoElement; + private _peerConnection?: RTCPeerConnection; + + private _remoteStream?: MediaStream; + protected render(): TemplateResult { if (this._error) { return html`${this._error}`; @@ -71,6 +75,7 @@ class HaWebRtcPlayer extends LitElement { private async _startWebRtc(): Promise { this._error = undefined; + const peerConnection = new RTCPeerConnection(); // Some cameras (such as nest) require a data channel to establish a stream // however, not used by any integrations. @@ -93,6 +98,7 @@ class HaWebRtcPlayer extends LitElement { ); } catch (err: any) { this._error = "Failed to start WebRTC stream: " + err.message; + peerConnection.close(); return; } @@ -102,21 +108,39 @@ class HaWebRtcPlayer extends LitElement { remoteStream.addTrack(event.track); this._videoEl.srcObject = remoteStream; }); + this._remoteStream = remoteStream; // Initiate the stream with the remote device const remoteDesc = new RTCSessionDescription({ type: "answer", sdp: webRtcAnswer.answer, }); - await peerConnection.setRemoteDescription(remoteDesc); + try { + await peerConnection.setRemoteDescription(remoteDesc); + } catch (err: any) { + this._error = "Failed to connect WebRTC stream: " + err.message; + peerConnection.close(); + return; + } + this._peerConnection = peerConnection; } private _cleanUp() { + if (this._remoteStream) { + this._remoteStream.getTracks().forEach((track) => { + track.stop(); + }); + this._remoteStream = undefined; + } if (this._videoEl) { const videoEl = this._videoEl; videoEl.removeAttribute("src"); videoEl.load(); } + if (this._peerConnection) { + this._peerConnection.close(); + this._peerConnection = undefined; + } } static get styles(): CSSResultGroup {