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