All hooks / Browser APIs
useUserMedia
Opens the camera and/or microphone with getUserMedia, and stops every track on unmount, when disabled, or when the constraints change, so the camera light turns off.
Enabling it makes the browser ask for permission the first time. Returns { stream: null, loading: false } on the server, during hydration, and while disabled. Constraints are compared by value, so an inline object is fine.
Import
import { useUserMedia } from '@vincent.ri/react-tils'
// or only this hook
import { useUserMedia } from '@vincent.ri/react-tils/useUserMedia'Usage
const { stream, error } = useUserMedia({ video: { facingMode: 'environment' } })
const videoRef = useCallback(
(video: HTMLVideoElement | null) => {
if (video) video.srcObject = stream
},
[stream],
)
if (error) return <p>Camera unavailable: {error.message}</p>
return <video ref={videoRef} autoPlay playsInline muted />Live demo
The camera light turns off when you stop.
When to use it
A video call preview, scanning a QR code, recording audio, or taking a profile photo.
When not to
A file input is enough (<input type="file" accept="image/*" capture> opens the camera on phones with no permission prompt). To check the permission first, use usePermission('camera').
API
function useUserMedia(constraints: MediaStreamConstraints, options?: {
enabled?: boolean;
}): UserMediaState| Parameter | Description |
|---|---|
constraints | getUserMedia constraints, e.g. { video: true, audio: false }. |
options | enabled: request while true. Default true. |
Types
export type UserMediaState = {
/** The live stream, or `null` while disabled, loading, or after an error. */
stream: MediaStream | null;
/** `NotAllowedError` (denied), `NotFoundError` (no device), etc., or an `Error` if unsupported. */
error: Error | null;
/** `true` while enabled and waiting for the stream or an error. */
loading: boolean;
};Browser support
| Uses | Chrome | Edge | Firefox | Safari | Chrome Android | Safari iOS |
|---|---|---|---|---|---|---|
| getUserMediaWidely available | 53+ | 12+ | 36+ | 11+ | 53+ | 11+ |
- Needs a secure page (HTTPS or localhost).
First version with support, from MDN's compatibility data (web-features 3.42.0, @mdn/browser-compat-data 8.1.5).