Automatically pause/unload media on document visibility changes.

This commit is contained in:
Dermot Duffy
2022-01-27 19:27:24 -08:00
parent 748b4fcf54
commit 87aaa25529
3 changed files with 41 additions and 25 deletions
+1 -1
View File
@@ -191,7 +191,7 @@ live:
| - | - | - | - |
| `preload` | `false` | :heavy_multiplication_x: | Whether or not to preload the live view. Preloading causes the live view to render in the background regardless of what view is actually shown, so it's instantly available when requested. This consumes additional network/CPU resources continually. |
| `lazy_load` | `true` | :heavy_multiplication_x: | Whether or not to lazily load cameras in the camera carousel. Setting this will `false` will cause all cameras to load simultaneously when the `live` carousel is opened (or cause all cameras to load continually if both `lazy_load` and `preload` are `true`). This will result in a smoother carousel experience at a cost of (potentially) a substantial amount of continually streamed data. |
| `lazy_unload` | `false` | :heavy_multiplication_x: | Whether or not to lazily **un**load cameras in the camera carousel, or just leave the camera paused. Setting this to `true` will cause cameras to be entirely unloaded when they are no longer visible. This will cause a reloading delay on revisiting that camera in the carousel but will save the streaming network resources that are otherwise consumed. |
| `lazy_unload` | `false` | :heavy_multiplication_x: | Whether or not to lazily **un**load cameras in the camera carousel, or just leave the camera paused. Setting this to `true` will cause cameras to be entirely unloaded when they are no longer visible (either because the carousel has scrolled past them, or because the document has been marked hidden/inactive by the browser). This will cause a reloading delay on revisiting that camera in the carousel but will save the streaming network resources that are otherwise consumed. |
| `draggable` | `true` | :heavy_multiplication_x: | Whether or not the live carousel can be dragged left or right, via touch/swipe and mouse dragging. |
| `provider` | `frigate` | :white_check_mark: | The means through which the live camera view is displayed. See [Live Provider](#live-provider) below.|
| `actions` | | :white_check_mark: | Actions to use for the `live` view. See [actions](#actions) below.|
+13
View File
@@ -39,6 +39,7 @@ export function Lazyload(userOptions?: LazyloadOptionsType): LazyloadType {
if (options.lazyunloadCallback) {
unloadEvents.forEach((evt) => carousel.on(evt, lazyunloadHandler));
}
document.addEventListener('visibilitychange', visibilityHandler);
}
/**
@@ -51,6 +52,18 @@ export function Lazyload(userOptions?: LazyloadOptionsType): LazyloadType {
if (options.lazyunloadCallback) {
unloadEvents.forEach((evt) => carousel.off(evt, lazyunloadHandler));
}
document.removeEventListener('visibilitychange', visibilityHandler);
}
/**
* Handle document visibility changes.
*/
function visibilityHandler(): void {
if (document.visibilityState == 'hidden' && lazyunloadHandler) {
lazyunloadHandler();
} else if (document.visibilityState == 'visible' && lazyloadHandler) {
lazyloadHandler();
}
}
/**
+27 -24
View File
@@ -2,17 +2,10 @@ import { EmblaCarouselType, EmblaPluginType } from 'embla-carousel';
import { FrigateCardMediaPlayer } from '../../types.js';
export type MediaAutoPlayPauseOptionsType = {
autoplay?: boolean;
autopause?: boolean;
playerSelector: string;
};
export const defaultOptions: Partial<MediaAutoPlayPauseOptionsType> = {
// Frigate card media autoplays when the media loads, not necessarily when the
// slide is selected.
autoplay: false,
autopause: true,
};
export const defaultOptions: Partial<MediaAutoPlayPauseOptionsType> = {};
export type MediaAutoPlayPauseType = EmblaPluginType<MediaAutoPlayPauseOptionsType> & {
play: () => void;
@@ -33,29 +26,32 @@ export function MediaAutoPlayPause(
carousel = embla;
slides = carousel.slideNodes();
if (options.autopause) {
carousel.on('destroy', pauseAllHandler);
carousel.on('select', pausePrevious);
}
// Frigate card media autoplays when the media loads not necessarily when the
// slide is selected, so only pause based on carousel events.
carousel.on('destroy', pauseAllHandler);
carousel.on('select', pausePrevious);
if (options.autoplay) {
carousel.on('select', play);
carousel.on('init', play);
}
document.addEventListener('visibilitychange', visibilityHandler);
}
/**
* Destroy the plugin.
*/
function destroy(): void {
if (options.autopause) {
carousel.off('destroy', pauseAllHandler);
carousel.off('select', pausePrevious);
}
carousel.off('destroy', pauseAllHandler);
carousel.off('select', pausePrevious);
if (options.autoplay) {
carousel.off('select', play);
carousel.off('init', play);
document.removeEventListener('visibilitychange', visibilityHandler);
}
/**
* Handle document visibility changes.
*/
function visibilityHandler(): void {
if (document.visibilityState == 'hidden') {
pause();
} else if (document.visibilityState == 'visible') {
play();
}
}
@@ -82,10 +78,17 @@ export function MediaAutoPlayPause(
getPlayer(slides[carousel.selectedScrollSnap()])?.play();
}
/**
* Autopause the current slide.
*/
function pause(): void {
getPlayer(slides[carousel.selectedScrollSnap()])?.pause();
}
/**
* Autopause the previous slide.
*/
function pausePrevious(): void {
function pausePrevious(): void {
getPlayer(slides[carousel.previousScrollSnap()])?.pause();
}