JavaScript Navigator getUserMedia() Method

Beginner
5 min read
Updated: Nov 2026
5 examples
Method

Definition

navigator.getUserMedia(constraints, success, error) is the legacy callback way to ask for a camera and/or microphone MediaStream (MDN). New code should use navigator.mediaDevices.getUserMedia() instead.

Pass the required arguments shown below. Check return values and browser support before you rely on the result.

Syntax

Call navigator.getUserMedia. Start with this line.

JavaScript
navigator.getUserMedia(constraints, onSuccess, onError)
CallWhat it does
navigator.getUserMedia(constraints, onSuccess, onError)Primary signature.
navigator.getUserMedia(...)Call with the arguments your case needs.

Built into the browser. Call getUserMedia(...) on a Navigator — no import required.

Library declarations
JavaScript
navigator.getUserMedia(constraints, onSuccess, onError)

Parameters

ParameterDescription
constraintsRequired. Which media (audio / video / sizes)
ContextRequired. Secure (HTTPS / localhost)

Return Value

Return ValueDescription
*The value returned by navigator.getUserMedia().

JavaScript Examples

Example 1 — Feature Detection

Compare legacy navigator.getUserMedia with modern mediaDevices.

JavaScript
const lines = [
  "navigator.getUserMedia: " +
    (typeof navigator.getUserMedia === "function" ? "available" : "missing"),
  "mediaDevices.getUserMedia: " +
    (navigator.mediaDevices &&
    typeof navigator.mediaDevices.getUserMedia === "function"
      ? "available"
      : "missing"),
  "isSecureContext: " + window.isSecureContext
];
console.log(lines.join("\n"));
Try It Yourself

How It Works

  1. Check the legacy method. Often missing in current browsers.
  2. Check mediaDevices.getUserMedia. This is what new apps should use.
  3. Confirm HTTPS. Insecure pages usually cannot open the camera.
  4. Branch on modern first. Only fall back to legacy if you must support very old code paths.

Example 2 — Legacy Callbacks (MDN)

Deprecated prefix + callback pattern for reading old tutorials.

JavaScript
navigator.getUserMedia =
  navigator.getUserMedia ||
  navigator.webkitGetUserMedia ||
  navigator.mozGetUserMedia;

if (navigator.getUserMedia) {
  navigator.getUserMedia(
    { audio: false, video: true },
    (stream) => {
      const video = document.querySelector("video");
      video.srcObject = stream;
      console.log("legacy success: tracks=" + stream.getTracks().length);
    },
    (err) => {
      console.error("legacy error: " + err.name);
    }
  );
} else {
  console.log("legacy getUserMedia not supported");
}
Try It Yourself

How It Works

  1. Normalize prefixes. Old WebKit / Gecko names still appear in textbooks.
  2. Pass three arguments. Constraints, success, and error — no Promise.
  3. Assign srcObject. Same preview step as the modern API.
  4. Do not ship this. Prefer mediaDevices.getUserMedia for new work.

Example 3 — Modern Promise API

Recommended path: await navigator.mediaDevices.getUserMedia().

JavaScript
async function startCamera() {
  if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
    return "mediaDevices.getUserMedia not supported";
  }
  try {
    const stream = await navigator.mediaDevices.getUserMedia({
      audio: false,
      video: true
    });
    const video = document.querySelector("video");
    video.srcObject = stream;
    await video.play();
    return "modern success: tracks=" + stream.getTracks().length;
  } catch (err) {
    return "Error: " + err.name;
  }
}

startCamera().then(console.log);
Try It Yourself

How It Works

  1. Feature-detect mediaDevices. Missing on insecure pages.
  2. Await the Promise. Resolves to a MediaStream.
  3. Attach and play. Use srcObject, not the old URL.createObjectURL pattern.
  4. Catch by err.name. Clear messages for Allow / Block / no device.

Example 4 — Video Constraints

Ask for a preferred size and read the actual track settings.

