Add play/pause event support.
This commit is contained in:
+16
-33
@@ -106,8 +106,8 @@ export class FrigateCard extends LitElement {
|
||||
@query('frigate-card-menu')
|
||||
_menu!: FrigateCardMenu;
|
||||
|
||||
// Whether or not there is an active clip being played.
|
||||
protected _clipPlaying = false;
|
||||
// Whether or not media is actively playing (live or clip).
|
||||
protected _mediaPlaying = false;
|
||||
|
||||
// A small cache to avoid needing to create a new list of entities every time
|
||||
// a hass update arrives.
|
||||
@@ -253,7 +253,7 @@ export class FrigateCard extends LitElement {
|
||||
// are browsing the mini-gallery). Do not allow re-rendering from a Home
|
||||
// Assistant update if there's been recent interaction (e.g. clicks on the
|
||||
// card) or if there is a clip active playing.
|
||||
if (this._interactionTimerID || this._clipPlaying) {
|
||||
if (this._interactionTimerID || this._mediaPlaying) {
|
||||
return false;
|
||||
}
|
||||
return shouldUpdateBasedOnHass(this._hass, oldHass, this._entitiesToMonitor);
|
||||
@@ -294,35 +294,6 @@ export class FrigateCard extends LitElement {
|
||||
return `${this.config.frigate_url}/events?camera=${this.config.frigate_camera_name}`;
|
||||
}
|
||||
|
||||
public updated(): void {
|
||||
this.updateComplete.then(() => {
|
||||
// DOM elements are not always present until after updateComplete promise
|
||||
// is resolved. Note that children of children (i.e. the underlying video
|
||||
// element) is not always present even when the promise returns, so
|
||||
// capture the event at the upper shadow root instead.
|
||||
const hls_player = this.renderRoot
|
||||
?.querySelector('ha-card')
|
||||
?.querySelector('ha-hls-player');
|
||||
|
||||
if (hls_player) {
|
||||
hls_player.shadowRoot?.addEventListener(
|
||||
'play',
|
||||
() => {
|
||||
this._clipPlaying = true;
|
||||
},
|
||||
true,
|
||||
);
|
||||
hls_player.shadowRoot?.addEventListener(
|
||||
'pause',
|
||||
() => {
|
||||
this._clipPlaying = true;
|
||||
},
|
||||
true,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Record interactions with the card.
|
||||
protected _interactionHandler(): void {
|
||||
if (!this.config.view_timeout) {
|
||||
@@ -364,6 +335,14 @@ export class FrigateCard extends LitElement {
|
||||
};
|
||||
}
|
||||
|
||||
protected _playHandler(): void {
|
||||
this._mediaPlaying = true;
|
||||
}
|
||||
|
||||
protected _pauseHandler(): void {
|
||||
this._mediaPlaying = false;
|
||||
}
|
||||
|
||||
protected _mediaLoadHandler(e: CustomEvent<MediaLoadInfo>): void {
|
||||
const mediaInfo = e.detail;
|
||||
|
||||
@@ -461,7 +440,9 @@ export class FrigateCard extends LitElement {
|
||||
.autoplayClip=${this.config.autoplay_clip}
|
||||
@frigate-card:change-view=${this._changeViewHandler}
|
||||
@frigate-card:media-load=${this._mediaLoadHandler}
|
||||
>
|
||||
@frigate-card:pause=${this._pauseHandler}
|
||||
@frigate-card:play=${this._playHandler}
|
||||
>
|
||||
</frigate-card-viewer>`
|
||||
: ``}
|
||||
${this._view.is('live')
|
||||
@@ -469,6 +450,8 @@ export class FrigateCard extends LitElement {
|
||||
.hass=${this._hass}
|
||||
.config=${this.config}
|
||||
@frigate-card:media-load=${this._mediaLoadHandler}
|
||||
@frigate-card:pause=${this._pauseHandler}
|
||||
@frigate-card:play=${this._playHandler}
|
||||
>
|
||||
</frigate-card-live>`
|
||||
: ``}
|
||||
|
||||
+36
-8
@@ -7,7 +7,12 @@ import { signedPathSchema } from '../types';
|
||||
import type { ExtendedHomeAssistant, FrigateCardConfig } from '../types';
|
||||
|
||||
import { localize } from '../localize/localize';
|
||||
import { dispatchMediaLoadEvent, homeAssistantWSRequest } from '../common';
|
||||
import {
|
||||
dispatchMediaLoadEvent,
|
||||
dispatchPauseEvent,
|
||||
dispatchPlayEvent,
|
||||
homeAssistantWSRequest,
|
||||
} from '../common';
|
||||
import {
|
||||
renderMessage,
|
||||
renderErrorMessage,
|
||||
@@ -95,7 +100,6 @@ export class FrigateCardViewerWebRTC extends LitElement {
|
||||
protected _webRTCElement: HTMLElement | null = null;
|
||||
|
||||
protected _createWebRTC(): TemplateResult | void {
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const webrtcElement = customElements.get('webrtc-camera') as any;
|
||||
if (webrtcElement) {
|
||||
@@ -125,11 +129,30 @@ export class FrigateCardViewerWebRTC extends LitElement {
|
||||
this.updateComplete.then(() => {
|
||||
const video = this.renderRoot.querySelector('#video') as HTMLVideoElement;
|
||||
if (video) {
|
||||
video.onloadedmetadata = () => {
|
||||
const onloadedmetadata = video.onloadedmetadata;
|
||||
const onplay = video.onplay;
|
||||
const onpause = video.onpause;
|
||||
|
||||
video.onloadedmetadata = (e) => {
|
||||
if (onloadedmetadata) {
|
||||
onloadedmetadata.call(video, e);
|
||||
}
|
||||
dispatchMediaLoadEvent(this, video);
|
||||
}
|
||||
};
|
||||
video.onplay = (e) => {
|
||||
if (onplay) {
|
||||
onplay.call(video, e);
|
||||
}
|
||||
dispatchPlayEvent(this);
|
||||
};
|
||||
video.onpause = (e) => {
|
||||
if (onpause) {
|
||||
onpause.call(video, e);
|
||||
}
|
||||
dispatchPauseEvent(this);
|
||||
};
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
@@ -212,11 +235,16 @@ export class FrigateCardViewerJSMPEG extends LitElement {
|
||||
// amount of time the canvas is empty (and show the spinner
|
||||
// instead).
|
||||
play: () => {
|
||||
dispatchPlayEvent(this);
|
||||
resolve(html`${this._jsmpegCanvasElement}`);
|
||||
},
|
||||
pause: () => {
|
||||
dispatchPauseEvent(this);
|
||||
},
|
||||
},
|
||||
},
|
||||
{ protocols: [],
|
||||
{
|
||||
protocols: [],
|
||||
videoBufferSize: 1024 * 1024 * 4,
|
||||
onVideoDecode: () => {
|
||||
// This is the only callback that is called after the dimensions
|
||||
@@ -226,8 +254,8 @@ export class FrigateCardViewerJSMPEG extends LitElement {
|
||||
videoDecoded = true;
|
||||
dispatchMediaLoadEvent(this, this._jsmpegCanvasElement);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
html,
|
||||
} from 'lit';
|
||||
import { customElement } from 'lit/decorators';
|
||||
import { dispatchMediaLoadEvent } from '../common';
|
||||
import { dispatchMediaLoadEvent, dispatchPauseEvent, dispatchPlayEvent } from '../common';
|
||||
|
||||
customElements.whenDefined("ha-hls-player").then(() => {
|
||||
@customElement("frigate-card-ha-hls-player")
|
||||
@@ -33,6 +33,8 @@ customElements.whenDefined("ha-hls-player").then(() => {
|
||||
?controls=${this.controls}
|
||||
@loadedmetadata=${(e) => dispatchMediaLoadEvent(this, e)}
|
||||
@loadeddata=${this._elementResized}
|
||||
@pause=${() => dispatchPauseEvent(this)}
|
||||
@play=${() => dispatchPlayEvent(this)}
|
||||
></video>
|
||||
`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user