Use MediaRecorder to capture a canvas stream and download as WebM

Tests MediaRecorder lifecycle and blob assembly. Answer: canvas.captureStream() into new MediaRecorder with video/webm, start(), collect chunks via dataavailable, stop(), then build a Blob and object URL for download.
WHAT THIS TESTS: This question probes whether you understand the MediaStream Recording API end-to-end, specifically how to bridge a CanvasRenderingContext2D animation into a recorded WebM file without server involvement. Interviewers care that you know the difference between a MediaStream, a MediaRecorder, and the resulting Blob, and that you recognize the asynchronous event-driven nature of the API. It also surfaces whether you think about MIME type support, memory management, and user-initiated download patterns.
A GOOD ANSWER COVERS: A good answer hits four things in order. First, obtain the stream by calling canvas.captureStream(framesPerSecond) which returns a MediaStream. Second, instantiate MediaRecorder with the stream and an options object containing mimeType set to video/webm, and optionally guard the call with MediaRecorder.isTypeSupported. Third, attach a dataavailable listener that pushes event.data into a chunks array, then call recorder.start(). Fourth, in the stop listener or after calling recorder.stop(), concatenate the chunks with new Blob(chunks, {type: 'video/webm'}), generate a URL with URL.createObjectURL, assign it to an anchor tag, set the download attribute, and programmatically click it. Mention that stop() itself does not return data; it merely signals the end, and the final chunk arrives via the dataavailable event.
COMMON WRONG ANSWERS: Common wrong answers include trying to create the download URL immediately after calling stop() without waiting for the terminal dataavailable event, which yields an incomplete or empty file. Another red flag is ignoring isTypeSupported and hard-coding video/webm on a browser that might default to video/mp4 or refuse the type. Some candidates suggest reading from the canvas pixel data directly via toBlob in a loop, which misses the point of the MediaRecorder API entirely. Forgetting to revoke the object URL afterward is a minor but notable leak.
LIKELY FOLLOW-UPS: Interviewers often ask how you would handle a timeslice argument to start() to produce chunked uploads instead of a single large Blob. They may ask what happens if the canvas stops drawing or the tab loses focus, or how to record audio alongside the canvas using a mixed MediaStream from MediaStream.addTrack. You might also be asked about performance implications of high frame-rate capture or how to offer a preview of the recorded video before download.
ONE CONCRETE EXAMPLE: Imagine a 30 FPS canvas animation. You call const stream = canvas.captureStream(30), then const recorder = new MediaRecorder(stream, {mimeType: 'video/webm'}). You declare const chunks = [], then recorder.ondataavailable = e => { if (e.data.size > 0) chunks.push(e.data); }. You call recorder.start(). Five seconds later you call recorder.stop(). In recorder.onstop you build const blob = new Blob(chunks, {type: 'video/webm'}), then const url = URL.createObjectURL(blob), then set a.href = url and a.download = 'capture.webm', and call a.click(). Finally you call URL.revokeObjectURL(url) after a short delay or on the next user interaction.
Source: developer.mozilla.org
Read the original → developer.mozilla.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.