JavaScript
async function startHdPreview() {
  if (!navigator.mediaDevices?.getUserMedia) return "API missing";
  const stream = await navigator.mediaDevices.getUserMedia({
    audio: false,
    video: { width: 1280, height: 720 }
  });
  document.querySelector("video").srcObject = stream;
  const settings = stream.getVideoTracks()[0]?.getSettings() || {};
  return JSON.stringify({
    width: settings.width || null,
    height: settings.height || null,
    tracks: stream.getTracks().length
  });
}

startHdPreview().then(console.log).catch((err) => console.log("Error: " + err.name));
Try It Yourself

How It Works

  1. Pass ideal sizes. Plain numbers are treated as preferred / ideal.
  2. Browser negotiates. Hardware may return a nearby resolution.
  3. Read getSettings(). See what you actually got.
  4. Use exact / min carefully. Too strict → OverconstrainedError.

Example 5 — Stop Tracks (Always)

Release the camera/mic when you are done — privacy and battery friendly.

JavaScript
async function captureThenStop() {
  if (!navigator.mediaDevices?.getUserMedia) {
    return { ok: false, reason: "unsupported", tracks: 0 };
  }
  try {
    const stream = await navigator.mediaDevices.getUserMedia({
      video: true,
      audio: false
    });
    const tracks = stream.getTracks().length;
    stream.getTracks().forEach((track) => track.stop());
    return { ok: true, reason: "stopped", tracks: tracks };
  } catch (err) {
    return { ok: false, reason: err.name, tracks: 0 };
  }
}

captureThenStop().then((r) =>
  console.log(JSON.stringify(r))
);
Try It Yourself

How It Works

  1. Open the stream briefly. Same modern API as example 3.
  2. Count tracks. Useful for logging / tests.
  3. Call track.stop(). Turns off the camera light and releases hardware.
  4. Also stop on leave. Clear srcObject when navigating away or closing a modal.

Browser Support

navigator.getUserMedia() is the Deprecated callback API. The modern replacement navigator.mediaDevices.getUserMedia() is Baseline Widely available (since Sept 2017) and requires a secure context. Prefer mediaDevices for all new JavaScript. Legacy prefixed names (webkitGetUserMedia / mozGetUserMedia) appear only in old code.

✓ Deprecated legacy · Modern Baseline

Navigator.getUserMedia()

Legacy callbacks for camera/mic — migrate to mediaDevices.getUserMedia().

95% Modern mediaDevices support
Google Chrome mediaDevices · Baseline; legacy deprecated
Supported
Microsoft Edge mediaDevices · Baseline; legacy deprecated
Supported
Apple Safari mediaDevices · Baseline; legacy deprecated
Supported
Opera mediaDevices · Baseline; legacy deprecated
Supported
Mozilla Firefox mediaDevices · Baseline; legacy deprecated
Supported
Internet Explorer No standard mediaDevices.getUserMedia
Unavailable
mediaDevices.getUserMedia() Excellent

Bottom line: Teach the deprecated API for reading legacy code; ship mediaDevices.getUserMedia with HTTPS, permission UX, and track.stop().

Frequently Asked Questions

It is the old callback API that asks for permission to use the camera and/or microphone and delivers a MediaStream to a success callback, or an error object to an error callback.
No. MDN marks it Deprecated. Use navigator.mediaDevices.getUserMedia(), which returns a Promise and is the supported modern API.
navigator.mediaDevices.getUserMedia(constraints). Await the Promise, assign stream to video.srcObject, and stop tracks when finished.
Yes. getUserMedia is available only in secure contexts (HTTPS or localhost). In insecure pages, mediaDevices is often undefined.
An object describing which media you want, such as { audio: true, video: true } or more detailed video size settings like { video: { width: 1280, height: 720 } }.
Neither callback (legacy) nor the Promise (modern) may settle until the user chooses Allow or Block. Design UI that waits and offers a clear retry.

Next: getVRDisplays()

Learn the legacy WebVR display enumeration API on Navigator.

getVRDisplays() →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

9 people found this page helpful