Webcam API
Browser Permissions
Front-end Development
WebRTC
User Privacy

Camera access through browser

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Modern browsers allow web applications to access the camera through navigator.mediaDevices.getUserMedia. The API is powerful, but it is guarded by permission rules, secure-context requirements, and device-compatibility differences. A correct implementation is not just "turn on the camera". It also has to handle denial, cleanup, and user expectations around privacy.

Request Camera Access with getUserMedia

The usual starting point is a video element plus a media request:

html
1<video id="preview" autoplay playsinline></video>
2<script>
3async function startCamera() {
4  const stream = await navigator.mediaDevices.getUserMedia({
5    video: true,
6    audio: false
7  });
8
9  document.getElementById("preview").srcObject = stream;
10}
11
12startCamera().catch(console.error);
13</script>

If the user grants permission, the returned MediaStream can be attached directly to a video element.

Secure Context Is Required

In normal browser environments, camera access works only on secure origins such as HTTPS or localhost during development. If you test on an insecure origin, the browser may refuse the call before permission is even shown.

That means camera features should be planned as secure-by-default web features, not as something you "turn on later".

Handle Permission Denial and Device Absence

Users can deny access, devices can be busy, and some systems may not have a usable camera at all. Good code handles those cases cleanly.

javascript
1async function startCamera() {
2  try {
3    const stream = await navigator.mediaDevices.getUserMedia({ video: true });
4    preview.srcObject = stream;
5  } catch (err) {
6    if (err.name === "NotAllowedError") {
7      console.log("camera permission denied");
8    } else {
9      console.log("camera unavailable:", err.name);
10    }
11  }
12}

That is much better than a silent failure or a generic message.

It is also good UX to connect the message to a next step, such as "check browser site permissions" or "make sure no other application is using the camera". Users often need guidance more than they need the raw error name.

That small product detail matters because camera access failures often look like the site is broken, even when the browser is correctly enforcing user choice or hardware availability.

Clear status text next to the preview area is often enough to make the behavior understandable.

Stop the Camera When You Are Done

The browser does not necessarily stop the camera just because the preview element disappears. Stop the tracks explicitly.

javascript
1function stopCamera(videoEl) {
2  const stream = videoEl.srcObject;
3  if (!stream) return;
4
5  stream.getTracks().forEach(track => track.stop());
6  videoEl.srcObject = null;
7}

This matters for privacy, battery usage, and avoiding camera-lock conflicts with other applications.

On mobile browsers this cleanup matters even more, because camera use can interfere with battery life, tab switching, and other applications trying to claim the same hardware.

Use Constraints Carefully

You can ask for front or rear cameras, preferred resolutions, and more, but constraints are requests rather than guarantees.

javascript
1const stream = await navigator.mediaDevices.getUserMedia({
2  video: {
3    facingMode: "environment",
4    width: { ideal: 1280 },
5    height: { ideal: 720 }
6  }
7});

Different browsers and devices support different levels of constraint control, so always test the fallback behavior.

Common Pitfalls

  • Trying to access the camera from a non-HTTPS origin.
  • Forgetting to handle permission denial or missing-device errors.
  • Leaving media tracks running after the UI no longer needs them.
  • Assuming requested constraints are always satisfied exactly.
  • Building the feature without considering user privacy expectations and visible feedback.

Summary

  • Browser camera access usually goes through getUserMedia.
  • The page must run in a secure context such as HTTPS or localhost.
  • Good implementations handle permission denial and device errors explicitly.
  • Stop tracks when the camera is no longer needed.
  • Constraints help guide camera selection, but they do not guarantee identical behavior on every device.

Course illustration
Course illustration

All Rights Reserved.