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;
recordingsWrapperEl.appendChild(playbackVideoEl);
};
Nothing will happen yet! We need to start the recorder:
recorder.start(1000);
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.
This page copyright James Fisher 2020. Content is not associated with my employer.