โ† Back to list

๐ŸŽฅ Stream and Store Screen Recordings in WebM Chunks Using MediaRecorder API + RecordRTC

Recording screen activity from the browser and streaming it in chunks can be trickyโ€Šโ€”โ€Šespecially if your goal is to process each chunkโ€ฆ

Mudit Tiwari in JavaScript in Plain English ยท 2025-07-04 07:24 ยท 1 claps ยท 2.2 min read
#javascript #webm #streaming
Open on Medium โ†—
Wiki topics: GEN ยท Genomics & Sequencing ๐ŸŒ ยท Web Development ๐ŸŽฌ ยท Film & Television

๐ŸŽฅ Stream and Store Screen Recordings in WebM Chunks Using MediaRecorder API + RecordRTC

Recording screen activity from the browser and streaming it in chunks can be tricky โ€” especially if your goal is to process each chunk independently (like extracting audio or processing metadata). While the MediaRecorder API makes recording possible, the chunks it generates (after the first one) often lack essential metadata headers. This causes issues when you try to process or extract audio from those chunks using tools like FFmpeg.

Recently, I faced this challenge and solved it by combining the MediaRecorder API with RecordRTC, ensuring every chunk remains self-contained and independently processable.

Hereโ€™s a breakdown of how I tackled the problem:

๐Ÿ”น Step 1: Get the Screen Stream

First, use the MediaDevices API to prompt the user for screen access. We reuse the same stream for all chunks to avoid re-prompting the user every time.

let screenStream = null;

async function getScreenStream() {
  if (!screenStream) {
    screenStream = await navigator.mediaDevices.getDisplayMedia({
      video: true,
      audio: true,
    });
    console.log("Screen stream initialized.");
  }
  return screenStream;
}

๐Ÿ”น Step 2: Record the Stream in Chunks

The core of the solution is using RecordRTCPromisesHandler from RecordRTC. By specifying a timeSlice, it creates consistent, self-contained chunks every few seconds.

let isRecording = false;

async function startScreenRecording() {
  console.log("Starting screen recording...");
  let recordedChunks = [];

  try {
    if (isRecording) return;
    isRecording = true;

    const stream = await getScreenStream();
    const recorder = new RecordRTCPromisesHandler(stream, {
      type: "video",
      mimeType: "video/webm",
      timeSlice: 20000, // Record in 20s chunks
    });

    await recorder.startRecording();

    setTimeout(async () => {
      await recorder.stopRecording();
      isRecording = false;

      const blob = await recorder.getBlob();
      console.log("Recording stopped, sending file...");

      if (!blob || !(blob instanceof Blob)) {
        console.error("Error: Invalid Blob received.");
        return;
      }

      await sendChunksToServer(blob);
      startScreenRecording(); // Loop to keep recording continuously
    }, 20000);
  } catch (err) {
    console.error("Error accessing media devices:", err);
  }
}

๐Ÿ”น Step 3: Upload Each Chunk to Your Server

Each chunk is uploaded right after itโ€™s recorded using a simple fetch request and FormData.

async function sendChunksToServer(blob) {
  try {
    const formData = new FormData();
    formData.append("video_chunk", blob, "chunk.webm");

    const response = await fetch("https://yourserver.com/upload", {
      method: "POST",
      body: formData,
    });

    if (!response.ok) throw new Error("Failed to upload chunk");
    console.log("Chunk uploaded successfully.");
  } catch (error) {
    console.error("Error uploading chunk:", error);
  }
}

๐Ÿ“Œ Why This Works

  • โœ… The stream is initialized once and reused across chunks.
  • โœ… RecordRTC ensures that each chunk includes necessary metadata.
  • โœ… The recording loop runs continuously without user interruption.
  • โœ… Each chunk is independently processable โ€” no more EBML header parsing failed errors in FFmpeg.

๐Ÿง  Bonus Tips

  • Want to extract audio from each chunk using FFmpeg? You can now directly do:
ffmpeg -i chunk.webm -vn -acodec libmp3lame output.mp3
  • To stop the recording loop gracefully, keep a shouldRecord flag.
  • You can extend this flow to stream to cloud storage or convert chunks on the server.

If youโ€™re building a screen recording app or browser-based streaming tool, this approach gives you smooth chunked recording with real-time upload and easy processing โ€” without dealing with metadata headaches.

If you found this helpful, please give it a ๐Ÿ‘ and share it with others who might benefit!

Thank you for being a part of the community

Before you go:


๋ฉ”ํƒ€๋ฐ์ดํ„ฐ
post_id
4e2dc188f23b
slug
stream-and-store-screen-recordings-in-webm-chunks-using-mediarecorder-api-recordrtc-4e2dc188f23b
url
https://javascript.plainenglish.io/stream-and-store-screen-recordings-in-webm-chunks-using-mediarecorder-api-recordrtc-4e2dc188f23b
canonical_url
https://javascript.plainenglish.io/stream-and-store-screen-recordings-in-webm-chunks-using-mediarecorder-api-recordrtc-4e2dc188f23b
author_url
https://medium.com/@mudit.alwar31
status
ok
fetched_at
2026-06-25 12:15:08