Skip to main content

useMediaDevices

Overview

The useMediaDevices hook simplifies access to media input devices like microphones and cameras, managing permissions and providing a way to retrieve available devices based on the specified types.

Importing

To use the useMediaDevices hook, import it:

import { useMediaDevices } from './path/to/useMediaDevices'

Hook Signature

useMediaDevices(
...xs: MediaDeviceKind[]
): [() => Promise<DeviceOptions | undefined>]

Parameters

  • ...xs: A list of media device kinds to check for. Valid values:
    • 'microphone': To check for audio input devices.
    • 'camera': To check for video input devices.

Returns

An array with a single function:

  1. A callback function that, when called, checks permissions and retrieves available devices for the specified media kinds.

Supporting Types

MediaDeviceKind

type MediaDeviceKind = 'microphone' | 'camera';

Represents the types of media devices that can be checked.

MediaDeviceInfoMediaDeviceSelection

type MediaDeviceInfoMediaDeviceSelection = {
deviceId: string;
label: string;
device: MediaDeviceInfo;
};

Describes a media device, including its deviceId, label, and raw MediaDeviceInfo object.

DeviceOptions

type DeviceOptions = {
audio: MediaDeviceInfoMediaDeviceSelection[];
video: MediaDeviceInfoMediaDeviceSelection[];
};

Represents the available media devices separated into audio and video categories.


How It Works

  1. Permissions Check:
    • Uses the navigator.permissions.query API to check for microphone and camera permissions.
  2. Media Stream:
    • Temporarily acquires a media stream using navigator.mediaDevices.getUserMedia to ensure devices are available.
  3. Device Enumeration:
    • Retrieves a list of available media devices with navigator.mediaDevices.enumerateDevices.
  4. Cleanup:
    • Stops media tracks to avoid resource locking.

Example Usage

Basic Example

import React from 'react';
import { useMediaDevices } from './path/to/useMediaDevices';

const MediaDeviceComponent: React.FC = () => {
const [getDevices] = useMediaDevices('microphone', 'camera');
const [devices, setDevices] = React.useState<DeviceOptions | undefined>(undefined);

const fetchDevices = async () => {
const result = await getDevices();
setDevices(result);
};

return (
<div>
<h1>Media Devices</h1>
<button onClick={fetchDevices}>Get Devices</button>
{devices && (
<div>
<h2>Audio Devices</h2>
<ul>
{devices.audio.map((device) => (
<li key={device.deviceId}>{device.label || 'Unnamed Audio Device'}</li>
))}
</ul>
<h2>Video Devices</h2>
<ul>
{devices.video.map((device) => (
<li key={device.deviceId}>{device.label || 'Unnamed Video Device'}</li>
))}
</ul>
</div>
)}
</div>
);
};

export default MediaDeviceComponent;

Explanation

  1. Media Device Check: The getDevices function is called to retrieve audio and video devices.
  2. State Update: The results are stored in devices and displayed in lists for audio and video devices.
  3. Dynamic Rendering: The UI updates based on the availability of media devices.

Best Practices

  • Handle Permissions Gracefully: Check for denied permissions and inform users if access is not granted.
  • Device Refresh: Provide a way to refresh the list of devices as they may change dynamically (e.g., USB device plugged in).
  • Error Handling: Use try-catch to manage potential errors when accessing media devices.

Notes

  • The checkPermissions helper function is used internally to validate permissions and gather devices.
  • Media tracks are stopped after use to prevent resource locking.

Contributing

If you encounter issues or have suggestions for improving the useMediaDevices hook, feel free to contribute or report an issue on the repository.