From bdc09c58382c2c11568e33b69dbfaf4ecb2b17c1 Mon Sep 17 00:00:00 2001 From: Dermot Duffy Date: Sat, 15 Jan 2022 11:35:10 -0800 Subject: [PATCH] Simplify autoplay functionality. Prevents all media in an entire carousel from simultaneously autoplaying in some browsers. Changes the default autoplay value to true, and applies autoplay configuration to all clips (whether from the gallery of most recent 'clip'). --- README.md | 2 +- src/components/carousel.ts | 2 +- src/components/live.ts | 2 +- src/components/media-carousel.ts | 2 +- src/components/viewer.ts | 42 +++++++++++++++++++++++--------- src/localize/languages/en.json | 2 +- src/patches/ha-hls-player.ts | 13 ++++++++++ src/types.ts | 2 +- 8 files changed, 50 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 0ce5fa77..66c34274 100644 --- a/README.md +++ b/README.md @@ -276,7 +276,7 @@ event_viewer: | Option | Default | Overridable | Description | | - | - | - | - | -| `autoplay_clip` | `false` | :heavy_multiplication_x: | Whether or not to autoplay clips in the 'clip' [view](#views). Clips manually chosen in the clips gallery will still autoplay.| +| `autoplay_clip` | `true` | :heavy_multiplication_x: | Whether or not to autoplay clips.| | `lazy_load` | `true` | :heavy_multiplication_x: | Whether or not to lazily load media in the event viewer carousel. Setting this will false will fetch all media immediately which may make the carousel experience smoother at a cost of (potentially) a substantial number of simultaneous media fetches on load. | | `draggable` | `true` | :heavy_multiplication_x: | Whether or not the event viewer carousel can be dragged left or right, via touch/swipe and mouse dragging. | | `controls` | | :heavy_multiplication_x: | Configuration for the event viewer. See below. | diff --git a/src/components/carousel.ts b/src/components/carousel.ts index c6febeda..540b3ae5 100644 --- a/src/components/carousel.ts +++ b/src/components/carousel.ts @@ -58,7 +58,7 @@ export class FrigateCardCarousel extends LitElement { } /** - * Load the carousel with "slides". + * Initialize the carousel. */ protected _initCarousel(): void { const carouselNode = this.renderRoot.querySelector( diff --git a/src/components/live.ts b/src/components/live.ts index 21d6f76d..0add77d1 100644 --- a/src/components/live.ts +++ b/src/components/live.ts @@ -1,4 +1,4 @@ -// TODO clip autoplay not working as expected +// TODO use the schema default remover code to simplify config schema // TODO verify README links worked correctly (e.g. basic cameras configuration) import { diff --git a/src/components/media-carousel.ts b/src/components/media-carousel.ts index 0460d225..9b1b73b1 100644 --- a/src/components/media-carousel.ts +++ b/src/components/media-carousel.ts @@ -67,7 +67,7 @@ export class FrigateCardMediaCarousel extends FrigateCardCarousel { } /** - * Initializse the carousel with "slides" (clips or snapshots). + * Initialize the carousel. */ protected _initCarousel(): void { super._initCarousel(); diff --git a/src/components/viewer.ts b/src/components/viewer.ts index 47b7e339..b883824b 100644 --- a/src/components/viewer.ts +++ b/src/components/viewer.ts @@ -522,6 +522,37 @@ export class FrigateCardViewerCarousel extends FrigateCardMediaCarousel { } } + /** + * Play the clip being shown to the user (video player may already be loaded + * depending on the lazyload configuration). + */ + protected _autoplayHandler(): void { + if (!this._carousel) { + return; + } + const nodes = this._carousel.slideNodes(); + this._carousel.slidesInView(true).forEach((slide) => { + const player = nodes[slide].querySelector('frigate-card-ha-hls-player') as + | (HTMLElement & { play: () => void }) + | undefined; + if (player) { + player.play(); + } + }); + } + + /** + * Initialize the carousel. + */ + protected _initCarousel(): void { + super._initCarousel(); + + if (this._carousel && this.viewerConfig && this.viewerConfig.autoplay_clip) { + this._carousel.on('init', this._autoplayHandler.bind(this)); + this._carousel.on('select', this._autoplayHandler.bind(this)); + } + } + /** * Get slides to include in the render. * @returns The slides to include in the render and an index keyed by slide @@ -643,22 +674,11 @@ export class FrigateCardViewerCarousel extends FrigateCardMediaCarousel { return; } - // In this block, no clip has been manually selected, so this is loading - // the most recent clip on card load. In this mode, autoplay of the clip - // may be disabled by configuration. If does not make sense to disable - // autoplay when the user has explicitly picked an event to play in the - // gallery. - let autoplay = true; - if (this.view.is('clip') || this.view.is('snapshot')) { - autoplay = this.viewerConfig.autoplay_clip; - } - return html`
${this.view.isClipRelatedView() ? html` { @customElement('frigate-card-ha-hls-player') // eslint-disable-next-line @typescript-eslint/no-unused-vars class FrigateCardHaHlsPlayer extends customElements.get('ha-hls-player') { + protected _videoRef: Ref = createRef(); + + /** + * Play the video. + */ + public play(): void { + if (this._videoRef.value) { + this._videoRef.value.play(); + } + } + // ===================================================================================== // Minor modifications from: // - https://github.com/home-assistant/frontend/blob/dev/src/components/ha-hls-player.ts @@ -29,6 +41,7 @@ customElements.whenDefined('ha-hls-player').then(() => { protected render(): TemplateResult { return html`