fix: Don't block for microphone initialization if browser does not support microphone (#1576)

This commit is contained in:
Dermot Duffy
2024-09-23 20:08:25 -07:00
committed by GitHub
parent 9c68b30ae3
commit d203f529f8
6 changed files with 213 additions and 46 deletions
@@ -52,7 +52,7 @@ export class InitializationManager {
InitializationAspect.LANGUAGES,
InitializationAspect.SIDE_LOAD_ELEMENTS,
InitializationAspect.CAMERAS,
...(config.live.microphone.always_connected
...(this._api.getMicrophoneManager().shouldConnectOnInitialization()
? [InitializationAspect.MICROPHONE_CONNECT]
: []),
InitializationAspect.VIEW,
@@ -99,7 +99,7 @@ export class InitializationManager {
// avoid issues with some cameras that only allow 2-way audio on the
// first stream initialized. See:
// https://github.com/dermotduffy/frigate-hass-card/issues/1235
...(config.live.microphone.always_connected && {
...(this._api.getMicrophoneManager().shouldConnectOnInitialization() && {
[InitializationAspect.MICROPHONE_CONNECT]: async () =>
await this._api.getMicrophoneManager().connect(),
}),
+24
View File
@@ -33,7 +33,27 @@ export class MicrophoneManager implements ReadonlyMicrophoneManager {
this._setConditionState();
}
public shouldConnectOnInitialization(): boolean {
return (
!!this._api.getConfigManager().getConfig()?.live.microphone?.always_connected &&
// If it won't be possible to connect the microphone at all, we do not
// block the initialization of the card (the microphone just won't work)
this.isSupported()
);
}
public isSupported(): boolean {
// Some browsers will have mediaDevices/getUserMedia as undefined if
// accessed over http.
// See: https://github.com/dermotduffy/frigate-hass-card/issues/1543
return !!navigator.mediaDevices?.getUserMedia;
}
public async connect(): Promise<boolean> {
if (!this.isSupported()) {
return false;
}
try {
this._stream = await navigator.mediaDevices.getUserMedia({
audio: true,
@@ -76,6 +96,10 @@ export class MicrophoneManager implements ReadonlyMicrophoneManager {
}
public async unmute(): Promise<void> {
if (!this.isSupported()) {
return;
}
const wasUnmuted = !this.isMuted();
const unmute = (): void => {
+6 -5
View File
@@ -374,11 +374,12 @@ export class MenuButtonController {
currentMediaLoadedInfo?: MediaLoadedInfo | null,
): MenuItem | null {
if (microphoneManager && currentMediaLoadedInfo?.capabilities?.supports2WayAudio) {
const forbidden = microphoneManager.isForbidden();
const unavailable =
microphoneManager.isForbidden() || !microphoneManager.isSupported();
const muted = microphoneManager.isMuted();
const buttonType = config.menu.buttons.microphone.type;
return {
icon: forbidden
icon: unavailable
? 'mdi:microphone-message-off'
: muted
? 'mdi:microphone-off'
@@ -386,8 +387,8 @@ export class MenuButtonController {
...config.menu.buttons.microphone,
type: 'custom:frigate-card-menu-icon',
title: localize('config.menu.buttons.microphone'),
style: forbidden || muted ? {} : this._getEmphasizedStyle(true),
...(!forbidden &&
style: unavailable || muted ? {} : this._getEmphasizedStyle(true),
...(!unavailable &&
buttonType === 'momentary' && {
start_tap_action: createGeneralAction(
'microphone_unmute',
@@ -396,7 +397,7 @@ export class MenuButtonController {
'microphone_mute',
) as FrigateCardCustomAction,
}),
...(!forbidden &&
...(!unavailable &&
buttonType === 'toggle' && {
tap_action: createGeneralAction(
muted ? 'microphone_unmute' : 'microphone_mute',