diff --git a/README.md b/README.md index 6ad3539..3178e20 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,19 @@ type: 'custom:webrtc-camera' entity: camera.generic_stream # change to your camera entity_id ``` +**or** + +```yaml +type: 'custom:webrtc-camera' +streams: + - url: go2rtc_stream_hd + name: HD + mode: webrtc # mode is optional + - url: go2rtc_stream_sd + name: SD + mode: mse +``` + **Full** ```yaml diff --git a/custom_components/webrtc/www/webrtc-camera.js b/custom_components/webrtc/www/webrtc-camera.js index 3f4a689..dba6f9b 100644 --- a/custom_components/webrtc/www/webrtc-camera.js +++ b/custom_components/webrtc/www/webrtc-camera.js @@ -8,12 +8,7 @@ class WebRTCCamera extends VideoRTC { * @param {Object} config */ setConfig(config) { - if (!config.url && !config.entity) throw new Error('Missing `url` or `entity`'); - - if (config.mode) this.mode = config.mode; - // backward compatibility - else if (config.mse === false) this.mode = 'webrtc'; - else if (config.webrtc === false) this.mode = 'mse'; + if (!config.url && !config.entity && !config.streams) throw new Error('Missing `url` or `entity` or `streams`'); if (config.background) this.background = config.background; @@ -22,7 +17,10 @@ class WebRTCCamera extends VideoRTC { /** * @type {{ - * url:string, entity:string, muted:boolean, poster:string, title:string, + * url:string, entity:string, mode:string, muted:boolean, poster:string, title:string, + * streams: { + * url:string, entity:string, mode:string + * }[] * intersection:number, ui:boolean, style:string, * digital_ptz:{ * mouse_drag_pan:boolean, @@ -42,7 +40,25 @@ class WebRTCCamera extends VideoRTC { * mse:boolean, webrtc:boolean, * }} config */ - this.config = config; + + this.defaultMode = config.mode + ? config.mode + : config.mse === false + ? "webrtc" + : config.webrtc === false + ? "mse" + : this.mode; + this.config = Object.assign({}, config); + if (!this.config.streams) { + this.config.streams = [ + { + url: config.url, + entity: config.entity, + }, + ]; + } + this.streamIdx = -1; + this.onNextStream(); } set hass(hass) { @@ -74,6 +90,18 @@ class WebRTCCamera extends VideoRTC { this.querySelector('.status').innerText = status || ''; } + onNextStream() { + this.streamIdx = (this.streamIdx + 1) % this.config.streams.length; + const stream = this.config.streams[this.streamIdx]; + this.config.url = stream.url; + this.config.entity = stream.entity; + this.mode = stream.mode || this.defaultMode; + } + + getStreamName() { + return this.config.streams[this.streamIdx].name || `S${this.streamIdx}`; + } + oninit() { super.oninit(); this.renderMain(); @@ -383,6 +411,15 @@ class WebRTCCamera extends VideoRTC { .volume { display: none; } + .stream { + padding-top: 2px; + margin-left: 2px; + font-weight: 400; + font-size: 20px; + color: white; + display: none; + cursor: pointer; + } `); card.insertAdjacentHTML('beforeend', ` @@ -390,6 +427,7 @@ class WebRTCCamera extends VideoRTC {
+ ${this.getStreamName()} @@ -427,6 +465,11 @@ class WebRTCCamera extends VideoRTC { }); // Chrome 71 } else if (icon === 'mdi:fullscreen-exit') { this.exitFullscreen(); + } else if (ev.target.className === 'stream'){ + this.onNextStream(); + this.ondisconnect(); + this.connectedCallback(); + ev.target.innerText = this.getStreamName(); } }); @@ -460,6 +503,8 @@ class WebRTCCamera extends VideoRTC { fullscreen.icon = this.fullscreenElement() ? 'mdi:fullscreen-exit' : 'mdi:fullscreen'; }); + const stream = this.querySelector('.stream'); + stream.style.display = this.config.streams.length > 1 ? 'block' : 'none'; } renderShortcuts() {