All hooks / Browser APIs

useUserMedia

313 B minified and brotliedSourceMarkdown✓ Works in all modern browsers

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.

off

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
ParameterDescription
constraintsgetUserMedia constraints, e.g. { video: true, audio: false }.
optionsenabled: 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

UsesChromeEdgeFirefoxSafariChrome AndroidSafari iOS
getUserMediaWidely available53+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).