diff --git a/src/frigate-card.scss b/src/frigate-card.scss index b2dbe57b..1dd8cb9f 100644 --- a/src/frigate-card.scss +++ b/src/frigate-card.scss @@ -56,6 +56,7 @@ .frigate-card-navbar { position: absolute; + top: 0px; width: 50px; z-index: 1; } @@ -65,6 +66,11 @@ right: 3px; } +.frigate-card-statusbar-webrtc { + @extend .frigate-card-navbar; + left: 53px; +} + ha-icon-button.button { position: relative; z-index: 2; diff --git a/src/frigate-card.ts b/src/frigate-card.ts index 2e56efa0..58264ded 100644 --- a/src/frigate-card.ts +++ b/src/frigate-card.ts @@ -1,5 +1,8 @@ // TODO Make editor work. -// TODO Explore webrtc support. +// TODO Add title to clips / snapshots playing/viewing +// TODO Add tooltips for gallary clips with details of event. +// TODO Sometimes webrtc component shows up as not found in browser (maybe after fresh build?) +// TODO Add gallery item to take to media browser // TODO Add documentation & screenshots. /* eslint-disable @typescript-eslint/no-explicit-any */ @@ -65,6 +68,8 @@ export class FrigateCard extends LitElement { this._viewMode = FrigateCardView.LIVE; this._viewEvent = null; this._interactionTimerID = null; + this._webrtcElement = null; + this._hass = null; } // Get the configuration element. @@ -76,9 +81,15 @@ export class FrigateCard extends LitElement { public static getStubConfig(): Record { return {}; } + set hass(hass: HomeAssistant) { + if (this._webrtcElement) { + this._webrtcElement.hass = hass; + } + this._hass = hass; + } @property({ attribute: false }) - public hass!: HomeAssistant; + protected _hass: HomeAssistant | null; @state() public config!: FrigateCardConfig; @@ -90,6 +101,7 @@ export class FrigateCard extends LitElement { protected _viewEvent: FrigateEvent | null; protected _interactionTimerID: number | null; + protected _webrtcElement: any | null; // Set the object configuration. public setConfig(inputConfig: FrigateCardConfig): void { @@ -118,10 +130,23 @@ export class FrigateCard extends LitElement { } } + if (config.live_provider == "webrtc") { + // Create a WebRTC element (https://github.com/AlexxIT/WebRTC) + const webrtcElement = customElements.get('webrtc-camera'); + if (webrtcElement) { + const webrtc = new webrtcElement(); + webrtc.setConfig(config.webrtc || {}); + webrtc.hass = this._hass; + this._webrtcElement = webrtc; + } else { + throw new Error(localize('common.missing_webrtc')); + } + } + this.config = config; this._setViewModeToDefault(); } - + // Set the view mode to the configured default. protected _setViewModeToDefault(): void { if (this.config.view_default == "live") { @@ -139,19 +164,9 @@ export class FrigateCard extends LitElement { } } - // == RTC experimentation == - // const div = document.createElement("div"); - // const webrtcElement = customElements.get('webrtc-camera'); - // const webrtc = new webrtcElement(); - // webrtc.setConfig({ "entity": "camera.landing_rtsp" }); - // webrtc.hass = this.hass; - // div.appendChild(webrtc); - // this.renderRoot.appendChild(div); - // == - // Determine whether the card should be updated. protected shouldUpdate(changedProps: PropertyValues): boolean { - if (!this.config || !this.hass) { + if (!this.config || !this._hass) { return false; } @@ -166,16 +181,16 @@ export class FrigateCard extends LitElement { return true; } - const oldHass = changedProps.get('hass') as HomeAssistant | undefined; + const oldHass = changedProps.get('_hass') as HomeAssistant | undefined; if (oldHass) { - if (cameraEntity in this.hass - && oldHass.states[cameraEntity] !== this.hass.states[cameraEntity]) { + if (cameraEntity in this._hass + && oldHass.states[cameraEntity] !== this._hass.states[cameraEntity]) { return true; } if (motionEntity - && motionEntity in this.hass - && oldHass.states[motionEntity] !== this.hass.states[motionEntity]) { + && motionEntity in this._hass + && oldHass.states[motionEntity] !== this._hass.states[motionEntity]) { return true; } return false; @@ -297,8 +312,9 @@ export class FrigateCard extends LitElement { if (stop) { video.pause(); video.currentTime = 0; - } else { - if (is_live) { + } else if (is_live) { + // Duration on webrtc is infinity so cannot fast-forward. + if (!this._webrtcElement) { // If it's a live view, 'fast-forward' to most recent content. const duration = video.duration; video.currentTime = duration; @@ -314,21 +330,28 @@ export class FrigateCard extends LitElement { controlVideo( stop, false, - this.shadowRoot?.querySelector( - `#frigate-card-clip-player`) as HTMLVideoElement); + this.shadowRoot?. + querySelector('video.frigate-card-viewer') as HTMLVideoElement); } if (control_live) { // Don't have direct access to the live video player as it is buried in // multiple components/shadow-roots, so need to navigate the path to get to