From f50bef74466075766b53cf0e7b79a7baa03d2ac9 Mon Sep 17 00:00:00 2001 From: Dermot Duffy Date: Sun, 9 Nov 2025 14:43:08 -0800 Subject: [PATCH] fix: Fix audio issue triggered by HA 2025.11 (#2237) - Closes: #2235 --- src/patches/ha-camera-stream.ts | 1 + src/patches/ha-web-rtc-player.ts | 33 +++++++++++++++++++++++--------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/patches/ha-camera-stream.ts b/src/patches/ha-camera-stream.ts index 2fd4c77b..8161ca87 100644 --- a/src/patches/ha-camera-stream.ts +++ b/src/patches/ha-camera-stream.ts @@ -141,6 +141,7 @@ customElements.whenDefined('ha-camera-stream').then(() => { this._capabilities?.frontend_stream_types, this._hlsStreams, this._webRtcStreams, + this.muted, ); const visibleStream = streams.find((stream) => stream.visible) ?? null; diff --git a/src/patches/ha-web-rtc-player.ts b/src/patches/ha-web-rtc-player.ts index 8b42fdb3..29a77814 100644 --- a/src/patches/ha-web-rtc-player.ts +++ b/src/patches/ha-web-rtc-player.ts @@ -11,7 +11,6 @@ import { css, CSSResultGroup, html, TemplateResult, unsafeCSS } from 'lit'; import { customElement } from 'lit/decorators.js'; -import { query } from 'lit/decorators/query.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import { dispatchLiveErrorEvent } from '../components-lib/live/utils/dispatch-live-error.js'; import { VideoMediaPlayerController } from '../components-lib/media-player/video.js'; @@ -39,14 +38,9 @@ customElements.whenDefined('ha-web-rtc-player').then(() => { @customElement('advanced-camera-card-ha-web-rtc-player') // eslint-disable-next-line @typescript-eslint/no-unused-vars class AdvancedCameraCardHaWebRtcPlayer extends HaWebRtcPlayer implements MediaPlayer { - // Due to an obscure behavior when this card is casted, this element needs - // to use query rather than the ref directive to find the player. - @query('#remote-stream') - protected _video: HTMLVideoElement; - protected _mediaPlayerController = new VideoMediaPlayerController( this, - () => this._video, + () => this._videoEl, () => this.controls, ); @@ -72,6 +66,27 @@ customElements.whenDefined('ha-web-rtc-player').then(() => { } } + private _addTrack = async (event: RTCTrackEvent) => { + if (!this._remoteStream) { + return; + } + + // Advanced Camera Card note: The HA frontend doesn't add audio tracks if + // the player is muted. It does not currently respond to unmuting to + // re-add the audio track, or perhaps assumes that situation would not + // arise. As such, this code is kept commented out. See: + // https://github.com/dermotduffy/advanced-camera-card/issues/2235 + // if (event.track.kind === 'audio' && this.muted) { + // return; + // } + + this._remoteStream.addTrack(event.track); + if (!this.hasUpdated) { + await this.updateComplete; + } + this._videoEl.srcObject = this._remoteStream; + }; + // ===================================================================================== // Minor modifications from: // - https://github.com/home-assistant/frontend/blob/dev/src/components/ha-web-rtc-player.ts @@ -98,7 +113,7 @@ customElements.whenDefined('ha-web-rtc-player').then(() => { @loadedmetadata=${() => { if (this.controls) { hideMediaControlsTemporarily( - this._video, + this._videoEl, MEDIA_LOAD_CONTROLS_HIDE_SECONDS, ); } @@ -117,7 +132,7 @@ customElements.whenDefined('ha-web-rtc-player').then(() => { mediaPlayerController: this._mediaPlayerController, capabilities: { supportsPause: true, - hasAudio: mayHaveAudio(this._video), + hasAudio: mayHaveAudio(this._videoEl), }, technology: ['webrtc'], });