# How to Access the Device Camera Using the MediaDevices API: A Complete Guide

> Learn how to access the device camera using the MediaDevices API. This guide shows you how to get a MediaStream and display video in your web app.

- Repository: [Jisan Mia/dom-projects](https://github.com/jisan-mia/dom-projects)
- Tags: how-to-guide
- Published: 2026-03-04

---

**You can access the device camera using the MediaDevices API by calling `navigator.mediaDevices.getUserMedia({ video: true })`, which returns a Promise that resolves to a MediaStream you can attach to a `<video>` element's `srcObject` property.**

The `jisan-mia/dom-projects` repository contains a practical Camera App implementation that demonstrates this pattern with clean, production-ready code. This guide breaks down the exact implementation found in the repository, showing you how to request camera permissions, display live video streams, and capture still images without external dependencies.

## Understanding the MediaDevices API

The **MediaDevices API** is a Web API interface that provides access to connected media input devices such as cameras and microphones. The entry point is the `navigator.mediaDevices` object, which exposes the `getUserMedia()` method for requesting permission and obtaining media streams.

According to the source code in `jisan-mia/dom-projects`, the implementation relies on two core Web APIs working together:

- **MediaDevices.getUserMedia()**: Requests permission and returns a MediaStream containing video tracks
- **HTMLCanvasElement.drawImage()**: Captures individual frames from the video stream for still images

## Project Structure and File Overview

The Camera App in the `jisan-mia/dom-projects` repository follows a standard three-file structure located in `projects/camera-app/`:

| File | Purpose | Key Components |
|------|---------|----------------|
| [`projects/camera-app/index.html`](https://github.com/jisan-mia/dom-projects/blob/main/projects/camera-app/index.html) | Markup structure | `<video>` element for streaming, `<canvas>` for snapshots, capture button |
| [`projects/camera-app/camera.js`](https://github.com/jisan-mia/dom-projects/blob/main/projects/camera-app/camera.js) | Core logic | `startCamera()` and `capturePhoto()` functions |
| [`projects/camera-app/style.css`](https://github.com/jisan-mia/dom-projects/blob/main/projects/camera-app/style.css) | Visual styling | Responsive layout and UI polish |

You can view the complete source code in the [camera-app directory](https://github.com/jisan-mia/dom-projects/tree/main/projects/camera-app).

## Implementing Camera Access in JavaScript

The [`camera.js`](https://github.com/jisan-mia/dom-projects/blob/main/camera.js) file contains the essential logic for accessing the device camera using the MediaDevices API. The implementation breaks down into three distinct operations: requesting the media stream, binding it to the video element, and capturing still images.

### Requesting Camera Permission with getUserMedia

The `startCamera()` function initiates the camera access flow. It uses `navigator.mediaDevices.getUserMedia()` with a constraints object specifying video access:

```javascript
async function startCamera() {
  const video = document.getElementById('video');
  try {
    // Request webcam access – core Media Devices API call
    const stream = await navigator.mediaDevices.getUserMedia({ video: true });
    video.srcObject = stream;
  } catch (error) {
    console.error('Error accessing the camera:', error);
  }
}

```

The `{ video: true }` constraint tells the browser to request access to the default video input device. This method returns a Promise that resolves to a **MediaStream** object containing the video track.

### Binding the MediaStream to the Video Element

Once the Promise resolves, the code assigns the MediaStream to the `srcObject` property of the `<video>` element:

```javascript
video.srcObject = await navigator.mediaDevices.getUserMedia({ video: true });

```

This binding is what causes the live camera feed to display in the browser. The `autoplay` attribute on the video element (set in the HTML) ensures the stream begins playing immediately after assignment.

### Capturing Still Images with Canvas

The `capturePhoto()` function handles converting the live video frame into a static image. It uses the HTML5 Canvas API to draw the current video frame:

```javascript
function capturePhoto() {
  const video = document.getElementById('video');
  const canvas = document.getElementById('canvas');
  const ctx = canvas.getContext('2d');

  // Size canvas to current video frame dimensions
  canvas.width = video.videoWidth;
  canvas.height = video.videoHeight;

  // Draw current frame onto canvas
  ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
  canvas.style.display = 'block'; // Reveal captured image
}

```

Setting the canvas dimensions to match `video.videoWidth` and `video.videoHeight` ensures the captured image maintains the native resolution of the camera stream.

## Complete Code Implementation

Here is the complete, runnable implementation based on the `jisan-mia/dom-projects` repository:

**HTML ([`index.html`](https://github.com/jisan-mia/dom-projects/blob/main/index.html)):**

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Camera App</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="container">
    <h1>Camera App</h1>
    <video id="video" autoplay></video>
    <button id="capture">Capture Photo</button>
    <canvas id="canvas"></canvas>
  </div>
  <script src="camera.js"></script>
</body>
</html>

```

**JavaScript ([`camera.js`](https://github.com/jisan-mia/dom-projects/blob/main/camera.js)):**

```javascript
async function startCamera() {
  const video = document.getElementById('video');
  try {
    // Core MediaDevices API call to access device camera
    const stream = await navigator.mediaDevices.getUserMedia({ video: true });
    video.srcObject = stream;
  } catch (error) {
    console.error('Error accessing the camera:', error);
    alert('Unable to access camera. Please ensure you have granted permission.');
  }
}

function capturePhoto() {
  const video = document.getElementById('video');
  const canvas = document.getElementById('canvas');
  const ctx = canvas.getContext('2d');

  // Set canvas dimensions to match video stream
  canvas.width = video.videoWidth;
  canvas.height = video.videoHeight;

  // Draw current video frame to canvas
  ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
  
  // Display the captured image
  canvas.style.display = 'block';
}

// Initialize camera when page loads
window.onload = startCamera;

// Wire up capture button
document.getElementById('capture').addEventListener('click', capturePhoto);

```

## Error Handling and Browser Compatibility

The implementation in [`projects/camera-app/camera.js`](https://github.com/jisan-mia/dom-projects/blob/main/projects/camera-app/camera.js) includes basic error handling using a `try/catch` block around the `getUserMedia()` call. This catches common failure scenarios including:

- **Permission denied**: User blocks camera access through the browser dialog
- **No camera device**: Hardware not detected or currently in use by another application
- **Insecure context**: API only works on HTTPS or localhost environments

The **MediaDevices API** is supported in all modern browsers including Chrome, Firefox, Safari, and Edge. However, it requires a secure context (HTTPS or localhost) to function. Legacy browsers may require the deprecated `navigator.getUserMedia()` method with vendor prefixes, though modern applications should use the standard `navigator.mediaDevices.getUserMedia()` as implemented in the `jisan-mia/dom-projects` repository.

## Summary

- **Access the device camera** by calling `navigator.mediaDevices.getUserMedia({ video: true })`, which returns a Promise resolving to a MediaStream.
- **Bind the stream** to a `<video>` element using `video.srcObject = stream` to display the live feed.
- **Capture still images** by drawing the current video frame onto a `<canvas>` element using `ctx.drawImage()`.
- **Handle errors** with `try/catch` blocks to manage permission denials and missing hardware gracefully.
- The `jisan-mia/dom-projects` repository provides a complete working example in `projects/camera-app/` with [`camera.js`](https://github.com/jisan-mia/dom-projects/blob/main/camera.js), [`index.html`](https://github.com/jisan-mia/dom-projects/blob/main/index.html), and [`style.css`](https://github.com/jisan-mia/dom-projects/blob/main/style.css).

## Frequently Asked Questions

### What is the MediaDevices API?

The **MediaDevices API** is a Web API interface that provides access to connected media input devices such as cameras and microphones. It is accessed through the `navigator.mediaDevices` object and provides methods like `getUserMedia()` to request user permission and obtain media streams for processing or display in web applications.

### How do I handle permission denials when accessing the camera?

Wrap your `navigator.mediaDevices.getUserMedia()` call in a `try/catch` block. If the user denies permission, the Promise rejects and execution jumps to the catch block. Log the error to the console and display a user-friendly alert or message explaining that camera access is required for the application to function properly.

### Can I access the rear camera on mobile devices using this API?

Yes, you can specify which camera to use by passing constraints to `getUserMedia()`. Instead of `{ video: true }`, use `{ video: { facingMode: "environment" } }` to access the rear camera, or `{ video: { facingMode: "user" } }` for the front camera. The `jisan-mia/dom-projects` implementation uses the default camera, but you can modify the constraints object in [`camera.js`](https://github.com/jisan-mia/dom-projects/blob/main/camera.js) to target specific devices.

### Is the MediaDevices API supported in all browsers?

The **MediaDevices API** is supported in all modern browsers including Chrome, Firefox, Safari, and Edge. However, it requires a secure context (HTTPS or localhost) to function. Legacy browsers may require the deprecated `navigator.getUserMedia()` method with vendor prefixes, though modern applications should use the standard `navigator.mediaDevices.getUserMedia()` as implemented in the `jisan-mia/dom-projects` repository.