fix: Improve 2-way audio detection (#2293)

- For Frigate cameras, you must be running at least [integration
v5.12.0](https://github.com/blakeblackshear/frigate-hass-integration/releases/tag/v5.12.0).
 - Closes: #2191 

Includes a significant refactor of cameras, and the introduction of a
`2-way-audio` capability that is dynamically fetched from `go2rtc`. One
gotcha is if you previously had a substream with 2-way audio, you may
need to modify

```yaml
 - camera_entity: camera.foo
    capabilities:
      disable_except:
        - substream
```

... to ...

```yaml
 - camera_entity: camera.foo
    capabilities:
      disable_except:
        - substream
        - 2-way-audio
```
This commit is contained in:
Dermot Duffy
2025-12-20 13:06:09 -08:00
committed by GitHub
parent 588ed6c98a
commit 1e821f09c6
47 changed files with 2240 additions and 958 deletions
+4 -23
View File
@@ -16,9 +16,8 @@ import { MicrophoneState } from '../../card-controller/types.js';
import { LazyLoadController } from '../../components-lib/lazy-load-controller.js';
import { dispatchLiveErrorEvent } from '../../components-lib/live/utils/dispatch-live-error.js';
import { PartialZoomSettings } from '../../components-lib/zoom/types.js';
import { LiveProvider } from '../../config/schema/cameras.js';
import { LiveConfig } from '../../config/schema/live.js';
import { CardWideConfig, configDefaults } from '../../config/schema/types.js';
import { CardWideConfig } from '../../config/schema/types.js';
import { STREAM_TROUBLESHOOTING_URL } from '../../const.js';
import { HomeAssistant } from '../../ha/types.js';
import { localize } from '../../localize/localize.js';
@@ -29,6 +28,7 @@ import {
MediaPlayerController,
MediaPlayerElement,
} from '../../types.js';
import { getResolvedLiveProvider } from '../../utils/live-provider.js';
import { dispatchMediaUnloadedEvent } from '../../utils/media-info.js';
import '../icon.js';
import { renderMessage } from '../message.js';
@@ -101,25 +101,6 @@ export class AdvancedCameraCardLiveProvider extends LitElement implements MediaP
return (await this._refProvider.value?.getMediaPlayerController()) ?? null;
}
/**
* Get the fully resolved live provider.
* @returns A live provider (that is not 'auto').
*/
protected _getResolvedProvider(): Omit<LiveProvider, 'auto'> {
const config = this.camera?.getConfig();
if (config?.live_provider === 'auto') {
if (config?.webrtc_card?.entity || config?.webrtc_card?.url) {
return 'webrtc-card';
} else if (config?.camera_entity) {
return 'ha';
} else if (config?.frigate.camera_name) {
return 'jsmpeg';
}
return configDefaults.cameras.live_provider;
}
return config?.live_provider || 'image';
}
/**
* Determine if a camera image should be shown in lieu of the real stream
* whilst loading.
@@ -172,7 +153,7 @@ export class AdvancedCameraCardLiveProvider extends LitElement implements MediaP
}
if (changedProps.has('camera')) {
const provider = this._getResolvedProvider();
const provider = getResolvedLiveProvider(this.camera?.getConfig());
if (provider === 'jsmpeg') {
this._importPromises.push(import('./providers/jsmpeg.js'));
} else if (provider === 'ha') {
@@ -248,7 +229,7 @@ export class AdvancedCameraCardLiveProvider extends LitElement implements MediaP
this.title = this.label;
this.ariaLabel = this.label;
const provider = this._getResolvedProvider();
const provider = getResolvedLiveProvider(this.camera?.getConfig());
if (
provider === 'ha' ||