Implement auto_mute .

This commit is contained in:
Dermot Duffy
2022-05-08 08:05:33 -07:00
parent 66588ee1c6
commit d552cf1a0d
9 changed files with 71 additions and 15 deletions
+28 -3
View File
@@ -1,11 +1,12 @@
import { EmblaCarouselType, EmblaPluginType } from 'embla-carousel'; import { EmblaCarouselType, EmblaPluginType } from 'embla-carousel';
import { AutoPauseCondition, FrigateCardMediaPlayer } from '../../types.js'; import { AutoMuteCondition, AutoPauseCondition, FrigateCardMediaPlayer } from '../../types.js';
export type AutoMediaPluginOptionsType = { export type AutoMediaPluginOptionsType = {
playerSelector: string; playerSelector: string;
autoPlayWhenVisible?: boolean; autoPlayWhenVisible?: boolean;
autoUnmuteWhenVisible?: boolean; autoUnmuteWhenVisible?: boolean;
autoPauseCondition?: AutoPauseCondition; autoPauseCondition?: AutoPauseCondition;
autoMuteCondition?: AutoMuteCondition;
}; };
export const defaultOptions: Partial<AutoMediaPluginOptionsType> = { export const defaultOptions: Partial<AutoMediaPluginOptionsType> = {
@@ -51,7 +52,12 @@ export function AutoMediaPlugin(
carousel.on('select', pausePrevious); carousel.on('select', pausePrevious);
} }
carousel.on('destroy', mute); carousel.on('destroy', mute);
if (
options.autoMuteCondition &&
['all', 'unselected'].includes(options.autoMuteCondition)
) {
carousel.on('select', mutePrevious); carousel.on('select', mutePrevious);
}
document.addEventListener('visibilitychange', visibilityHandler); document.addEventListener('visibilitychange', visibilityHandler);
} }
@@ -68,7 +74,12 @@ export function AutoMediaPlugin(
carousel.off('select', pausePrevious); carousel.off('select', pausePrevious);
} }
carousel.off('destroy', mute); carousel.off('destroy', mute);
if (
options.autoMuteCondition &&
['all', 'unselected'].includes(options.autoMuteCondition)
) {
carousel.off('select', mutePrevious); carousel.off('select', mutePrevious);
}
document.removeEventListener('visibilitychange', visibilityHandler); document.removeEventListener('visibilitychange', visibilityHandler);
} }
@@ -84,7 +95,12 @@ export function AutoMediaPlugin(
) { ) {
pauseAll(); pauseAll();
} }
mute(); if (
options.autoMuteCondition &&
['all', 'hidden'].includes(options.autoMuteCondition)
) {
muteAll();
}
} else if (document.visibilityState == 'visible') { } else if (document.visibilityState == 'visible') {
if (options.autoPlayWhenVisible) { if (options.autoPlayWhenVisible) {
play(); play();
@@ -126,7 +142,7 @@ export function AutoMediaPlugin(
} }
/** /**
* Pause the previous slide. * Pause all slides.
*/ */
function pauseAll(): void { function pauseAll(): void {
for (const slide of slides) { for (const slide of slides) {
@@ -155,6 +171,15 @@ export function AutoMediaPlugin(
getPlayer(slides[carousel.previousScrollSnap()])?.mute(); getPlayer(slides[carousel.previousScrollSnap()])?.mute();
} }
/**
* Mute all slides.
*/
function muteAll(): void {
for (const slide of slides) {
getPlayer(slide)?.mute();
}
}
const self: AutoMediaPluginType = { const self: AutoMediaPluginType = {
name: 'AutoMediaPlugin', name: 'AutoMediaPlugin',
options, options,
+3
View File
@@ -303,6 +303,9 @@ export class FrigateCardLiveCarousel extends FrigateCardMediaCarousel {
...(this.liveConfig?.auto_pause && { ...(this.liveConfig?.auto_pause && {
autoPauseCondition: this.liveConfig.auto_pause, autoPauseCondition: this.liveConfig.auto_pause,
}), }),
...(this.liveConfig?.auto_mute && {
autoMuteCondition: this.liveConfig.auto_mute,
}),
}), }),
]; ];
} }
+3
View File
@@ -285,6 +285,9 @@ export class FrigateCardViewerCarousel extends FrigateCardMediaCarousel {
...(this.viewerConfig?.auto_pause && { ...(this.viewerConfig?.auto_pause && {
autoPauseCondition: this.viewerConfig.auto_pause, autoPauseCondition: this.viewerConfig.auto_pause,
}), }),
...(this.viewerConfig?.auto_mute && {
autoMuteCondition: this.viewerConfig.auto_mute,
}),
}), }),
]; ];
} }
+2
View File
@@ -45,6 +45,7 @@ export const CONF_EVENT_GALLERY_CONTROLS_THUMBNAILS_SIZE =
export const CONF_EVENT_VIEWER = 'event_viewer' as const; export const CONF_EVENT_VIEWER = 'event_viewer' as const;
export const CONF_EVENT_VIEWER_AUTO_PAUSE = `${CONF_EVENT_VIEWER}.auto_pause` as const; export const CONF_EVENT_VIEWER_AUTO_PAUSE = `${CONF_EVENT_VIEWER}.auto_pause` as const;
export const CONF_EVENT_VIEWER_AUTO_PLAY = `${CONF_EVENT_VIEWER}.auto_play` as const; export const CONF_EVENT_VIEWER_AUTO_PLAY = `${CONF_EVENT_VIEWER}.auto_play` as const;
export const CONF_EVENT_VIEWER_AUTO_MUTE = `${CONF_EVENT_VIEWER}.auto_mute` as const;
export const CONF_EVENT_VIEWER_AUTO_UNMUTE = `${CONF_EVENT_VIEWER}.auto_unmute` as const; export const CONF_EVENT_VIEWER_AUTO_UNMUTE = `${CONF_EVENT_VIEWER}.auto_unmute` as const;
export const CONF_EVENT_VIEWER_DRAGGABLE = `${CONF_EVENT_VIEWER}.draggable` as const; export const CONF_EVENT_VIEWER_DRAGGABLE = `${CONF_EVENT_VIEWER}.draggable` as const;
export const CONF_EVENT_VIEWER_LAZY_LOAD = `${CONF_EVENT_VIEWER}.lazy_load` as const; export const CONF_EVENT_VIEWER_LAZY_LOAD = `${CONF_EVENT_VIEWER}.lazy_load` as const;
@@ -69,6 +70,7 @@ export const CONF_EVENT_VIEWER_CONTROLS_TITLE_DURATION_SECONDS =
export const CONF_LIVE = 'live' as const; export const CONF_LIVE = 'live' as const;
export const CONF_LIVE_AUTO_PAUSE = `${CONF_LIVE}.auto_pause` as const; export const CONF_LIVE_AUTO_PAUSE = `${CONF_LIVE}.auto_pause` as const;
export const CONF_LIVE_AUTO_MUTE = `${CONF_LIVE}.auto_mute` as const;
export const CONF_LIVE_AUTO_UNMUTE = `${CONF_LIVE}.auto_unmute` as const; export const CONF_LIVE_AUTO_UNMUTE = `${CONF_LIVE}.auto_unmute` as const;
export const CONF_LIVE_CONTROLS_NEXT_PREVIOUS_STYLE = export const CONF_LIVE_CONTROLS_NEXT_PREVIOUS_STYLE =
`${CONF_LIVE}.controls.next_previous.style` as const; `${CONF_LIVE}.controls.next_previous.style` as const;
+14 -4
View File
@@ -34,6 +34,7 @@ import {
CONF_EVENT_GALLERY_CONTROLS_THUMBNAILS_SHOW_CONTROLS, CONF_EVENT_GALLERY_CONTROLS_THUMBNAILS_SHOW_CONTROLS,
CONF_EVENT_GALLERY_CONTROLS_THUMBNAILS_SHOW_DETAILS, CONF_EVENT_GALLERY_CONTROLS_THUMBNAILS_SHOW_DETAILS,
CONF_EVENT_GALLERY_CONTROLS_THUMBNAILS_SIZE, CONF_EVENT_GALLERY_CONTROLS_THUMBNAILS_SIZE,
CONF_EVENT_VIEWER_AUTO_MUTE,
CONF_EVENT_VIEWER_AUTO_PAUSE, CONF_EVENT_VIEWER_AUTO_PAUSE,
CONF_EVENT_VIEWER_AUTO_PLAY, CONF_EVENT_VIEWER_AUTO_PLAY,
CONF_EVENT_VIEWER_AUTO_UNMUTE, CONF_EVENT_VIEWER_AUTO_UNMUTE,
@@ -51,6 +52,7 @@ import {
CONF_IMAGE_MODE, CONF_IMAGE_MODE,
CONF_IMAGE_REFRESH_SECONDS, CONF_IMAGE_REFRESH_SECONDS,
CONF_IMAGE_URL, CONF_IMAGE_URL,
CONF_LIVE_AUTO_MUTE,
CONF_LIVE_AUTO_PAUSE, CONF_LIVE_AUTO_PAUSE,
CONF_LIVE_AUTO_UNMUTE, CONF_LIVE_AUTO_UNMUTE,
CONF_LIVE_CONTROLS_NEXT_PREVIOUS_SIZE, CONF_LIVE_CONTROLS_NEXT_PREVIOUS_SIZE,
@@ -1010,6 +1012,10 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
CONF_LIVE_AUTO_PAUSE, CONF_LIVE_AUTO_PAUSE,
this._mediaActionConditions, this._mediaActionConditions,
)} )}
${this._renderOptionSelector(
CONF_LIVE_AUTO_MUTE,
this._mediaActionConditions,
)}
${this._renderSwitch(CONF_LIVE_AUTO_UNMUTE, defaults.live.auto_unmute)} ${this._renderSwitch(CONF_LIVE_AUTO_UNMUTE, defaults.live.auto_unmute)}
${this._renderOptionSelector( ${this._renderOptionSelector(
CONF_LIVE_CONTROLS_NEXT_PREVIOUS_STYLE, CONF_LIVE_CONTROLS_NEXT_PREVIOUS_STYLE,
@@ -1077,14 +1083,18 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
CONF_EVENT_VIEWER_AUTO_PLAY, CONF_EVENT_VIEWER_AUTO_PLAY,
defaults.event_viewer.auto_play, defaults.event_viewer.auto_play,
)} )}
${this._renderSwitch(
CONF_EVENT_VIEWER_AUTO_UNMUTE,
defaults.event_viewer.auto_unmute,
)}
${this._renderOptionSelector( ${this._renderOptionSelector(
CONF_EVENT_VIEWER_AUTO_PAUSE, CONF_EVENT_VIEWER_AUTO_PAUSE,
this._mediaActionConditions, this._mediaActionConditions,
)} )}
${this._renderOptionSelector(
CONF_EVENT_VIEWER_AUTO_MUTE,
this._mediaActionConditions,
)}
${this._renderSwitch(
CONF_EVENT_VIEWER_AUTO_UNMUTE,
defaults.event_viewer.auto_unmute,
)}
${this._renderSwitch( ${this._renderSwitch(
CONF_EVENT_VIEWER_DRAGGABLE, CONF_EVENT_VIEWER_DRAGGABLE,
defaults.event_viewer.draggable, defaults.event_viewer.draggable,
+2
View File
@@ -77,6 +77,7 @@
"event_viewer": { "event_viewer": {
"auto_play": "Automatically play media", "auto_play": "Automatically play media",
"auto_pause": "Automatically pause media", "auto_pause": "Automatically pause media",
"auto_mute": "Automatically mute media",
"auto_unmute": "Automatically unmute media", "auto_unmute": "Automatically unmute media",
"draggable": "Event Viewer can be dragged/swiped", "draggable": "Event Viewer can be dragged/swiped",
"lazy_load": "Event Viewer media is lazily loaded in carousel", "lazy_load": "Event Viewer media is lazily loaded in carousel",
@@ -127,6 +128,7 @@
"lazy_load": "Live cameras are lazily loaded", "lazy_load": "Live cameras are lazily loaded",
"lazy_unload": "Live cameras are lazily unloaded", "lazy_unload": "Live cameras are lazily unloaded",
"auto_pause": "Automatically pause live cameras", "auto_pause": "Automatically pause live cameras",
"auto_mute": "Automatically mute live cameras",
"auto_unmute": "Automatically unmute live cameras", "auto_unmute": "Automatically unmute live cameras",
"transition_effect": "Live camera transition effect", "transition_effect": "Live camera transition effect",
"controls": { "controls": {
+2 -2
View File
@@ -63,14 +63,14 @@ customElements.whenDefined('ha-camera-stream').then(() => {
* Mute the video. * Mute the video.
*/ */
public mute(): void { public mute(): void {
this.muted = true; this._playerRef.value?.mute();
} }
/** /**
* Unmute the video. * Unmute the video.
*/ */
public unmute(): void { public unmute(): void {
this.muted = false; this._playerRef.value?.unmute();
} }
/** /**
+10 -4
View File
@@ -38,14 +38,21 @@ customElements.whenDefined('ha-hls-player').then(() => {
* Mute the video. * Mute the video.
*/ */
public mute(): void { public mute(): void {
this.muted = true; // The muted property is only for the initial muted state. Must explicitly
// set the muted on the video player to make the change dynamic.
if (this._videoRef.value) {
this._videoRef.value.muted = true;
}
} }
/** /**
* Unmute the video. * Unmute the video.
*/ */
public unmute(): void { public unmute(): void {
this.muted = false; // See note in mute().
if (this._videoRef.value) {
this._videoRef.value.muted = false;
}
} }
// ===================================================================================== // =====================================================================================
@@ -54,8 +61,7 @@ customElements.whenDefined('ha-hls-player').then(() => {
// ===================================================================================== // =====================================================================================
protected render(): TemplateResult { protected render(): TemplateResult {
if (this._error) { if (this._error) {
// Use native Frigate card error handling, and attach the entityid to // Use native Frigate card error handling.
// clarify which camera the error refers to.
return dispatchErrorMessageEvent(this, this._error); return dispatchErrorMessageEvent(this, this._error);
} }
return html` return html`
+5
View File
@@ -66,6 +66,7 @@ export type LiveProvider = typeof LIVE_PROVIDERS[number];
const MEDIA_ACTION_CONDITIONS = ['all', 'unselected', 'hidden', 'never'] as const; const MEDIA_ACTION_CONDITIONS = ['all', 'unselected', 'hidden', 'never'] as const;
export type LazyUnloadCondition = typeof MEDIA_ACTION_CONDITIONS[number]; export type LazyUnloadCondition = typeof MEDIA_ACTION_CONDITIONS[number];
export type AutoMuteCondition = typeof MEDIA_ACTION_CONDITIONS[number];
export type AutoPauseCondition = typeof MEDIA_ACTION_CONDITIONS[number]; export type AutoPauseCondition = typeof MEDIA_ACTION_CONDITIONS[number];
export class FrigateCardError extends Error {} export class FrigateCardError extends Error {}
@@ -562,6 +563,7 @@ export type TitleControlConfig = z.infer<typeof titleControlConfigSchema>;
*/ */
const liveConfigDefault = { const liveConfigDefault = {
auto_pause: 'all' as const, auto_pause: 'all' as const,
auto_mute: 'all' as const,
auto_unmute: false, auto_unmute: false,
preload: false, preload: false,
lazy_load: true, lazy_load: true,
@@ -668,6 +670,7 @@ const liveConfigSchema = liveOverridableConfigSchema
.extend({ .extend({
// Non-overrideable parameters. // Non-overrideable parameters.
auto_pause: z.enum(MEDIA_ACTION_CONDITIONS).default(liveConfigDefault.auto_pause), auto_pause: z.enum(MEDIA_ACTION_CONDITIONS).default(liveConfigDefault.auto_pause),
auto_mute: z.enum(MEDIA_ACTION_CONDITIONS).default(liveConfigDefault.auto_mute),
auto_unmute: z.boolean().default(liveConfigDefault.auto_unmute), auto_unmute: z.boolean().default(liveConfigDefault.auto_unmute),
preload: z.boolean().default(liveConfigDefault.preload), preload: z.boolean().default(liveConfigDefault.preload),
lazy_load: z.boolean().default(liveConfigDefault.lazy_load), lazy_load: z.boolean().default(liveConfigDefault.lazy_load),
@@ -755,6 +758,7 @@ export type MenuConfig = z.infer<typeof menuConfigSchema>;
const viewerConfigDefault = { const viewerConfigDefault = {
auto_pause: 'all' as const, auto_pause: 'all' as const,
auto_play: true, auto_play: true,
auto_mute: 'all' as const,
auto_unmute: false, auto_unmute: false,
lazy_load: true, lazy_load: true,
draggable: true, draggable: true,
@@ -792,6 +796,7 @@ const viewerConfigSchema = z
.object({ .object({
auto_pause: z.enum(MEDIA_ACTION_CONDITIONS).default(viewerConfigDefault.auto_pause), auto_pause: z.enum(MEDIA_ACTION_CONDITIONS).default(viewerConfigDefault.auto_pause),
auto_play: z.boolean().default(viewerConfigDefault.auto_play), auto_play: z.boolean().default(viewerConfigDefault.auto_play),
auto_mute: z.enum(MEDIA_ACTION_CONDITIONS).default(viewerConfigDefault.auto_mute),
auto_unmute: z.boolean().default(viewerConfigDefault.auto_unmute), auto_unmute: z.boolean().default(viewerConfigDefault.auto_unmute),
lazy_load: z.boolean().default(viewerConfigDefault.lazy_load), lazy_load: z.boolean().default(viewerConfigDefault.lazy_load),
draggable: z.boolean().default(viewerConfigDefault.draggable), draggable: z.boolean().default(viewerConfigDefault.draggable),