diff --git a/src/room/LobbyView.tsx b/src/room/LobbyView.tsx index eab29262..8172a3ee 100644 --- a/src/room/LobbyView.tsx +++ b/src/room/LobbyView.tsx @@ -184,6 +184,16 @@ export const LobbyView: FC = ({ null) as LocalVideoTrack | null, [tracks], ); + + useEffect(() => { + if (videoTrack && videoInputId === undefined) { + // If we have a video track but no videoInputId, + // we have to update the available devices. So that we select the first + // available video input device as the default instead of the `""` id. + devices.requestDeviceNames(); + } + }, [devices, videoInputId, videoTrack]); + useTrackProcessorSync(videoTrack); const showSwitchCamera = useShowSwitchCamera( useObservable( diff --git a/src/state/MediaDevices.ts b/src/state/MediaDevices.ts index 92ac4e01..47b24939 100644 --- a/src/state/MediaDevices.ts +++ b/src/state/MediaDevices.ts @@ -355,6 +355,9 @@ export class MediaDevices { * available device, rather than numbered identifiers. This may invoke a * permissions pop-up, so it should only be called when there is a clear user * intent to view the device list. + * + * This always updates the `available$` devices for each media type with the current value + * of `enumerateDevices`. */ public requestDeviceNames(): void { void navigator.mediaDevices.enumerateDevices().then((result) => {