diff --git a/src/state/MediaDevices.ts b/src/state/MediaDevices.ts index cea97519..613aa3f4 100644 --- a/src/state/MediaDevices.ts +++ b/src/state/MediaDevices.ts @@ -15,6 +15,7 @@ import { Subject, switchMap, type Observable, + tap, } from "rxjs"; import { createMediaDeviceObserver } from "@livekit/components-core"; import { type Logger, logger as rootLogger } from "matrix-js-sdk/lib/logger"; @@ -34,6 +35,7 @@ import { getUrlParams } from "../UrlParams"; import { platform } from "../Platform"; import { switchWhen } from "../utils/observable"; import { type Behavior, constant } from "./Behavior"; +// import { RTCCallIntent } from "matrix-js-sdk/lib/matrixrtc"; // This hardcoded id is used in EX ios! It can only be changed in coordination with // the ios swift team. @@ -49,10 +51,18 @@ export type AudioOutputDeviceLabel = | { type: "earpiece" } | { type: "default"; name: string | null }; +/** + * Base selected-device value shared by all media kinds. + * + * `id` is the effective device identifier used by browser media APIs. + */ export interface SelectedDevice { id: string; } +/** + * Selected audio input value with audio-input-specific metadata. + */ export interface SelectedAudioInputDevice extends SelectedDevice { /** * Emits whenever we think that this audio input device has logically changed @@ -61,6 +71,9 @@ export interface SelectedAudioInputDevice extends SelectedDevice { hardwareDeviceChange$: Observable; } +/** + * Selected audio output value with output-routing-specific metadata. + */ export interface SelectedAudioOutputDevice extends SelectedDevice { /** * Whether this device is a "virtual earpiece" device. If so, we should output @@ -69,23 +82,42 @@ export interface SelectedAudioOutputDevice extends SelectedDevice { virtualEarpiece: boolean; } +/** + * Common reactive contract for selectable input/output media devices (mic, speaker, camera). + * + * `Label` is the type used to represent a device in UI lists. + * `Selected` is the type used to represent the active selection for a device kind. + */ export interface MediaDevice { /** - * A map from available device IDs to labels. + * Reactive map of currently available devices keyed by device ID. + * + * `Label` defines the UI-facing label data structure for each device type. */ available$: Behavior>; + /** - * The selected device. + * The active device selection. + * Can be `undefined` when no device is yet selected. + * + * When defined, `Selected` contains the selected device ID plus any + * type-specific metadata. */ selected$: Behavior; + /** - * Selects a new device. + * Requests selection of a device by ID. + * + * Implementations typically persist this preference and let `selected$` + * converge to the effective device (which may differ if the requested ID is + * unavailable). */ select(id: string): void; } /** * An observable that represents if we should display the devices menu for iOS. + * * This implies the following * - hide any input devices (they do not work anyhow on ios) * - Show a button to show the native output picker instead. @@ -143,19 +175,29 @@ function buildDeviceMap( function selectDevice$