useDevicesList
Reactively enumerates media input/output devices via the MediaDevices API. Provides filtered lists for video inputs (cameras), audio inputs (microphones), and audio outputs (speakers). Automatically updates when devices are connected or disconnected.
Enumerates media devices. Grant permissions to see device labels.
import { const useDevicesList: (options?: DeepMaybeObservable<UseDevicesListOptions>) => UseDevicesListReturn
useDevicesList } from "@usels/web";
function function DevicesDisplay(): JSX.Element
DevicesDisplay() { const { const isSupported$: ReadonlyObservable<boolean>
isSupported$, const devices$: ReadonlyObservable<{}>
All enumerated media devices
devices$, const videoInputs$: ReadonlyObservable<{}>
Video input devices (cameras)
videoInputs$, const audioInputs$: ReadonlyObservable<{}>
Audio input devices (microphones)
audioInputs$, const audioOutputs$: ReadonlyObservable<{}>
Audio output devices (speakers)
audioOutputs$, const permissionGranted$: ReadonlyObservable<boolean>
Whether media permissions have been granted
permissionGranted$, const ensurePermissions: () => Promise<boolean>
Request media device permissions
ensurePermissions, } = function useDevicesList(options?: DeepMaybeObservable<UseDevicesListOptions>): UseDevicesListReturn
Framework-agnostic reactive wrapper around
MediaDevices.enumerateDevices().
Lists available media input/output devices and tracks changes via the
devicechange event on navigator.mediaDevices. Optionally requests
permissions on mount.
useDevicesList();
return ( <JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> <JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Supported: {const isSupported$: ReadonlyObservable<boolean>
isSupported$.ImmutableObservableBase<boolean>.get(trackingType?: TrackingType | GetOptions): {}
get() ? "Yes" : "No"}</JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> <JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Total devices: {const devices$: ReadonlyObservable<{}>
All enumerated media devices
devices$.ImmutableObservableBase<{}>.get(trackingType?: TrackingType | GetOptions): {}
get().any
length}</JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> <JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Cameras: {const videoInputs$: ReadonlyObservable<{}>
Video input devices (cameras)
videoInputs$.ImmutableObservableBase<{}>.get(trackingType?: TrackingType | GetOptions): {}
get().any
length}</JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> <JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Microphones: {const audioInputs$: ReadonlyObservable<{}>
Audio input devices (microphones)
audioInputs$.ImmutableObservableBase<{}>.get(trackingType?: TrackingType | GetOptions): {}
get().any
length}</JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> <JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Speakers: {const audioOutputs$: ReadonlyObservable<{}>
Audio output devices (speakers)
audioOutputs$.ImmutableObservableBase<{}>.get(trackingType?: TrackingType | GetOptions): {}
get().any
length}</JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> {!const permissionGranted$: ReadonlyObservable<boolean>
Whether media permissions have been granted
permissionGranted$.ImmutableObservableBase<boolean>.get(trackingType?: TrackingType | GetOptions): {}
get() && ( <JSX.IntrinsicElements.button: DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button DOMAttributes<HTMLButtonElement>.onClick?: MouseEventHandler<HTMLButtonElement> | undefined
onClick={() => const ensurePermissions: () => Promise<boolean>
Request media device permissions
ensurePermissions()}>Grant Permissions</JSX.IntrinsicElements.button: DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button> )} </JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> );}import { createDevicesList } from "@usels/web";
function DevicesDisplay() { "use scope" const { isSupported$, devices$, videoInputs$, audioInputs$, audioOutputs$, permissionGranted$, ensurePermissions, } = createDevicesList();
return ( <div> <p>Supported: {isSupported$.get() ? "Yes" : "No"}</p> <p>Total devices: {devices$.get().length}</p> <p>Cameras: {videoInputs$.get().length}</p> <p>Microphones: {audioInputs$.get().length}</p> <p>Speakers: {audioOutputs$.get().length}</p> {!permissionGranted$.get() && ( <button onClick={() => ensurePermissions()}>Grant Permissions</button> )} </div> );}Requesting Permissions on Mount
Section titled “Requesting Permissions on Mount”// @noErrorsimport { useDevicesList } from "@usels/web";
// Automatically request permissions when the component mountsconst { devices$ } = useDevicesList({ requestPermissions: true });Reactive options
Section titled “Reactive options”Options can be passed as plain values, per-field Observables, or a single Observable<UseDevicesListOptions>. Changes are picked up reactively.
import { observable } from "@usels/core";import { useDevicesList } from "@usels/web";
const constraints$ = observable<MediaStreamConstraints>({ audio: true, video: true });
const { ensurePermissions } = useDevicesList({ constraints: constraints$, onUpdated: (devices) => console.log("Updated:", devices.length),});
// Later: update constraints reactivelyconstraints$.set({ audio: true, video: false });options is DeepMaybeObservable. Each option field can be a plain value or an Observable. The onUpdated callback and constraints are read at call time, so changes take effect on the next ensurePermissions() or device change. requestPermissions is mount-time-only.
Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
options | UseDevicesListOptions (optional) | - |
UseDevicesListOptions
Section titled “UseDevicesListOptions”Returns
Section titled “Returns”UseDevicesListReturn
| Name | Type | Description |
|---|---|---|
devices$ | ReadonlyObservable<MediaDeviceInfo[]> | All enumerated media devices |
videoInputs$ | ReadonlyObservable<MediaDeviceInfo[]> | Video input devices (cameras) |
audioInputs$ | ReadonlyObservable<MediaDeviceInfo[]> | Audio input devices (microphones) |
audioOutputs$ | ReadonlyObservable<MediaDeviceInfo[]> | Audio output devices (speakers) |
permissionGranted$ | ReadonlyObservable<boolean> | Whether media permissions have been granted |
ensurePermissions | () => Promise<boolean> | Request media device permissions |
isSupported$ | ReadonlyObservable<boolean> | - |