Use HLS player instead of video element for clips.

This commit is contained in:
Dermot Duffy
2021-08-27 20:47:05 -07:00
parent ced7dc9604
commit 0f8a84809f
+40 -14
View File
@@ -45,7 +45,8 @@ import dayjs from 'dayjs';
import dayjs_utc from 'dayjs/plugin/utc'; import dayjs_utc from 'dayjs/plugin/utc';
import dayjs_timezone from 'dayjs/plugin/timezone'; import dayjs_timezone from 'dayjs/plugin/timezone';
const URL_TROUBLESHOOTING = "https://github.com/dermotduffy/frigate-hass-card#troubleshooting"; const URL_TROUBLESHOOTING =
'https://github.com/dermotduffy/frigate-hass-card#troubleshooting';
// Load dayjs plugins. // Load dayjs plugins.
dayjs.extend(dayjs_timezone); dayjs.extend(dayjs_timezone);
@@ -431,8 +432,7 @@ export class FrigateCard extends LitElement {
): TemplateResult { ): TemplateResult {
return html` <div class="frigate-card-attention"> return html` <div class="frigate-card-attention">
<span> <span>
<ha-icon icon="${icon}"> <ha-icon icon="${icon}"> </ha-icon>
</ha-icon>
${message ? html`&nbsp;${message}` : ''} ${message ? html`&nbsp;${message}` : ''}
</span> </span>
</div>`; </div>`;
@@ -442,7 +442,8 @@ export class FrigateCard extends LitElement {
protected _renderError(error: string): TemplateResult { protected _renderError(error: string): TemplateResult {
return this._renderAttentionIcon( return this._renderAttentionIcon(
'mdi:alert-circle', 'mdi:alert-circle',
html`${error}. See <a href="${URL_TROUBLESHOOTING}">troubleshooting</a></span>.`); html`${error}. See <a href="${URL_TROUBLESHOOTING}">troubleshooting</a></span>.`,
);
} }
// Generate a human-readable title from an event. // Generate a human-readable title from an event.
@@ -606,7 +607,7 @@ export class FrigateCard extends LitElement {
if (!event.has_clip) { if (!event.has_clip) {
return null; return null;
} }
return `${this.config.frigate_url}/vod/event/${event.id}/index.m3u8` return `${this.config.frigate_url}/vod/event/${event.id}/index.m3u8`;
} }
protected _getSnapshotURLFromEvent(event: FrigateEvent): string | null { protected _getSnapshotURLFromEvent(event: FrigateEvent): string | null {
@@ -654,24 +655,49 @@ export class FrigateCard extends LitElement {
this._eventBeingShown = event; this._eventBeingShown = event;
return html` return html`
<video <ha-hls-player
.hass=${this._hass}
.url=${clipURL}
class="frigate-card-viewer" class="frigate-card-viewer"
muted muted
controls controls
playsinline playsinline
@play=${() => { allow-exoplayer
this._clipPlaying = true;
}}
@pause=${() => {
this._clipPlaying = false;
}}
?autoplay="${autoplay}" ?autoplay="${autoplay}"
> >
<source src="${clipURL}" type="application/x-mpegURL" /> </ha-hls-player>
</video>
`; `;
} }
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,
);
}
});
}
// Render a snapshot. // Render a snapshot.
protected async _renderSnapshotViewer(): Promise<TemplateResult> { protected async _renderSnapshotViewer(): Promise<TemplateResult> {
let event: FrigateEvent, events: FrigateGetEventsResponse; let event: FrigateEvent, events: FrigateGetEventsResponse;