How to Capture Media Streams with MediaDevices API

This article explains how JavaScript captures real-time audio and video from user hardware using the MediaDevices API. You will learn how to request user permissions, configure media constraints, display live streams on a webpage, capture screen content, and properly manage hardware resources using modern web standards.

Accessing the MediaDevices Interface

The MediaDevices interface is accessed through the global navigator.mediaDevices object. It provides methods for connecting to available media input hardware like cameras, microphones, and screen-sharing utilities. Because accessing user hardware involves privacy and security, all capture methods return Promises and must be executed in a secure context (HTTPS or localhost).

Capturing Camera and Microphone Input

The primary method for accessing user cameras and microphones is navigator.mediaDevices.getUserMedia(). This method accepts a constraints object that specifies which media types to request and their desired properties.

async function startMediaCapture() {
  const constraints = {
    audio: true,
    video: {
      width: { ideal: 1280 },
      height: { ideal: 720 },
      facingMode: "user" // Use 'environment' for the back camera on mobile
    }
  };

  try {
    const stream = await navigator.mediaDevices.getUserMedia(constraints);
    const videoElement = document.querySelector('video');
    videoElement.srcObject = stream;
    videoElement.play();
  } catch (error) {
    console.error("Error accessing media devices:", error);
  }
}

When called, the browser prompts the user for permission. If accepted, the method resolves with a MediaStream object.

Displaying the MediaStream

A MediaStream consists of one or more MediaStreamTrack objects representing audio or video channels. To render the stream in real time, assign the stream directly to the srcObject property of an HTML5 <video> or <audio> element. Setting autoplay and muted attributes on the video element ensures immediate playback without triggering browser autoplay restrictions.

Capturing Screen and Display Content

To capture screen output, windows, or browser tabs, use navigator.mediaDevices.getDisplayMedia(). This method works similarly to getUserMedia but initiates the browser’s screen-sharing picker.

async function startScreenCapture() {
  try {
    const screenStream = await navigator.mediaDevices.getDisplayMedia({
      video: { cursor: "always" },
      audio: false
    });
    
    const videoElement = document.querySelector('video');
    videoElement.srcObject = screenStream;
  } catch (error) {
    console.error("Error capturing screen:", error);
  }
}

Managing and Stopping Media Tracks

Media capture remains active until explicitly stopped or until the user navigates away. To turn off the camera or microphone and release the hardware indicator light, iterate through all active tracks and invoke the stop() method:

function stopMediaStream(stream) {
  const tracks = stream.getTracks();
  tracks.forEach(track => track.stop());
}

Handling Common Errors

Always wrap calls to getUserMedia and getDisplayMedia in try...catch blocks to handle potential rejections: