DEV Community

Michael Lip
Michael Lip

Posted on • Originally published at zovo.one

Browser Screen Recording Without Extensions: The MediaRecorder API

You don't need OBS, Loom, or a Chrome extension to record your screen. The browser's MediaRecorder API, combined with getDisplayMedia, provides everything needed for screen recording. And since it runs entirely in the browser, nothing is uploaded to anyone's server.

The API

async function startRecording() {
  const stream = await navigator.mediaDevices.getDisplayMedia({
    video: { mediaSource: 'screen' },
    audio: true
  });

  const recorder = new MediaRecorder(stream, {
    mimeType: 'video/webm;codecs=vp9'
  });

  const chunks = [];
  recorder.ondataavailable = e => chunks.push(e.data);
  recorder.onstop = () => {
    const blob = new Blob(chunks, { type: 'video/webm' });
    const url = URL.createObjectURL(blob);
    // Create download link
  };

  recorder.start();
}
Enter fullscreen mode Exit fullscreen mode

getDisplayMedia prompts the user to select what to share: entire screen, a specific window, or a browser tab. The selection UI is browser-provided and can't be customized or bypassed (this is a security feature).

Audio capture

Screen recording with system audio is a relatively recent addition. Before, getDisplayMedia could capture a tab's audio but not system audio. Chrome now supports system audio capture on most platforms, though the user must explicitly check the "share system audio" box in the selection dialog.

For narrated recordings, you can mix screen audio with microphone audio by combining two streams:

const screenStream = await navigator.mediaDevices.getDisplayMedia({ video: true, audio: true });
const micStream = await navigator.mediaDevices.getUserMedia({ audio: true });

const audioContext = new AudioContext();
const destination = audioContext.createMediaStreamDestination();
const screenAudio = audioContext.createMediaStreamSource(screenStream);
const micAudio = audioContext.createMediaStreamSource(micStream);
screenAudio.connect(destination);
micAudio.connect(destination);

const combinedStream = new MediaStream([
  ...screenStream.getVideoTracks(),
  ...destination.stream.getAudioTracks()
]);
Enter fullscreen mode Exit fullscreen mode

Codec and quality considerations

The MediaRecorder typically supports WebM (VP8/VP9 video, Opus audio) and sometimes MP4 (H.264 video, AAC audio). You can control quality through the videoBitsPerSecond option:

  • 1,000,000 (1 Mbps): Adequate for demos, small file size
  • 2,500,000 (2.5 Mbps): Good balance of quality and size
  • 5,000,000 (5 Mbps): High quality, larger files
  • 8,000,000+ (8 Mbps): Near-lossless for presentations

A 10-minute recording at 2.5 Mbps produces approximately a 190 MB file. At 5 Mbps, about 375 MB.

Browser limitations

The recording runs at the source's frame rate, which depends on the screen's refresh rate and the compositor's rendering speed. Complex animations might not be captured at full frame rate. For recording browser tabs, Chrome uses a more efficient capture path that typically maintains 30fps.

There's no built-in editing. The recording is one continuous file. For trimming, annotations, or cuts, you need a separate tool or a more complex implementation using Canvas-based compositing.

I built a screen recorder at zovo.one/free-tools/screen-recorder that uses these browser APIs to capture screen, tab, or window with system and microphone audio. It runs entirely locally with no server uploads. Record, preview, and download, all in the browser.

I'm Michael Lip. I build free developer tools at zovo.one. 500+ tools, all private, all free.

Top comments (0)