diff --git a/src/frontend/src/features/rooms/components/Join.tsx b/src/frontend/src/features/rooms/components/Join.tsx index 6bc5e111..b97d3e0e 100644 --- a/src/frontend/src/features/rooms/components/Join.tsx +++ b/src/frontend/src/features/rooms/components/Join.tsx @@ -30,6 +30,7 @@ import { useSnapshot } from 'valtio' import { openPermissionsDialog, permissionsStore } from '@/stores/permissions' import { ToggleDevice } from './join/ToggleDevice' import { SelectDevice } from './join/SelectDevice' +import { useResolveDefaultDeviceId } from '../livekit/hooks/useResolveDefaultDevice' const onError = (e: Error) => console.error('ERROR', e) @@ -140,6 +141,11 @@ export const Join = ({ [tracks] ) + // LiveKit by default populates device choices with "default" value. + // Instead, use the current device id used by the preview track as a default + useResolveDefaultDeviceId(audioDeviceId, audioTrack, saveAudioInputDeviceId) + useResolveDefaultDeviceId(videoDeviceId, videoTrack, saveVideoInputDeviceId) + const videoEl = useRef(null) const isVideoInitiated = useRef(false) diff --git a/src/frontend/src/features/rooms/livekit/hooks/useResolveDefaultDevice.ts b/src/frontend/src/features/rooms/livekit/hooks/useResolveDefaultDevice.ts new file mode 100644 index 00000000..673b65fc --- /dev/null +++ b/src/frontend/src/features/rooms/livekit/hooks/useResolveDefaultDevice.ts @@ -0,0 +1,18 @@ +import { useEffect } from 'react' + +export const useResolveDefaultDeviceId = < + T extends { getDeviceId(): Promise }, +>( + currentId: string, + track: T | undefined, + save: (id: string) => void +) => { + useEffect(() => { + if (currentId !== 'default' || !track) return + const resolveDefaultDeviceId = async () => { + const actualDeviceId = await track.getDeviceId() + if (actualDeviceId && actualDeviceId !== 'default') save(actualDeviceId) + } + resolveDefaultDeviceId() + }, [currentId, track, save]) +}