Skip to content

Commit

Permalink
Merge pull request #81 from idoaflalo/bugfix/clean-up-after-dom-remove
Browse files Browse the repository at this point in the history
Bugfix/clean up after dom remove
  • Loading branch information
AlexxIT authored Jun 7, 2021
2 parents 6852810 + 998551d commit cc3337f
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 12 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ poster: https://home-assistant.io/images/cast/splash.png # still image when str
intersection: 0.75 # auto pause stream when less than 75% of video element is in the screen, 50% by default
muted: false # disable sound, default true
ui: true # custom video controls, default false
should_run_in_background: true # makes the component run when not displayed (ex. for quick video loading), default false
ptz: # check full examples in wiki
Expand Down
80 changes: 68 additions & 12 deletions custom_components/webrtc/www/webrtc-camera.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
class WebRTCCamera extends HTMLElement {
subscriptions = [];
rendered = false;

async initMSE(hass, pc = null) {
const ts = Date.now();

Expand All @@ -16,6 +19,12 @@ class WebRTCCamera extends HTMLElement {
ws.binaryType = 'arraybuffer';

let mediaSource, sourceBuffer;

this.subscriptions.push(() => {
this.ws.onclose = null;
this.ws.close();
console.debug("Closing websocket");
});

ws.onopen = async () => {
this.readyState = 'websocket';
Expand All @@ -39,6 +48,11 @@ class WebRTCCamera extends HTMLElement {

const offer = await pc.createOffer({iceRestart: true})
await pc.setLocalDescription(offer);
this.subscriptions.push(() => {
pc.close();
pc = null;
console.debug("Closing RTCPeerConnection");
});
}
}
ws.onmessage = ev => {
Expand Down Expand Up @@ -88,8 +102,10 @@ class WebRTCCamera extends HTMLElement {
console.debug(`Reconnect in ${delay} ms`);

setTimeout(() => {
this.status = "Restart connection";
this.initMSE(hass, pc);
if (this.isConnected) {
this.status = "Restart connection";
this.initMSE(hass, pc);
}
}, delay);
}
}
Expand Down Expand Up @@ -167,8 +183,10 @@ class WebRTCCamera extends HTMLElement {
const offer = await pc.createOffer({iceRestart: true})
await pc.setLocalDescription(offer);
} else {
video.src = '';
this.initMSE(hass, pc);
if (this.isConnected) {
video.src = '';
this.initMSE(hass, pc);
}
}
} else if (pc.connectionState === 'connected') {
this.readyState = 'webrtc-loading';
Expand Down Expand Up @@ -496,6 +514,8 @@ class WebRTCCamera extends HTMLElement {
video.play().then(() => null, () => null);
});

this.initPageVisibilityListener();

const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
Expand Down Expand Up @@ -569,14 +589,6 @@ class WebRTCCamera extends HTMLElement {
}
}

set hass(hass) {
if (this.firstChild || typeof this.config === 'undefined') return;

this.renderGUI(hass).then(async () => {
await this.initMSE(hass);
});
}

setPTZVisibility(show) {
const ptz = this.querySelector('.ptz');
if (ptz) {
Expand Down Expand Up @@ -614,6 +626,50 @@ class WebRTCCamera extends HTMLElement {
url: 'rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov'
}
}

initPageVisibilityListener() {
var hidden, visibilityChange;
if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
hidden = "hidden";
visibilityChange = "visibilitychange";
} else if (typeof document.msHidden !== "undefined") {
hidden = "msHidden";
visibilityChange = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
hidden = "webkitHidden";
visibilityChange = "webkitvisibilitychange";
}

document.addEventListener(visibilityChange, () => {
if (!document[hidden] && this.isConnected) {
this.connectedCallback();
} else {
this.disconnectedCallback();
}
}, false);
}

async connectedCallback() {
if (!this.config) return;

if (!this.rendered) {
await this.renderGUI(this.hass);
this.rendered = true;
}

if (this.ws && this.config.should_run_in_background === true) return;

if (!this.ws || [this.ws.CLOSING, this.ws.CLOSED].includes(this.ws.readyState)) {
await this.initMSE(this.hass);
}
}

disconnectedCallback(){
if (this.config.should_run_in_background !== true) {
this.subscriptions.forEach(callback => callback());
this.subscriptions = [];
}
}
}

customElements.define('webrtc-camera', WebRTCCamera);
Expand Down

0 comments on commit cc3337f

Please sign in to comment.