Learn more about Russian war crimes in Ukraine.

MediaRecorder hello world

The MediaStream Recording API lets you convert a MediaStream to a Blob containing compressed video and audio. Here’s a hello world. Click the button, and this page will record a 5-second clip from your camera and microphone, then present it back for you to replay.

You first need a MediaStream, which you can get from many places, but here’s one method:

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

Next, you instantiate a MediaRecorder with the stream:

const recorder = new MediaRecorder(stream);

There are various options for how to encode the video, but we’ll leave it at the defaults.

The MediaRecorder provides data in a dataavailable event which contains a Blob. This event can happen many times. Each event contains a chunk of the recording since the previous event. The frequency of the dataavailable event depends on on how we configure the MediaRecorder. We can configure it to only provide a chunk once, but in general there are many chunks, so let’s assume that, and keep an array of all the chunks:

const chunks = [];
recorder.ondataavailable = e => chunks.push(e.data);

Once all the chunks have been provided, we get a stop event. Here, we concatenate our chunks into one video Blob, then set it as the source of a <video> element:

recorder.onstop = e => {
  const totalBlob = new Blob(chunks, { type: chunks[0].type });
  const url = URL.createObjectURL(totalBlob);
  const playbackVideoEl = document.createElement("video");
  playbackVideoEl.controls = true;
  playbackVideoEl.src = url;

Nothing will happen yet! We need to start the recorder:


Still nothing will happen! We’re accumulating chunks, but at some point we need to tell the MediaRecorder stop, at which point it will generate any remaining chunks, and finally the stop event. Here I stop the recording after 5 seconds:

setTimeout(() => recorder.stop(), 5000);

One “interesting” issue I found was that the audio and video are sometimes not synced. I don’t know if this is a bug in Chrome. I was able to avoid this behavior by introducing a 1-second delay between getting the stream and starting the MediaRecorder. Something to investigate.

What can computers do? What are the limits of mathematics? And just how busy can a busy beaver be? This year, I’m writing Busy Beavers, a unique interactive book on computability theory. You and I will take a practical and modern approach to answering these questions — or at least learning why some questions are unanswerable!

It’s only $19, and you can get 50% off if you find the discount code ... Not quite. Hackers use the console!

After months of secret toil, I and Andrew Carr released Everyday Data Science, a unique interactive online course! You’ll make the perfect glass of lemonade using Thompson sampling. You’ll lose weight with differential equations. And you might just qualify for the Olympics with a bit of statistics!

It’s $29, but you can get 50% off if you find the discount code ... Not quite. Hackers use the console!

More by Jim

Tagged #programming, #web. All content copyright James Fisher 2020. This post is not associated with my employer. Found an error? Edit this page.