diff --git a/frontend/src/pages/RoomPage.tsx b/frontend/src/pages/RoomPage.tsx index 14cad30..d83f808 100644 --- a/frontend/src/pages/RoomPage.tsx +++ b/frontend/src/pages/RoomPage.tsx @@ -452,8 +452,23 @@ export function RoomPage() { // dynacast: паблишер прекращает отдавать слои, на которые нет подписчиков. adaptiveStream: true, dynacast: true, - audioCaptureDefaults: { deviceId: userChoices.audioDeviceId || undefined }, - videoCaptureDefaults: { deviceId: userChoices.videoDeviceId || undefined }, + // `usePersistentUserChoices` хранит «устройство не выбрано» как литерал + // `"default"` (`@livekit/components-core`, `defaultUserChoices`), а не + // пустую строку — `|| undefined` его не отсекает, и в Chrome это давало + // `OverconstrainedError` на первом визите (см. тот же сентинел в + // `useDeviceCheckAccess.ts::openStream`). + audioCaptureDefaults: { + deviceId: + userChoices.audioDeviceId && userChoices.audioDeviceId !== 'default' + ? userChoices.audioDeviceId + : undefined, + }, + videoCaptureDefaults: { + deviceId: + userChoices.videoDeviceId && userChoices.videoDeviceId !== 'default' + ? userChoices.videoDeviceId + : undefined, + }, // Аудиовыход (колонки/наушники/bluetooth) — отдельный персист, не через // usePersistentUserChoices: LocalUserChoices LiveKit про него не знает // (см. lib/audioOutputDevice.ts). Читаем один раз при монтировании —