How to Build a Browser Screen Recorder with the MediaRecorder API

This guide explains how to use the native MediaRecorder API to capture screen, audio, or canvas streams in the browser, walk through a three‑step implementation—getting the stream, recording it, and handling the output—and shares best practices for compatibility, MIME types, user permissions, resource cleanup, and performance.

JavaScript
JavaScript
JavaScript
How to Build a Browser Screen Recorder with the MediaRecorder API

In the past, implementing screen‑recording on a web page required complex browser plugins, desktop applications, or paid third‑party services, increasing both user friction and developer effort. Today, the powerful native MediaRecorder API provides a streamlined solution.

What is the MediaRecorder API?

MediaRecorder, part of the WebRTC stack, receives a MediaStream and encodes it into formats such as WebM or MP4, outputting the data as Blob chunks.

Media streams can originate from many sources, including:

User camera and microphone ( navigator.mediaDevices.getUserMedia)

User screen, window, or tab ( navigator.mediaDevices.getDisplayMedia)

HTML <video> or <audio> elements

Dynamically generated Canvas elements

The screen‑recording feature specifically leverages the second source— getDisplayMedia API.

Build a basic screen‑recording feature in three steps

The core workflow is: Get stream → Record stream → Process result .

Step 1: Obtain a screen‑sharing MediaStream

Prompt the user for permission and request the screen, window, or tab stream using getDisplayMedia. This call must be triggered by a user interaction.

async function getScreenStream() {
  try {
    // Prompt user to select screen or window
    const stream = await navigator.mediaDevices.getDisplayMedia({
      video: true, // capture video
      audio: true  // optionally capture audio
    });
    return stream;
  } catch (error) {
    console.error("Failed to get screen sharing:", error);
    alert("You cancelled screen sharing or an error occurred.");
    return null;
  }
}

Note: getDisplayMedia must be called from a user‑initiated action (e.g., button click), otherwise browsers will block it for security reasons.

Step 2: Create a MediaRecorder instance and start recording

After acquiring the MediaStream, instantiate a MediaRecorder to begin capturing.

Step 3: Stop recording and handle the result

When the user stops sharing or clicks a stop button, call mediaRecorder.stop(). Recorded chunks accumulate in the recordedChunks array; combine them into a single Blob to produce the final video file.

// Stop recording function
function stopRecording() {
  if (mediaRecorder && mediaRecorder.state !== 'inactive') {
    mediaRecorder.stop();
  }
}

// Process recorded data
function handleRecordingStop() {
  // Merge all chunks into a Blob
  const recordedBlob = new Blob(recordedChunks, { type: 'video/webm' });
  const videoUrl = URL.createObjectURL(recordedBlob);

  // Create a download link
  const downloadLink = document.createElement('a');
  downloadLink.href = videoUrl;
  downloadLink.download = `recording-${new Date().toISOString()}.webm`;
  downloadLink.textContent = 'Download recording';
  document.body.appendChild(downloadLink);

  // Or create a video element for preview
  const previewVideo = document.createElement('video');
  previewVideo.src = videoUrl;
  previewVideo.controls = true;
  document.body.appendChild(previewVideo);

  // Clean up for next recording
  recordedChunks = [];
}

Integrating these steps with UI buttons (Start, Stop) yields a complete web‑based screen‑recording application.

The MediaRecorder API can also be used for user feedback and bug reproduction, online education, live demos, and more.

Considerations and best practices

Browser compatibility: MediaRecorder is widely supported in modern browsers (Chrome, Firefox, Edge, Safari), but always verify support and provide graceful fallbacks for unsupported environments.

MIME types: Different browsers support different mimeType s. Use MediaRecorder.isTypeSupported() to check availability; video/webm offers the broadest compatibility.

User authorization: Invoke getDisplayMedia only after explicit user interaction and clearly explain why the permission is needed.

Resource management: After recording, call URL.revokeObjectURL() to free the created URL and stop all tracks with stream.getTracks().forEach(track => track.stop()) to turn off camera or screen‑sharing indicators.

Performance considerations: Long or high‑resolution recordings consume significant memory and CPU. For upload scenarios, consider chunked uploading instead of waiting for the entire file.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaScriptBrowserWeb APIScreen RecordingMediaRecorder
JavaScript
Written by

JavaScript

Provides JavaScript enthusiasts with tutorials and experience sharing on web front‑end technologies, including JavaScript, Node.js, Deno, Vue.js, React, Angular, HTML5, CSS3, and more.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.