diff --git a/src/state/MediaDevices.ts b/src/state/MediaDevices.ts index a5b2b94f..884e1ef7 100644 --- a/src/state/MediaDevices.ts +++ b/src/state/MediaDevices.ts @@ -33,6 +33,7 @@ import { } from "../controls"; import { getUrlParams } from "../UrlParams"; import { platform } from "../Platform"; +import { switchWhen } from "../utils/observable"; // This hardcoded id is used in EX ios! It can only be changed in coordination with // the ios swift team. @@ -94,17 +95,28 @@ export const iosDeviceMenu$ = function availableRawDevices$( kind: MediaDeviceKind, - updateAvailableDeviceRequests$: Observable, + usingNames$: Observable, scope: ObservableScope, ): Observable { - return updateAvailableDeviceRequests$.pipe( - startWith(false), - switchMap((withPermissions) => - createMediaDeviceObserver( - kind, - (e) => logger.error("Error creating MediaDeviceObserver", e), - withPermissions, - ), + const logError = (e: Error): void => + logger.error("Error creating MediaDeviceObserver", e); + const devices$ = createMediaDeviceObserver(kind, logError, false); + const devicesWithNames$ = createMediaDeviceObserver(kind, logError, true); + + return usingNames$.pipe( + switchMap((withNames) => + withNames + ? // It might be that there is already a media stream running somewhere, + // and so we can do without requesting a second one. Only switch to the + // device observer that explicitly requests the names if we see that + // names are in fact missing from the initial device enumeration. + devices$.pipe( + switchWhen( + (devices, i) => i === 0 && devices.every((d) => !d.label), + devicesWithNames$, + ), + ) + : devices$, ), startWith([]), scope.state(), @@ -147,11 +159,7 @@ function selectDevice$