Skip to content
Sensors

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.

Devices List
Not Supported

Enumerates media devices. Grant permissions to see device labels.

Cameras
0
Microphones
0
Speakers
0
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
>
);
}
// @noErrors
import { useDevicesList } from "@usels/web";
// Automatically request permissions when the component mounts
const { devices$ } = useDevicesList({ requestPermissions: true });

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 reactively
constraints$.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.

ParameterTypeDescription
optionsUseDevicesListOptions (optional)-
OptionTypeDefaultDescription
requestPermissionsboolean-Request permissions on mount
constraintsMediaStreamConstraints-Constraints for getUserMedia when requesting permissions
onUpdated((devices: MediaDeviceInfo[]) => void)-Callback when device list is updated

UseDevicesListReturn

NameTypeDescription
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>-

View on GitHub