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
+26 -32
View File
@@ -22,11 +22,7 @@ import { isHARelativeURL } from '../../ha/is-ha-relative-url.js';
import { ResolvedMediaCache, resolveMedia } from '../../ha/resolved-media.js';
import { homeAssistantSignPath } from '../../ha/sign-path.js';
import { HomeAssistant, ResolvedMedia } from '../../ha/types.js';
import {
addDynamicProxyURL,
getWebProxiedURL,
shouldUseWebProxy,
} from '../../ha/web-proxy.js';
import { createProxiedEndpointIfNecessary } from '../../ha/web-proxy.js';
import '../../patches/ha-hls-player.js';
import viewerProviderStyle from '../../scss/viewer-provider.scss';
import { MediaPlayer, MediaPlayerController, MediaPlayerElement } from '../../types.js';
@@ -153,34 +149,32 @@ export class AdvancedCameraCardViewerProvider extends LitElement implements Medi
const camera = cameraID ? this.cameraManager?.getStore().getCamera(cameraID) : null;
const proxyConfig = camera?.getProxyConfig();
if (proxyConfig && shouldUseWebProxy(this.hass, proxyConfig, 'media')) {
if (proxyConfig.dynamic) {
// Don't use URL() parsing, since that will strip the port number if
// it's the default, just need to strip any hash part of the URL.
const urlWithoutQSorHash = unsignedURL.split(/#/)[0];
try {
await addDynamicProxyURL(this.hass, urlWithoutQSorHash, {
proxyConfig,
// The link may need to be opened multiple times.
openLimit: 0,
});
} catch (e) {
errorToConsole(e as Error);
}
}
try {
this._url = await homeAssistantSignPath(
this.hass,
getWebProxiedURL(unsignedURL),
);
} catch (e) {
errorToConsole(e as Error);
}
} else {
if (!proxyConfig) {
this._url = unsignedURL;
return;
}
try {
// Create endpoint from unsigned URL - it doesn't need signing initially
const unsignedEndpoint = { endpoint: unsignedURL, sign: false };
const proxiedEndpoint = await createProxiedEndpointIfNecessary(
this.hass,
unsignedEndpoint,
proxyConfig,
{
context: 'media',
// The link may need to be opened multiple times.
openLimit: 0,
},
);
if (proxiedEndpoint.sign) {
this._url = await homeAssistantSignPath(this.hass, proxiedEndpoint.endpoint);
} else {
this._url = proxiedEndpoint.endpoint;
}
} catch (e) {
errorToConsole(e as Error);
}
}