From 4e576afebd40842145d765c25322767917c067ed Mon Sep 17 00:00:00 2001 From: Ovgodd Date: Thu, 1 Oct 2026 10:16:35 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B(frontend)=20omit=20the=20default?= =?UTF-8?q?=20speaker=20id=20sent=20to=20LiveKit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Firefox rejects setSinkId('default') when a remote audio track is attached. Omit that id and only send a real device id. --- CHANGELOG.md | 1 + .../src/features/analytics/exceptionFilters.ts | 4 ++++ .../src/features/rooms/components/Conference.tsx | 3 ++- .../rooms/utils/resolveAudioOutputDeviceId.ts | 11 +++++++++++ 4 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 src/frontend/src/features/rooms/utils/resolveAudioOutputDeviceId.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index bfd008d74..742bd0e2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to ### Fixed +- 🐛(frontend) omit the default speaker id sent to LiveKit - 🐛(frontend) enforce recording-mode permissions on the checkboxes - 🔒️(agents) fix util-linux CVEs reported by Cyberwatch diff --git a/src/frontend/src/features/analytics/exceptionFilters.ts b/src/frontend/src/features/analytics/exceptionFilters.ts index aa97d5025..f8936d2fa 100644 --- a/src/frontend/src/features/analytics/exceptionFilters.ts +++ b/src/frontend/src/features/analytics/exceptionFilters.ts @@ -8,6 +8,10 @@ const IGNORED_EXCEPTION_PATTERNS = [ // the close reason is already logged by the SDK. // See: https://github.com/livekit/client-sdk-js/issues/2062 /^Event captured as exception with keys: isTrusted$/, + // LiveKit logs a rejected setSinkId on remote audio attach and already + // swallows it. capture_console_errors turns that log into an exception + // and stringifies the real error as [object Object]. + /^Failed to set sink id on remote audio track/, ] const shouldIgnoreException = (value: unknown): boolean => diff --git a/src/frontend/src/features/rooms/components/Conference.tsx b/src/frontend/src/features/rooms/components/Conference.tsx index 2877015e1..6901adf9d 100644 --- a/src/frontend/src/features/rooms/components/Conference.tsx +++ b/src/frontend/src/features/rooms/components/Conference.tsx @@ -45,6 +45,7 @@ import { userStore } from '@/stores/user' import { WatchMediaDeviceErrors } from './WatchMediaDeviceErrors' import { MeetDevtools } from '@/features/devtools' import { VOICE_AUDIO_CONSTRAINTS } from '@/features/rooms/livekit/utils/constants' +import { resolveAudioOutputDeviceId } from '@/features/rooms/utils/resolveAudioOutputDeviceId' export const Conference = ({ roomId, @@ -120,7 +121,7 @@ export const Conference = ({ ...VOICE_AUDIO_CONSTRAINTS, }, audioOutput: { - deviceId: userConfig.audioOutputDeviceId ?? undefined, + deviceId: resolveAudioOutputDeviceId(userConfig.audioOutputDeviceId), }, } // do not rely on the userConfig object directly as its reference may change on every render diff --git a/src/frontend/src/features/rooms/utils/resolveAudioOutputDeviceId.ts b/src/frontend/src/features/rooms/utils/resolveAudioOutputDeviceId.ts new file mode 100644 index 000000000..b417efdee --- /dev/null +++ b/src/frontend/src/features/rooms/utils/resolveAudioOutputDeviceId.ts @@ -0,0 +1,11 @@ +/** + * `'default'` means "use the system output". Firefox has no device with that + * id, so LiveKit's setSinkId('default') rejects on every remote audio attach. + * Omit it and the browser keeps the OS default, which is the same result. + */ +export const resolveAudioOutputDeviceId = ( + deviceId: string | undefined +): string | undefined => { + if (!deviceId || deviceId === 'default') return undefined + return deviceId +}