User Rating 0.0 โ˜…โ˜…โ˜…โ˜…โ˜…
Total Usage 0 times
Category Media Tools
Presets
Frames: 0 Time: 0.0s Size: 0 KB
Is this tool helpful?

Your feedback helps us improve.

โ˜… โ˜… โ˜… โ˜… โ˜…

About

Recording an HTML5 Canvas animation to a distributable video file has historically required server-side FFmpeg pipelines or frame-by-frame PNG export followed by manual stitching. Both approaches introduce latency, storage overhead, and deployment complexity. This tool eliminates that dependency entirely by leveraging the browser-native captureStream(fps) method on the <canvas> element, piping the resulting MediaStream into a MediaRecorder instance configured for VP8/VP9 WebM encoding. The output is a standards-compliant video file generated with zero server round-trips. Recording fidelity depends on the client GPU and the complexity of the draw loop. Frame drops occur when the compositor cannot maintain the requested fps under heavy fill-rate pressure. This tool approximates constant-framerate output, but the WebM container uses variable frame timing internally. For production pipelines requiring H.264/MP4, the exported WebM can be transcoded offline via FFmpeg.

canvas to video canvas recorder mediarecorder webm export html5 canvas animation capture canvas capturestream browser video recording

Formulas

The canvas stream capture pipeline follows a direct data flow from the rendering context to an encoded video container:

stream = canvas.captureStream(fps) โ†’ MediaRecorder(stream) โ†’ Blob[] โ†’ WebM

Estimated output file size can be approximated by:

S bitrate ร— t

where S is file size in bits, bitrate is the encoder output rate in bps, and t is duration in seconds. For VP8 at default quality on a 720p canvas:

S 2.5 ร— 106 ร— t bits

Frame timing within the animation loop uses delta-time normalization to decouple rendering speed from monitor refresh rate:

ฮด = tcurrent โˆ’ tprevious1000

where ฮด is the elapsed time in seconds, used to scale all position updates. This ensures consistent animation speed whether the display runs at 60 Hz or 144 Hz.

Reference Data

ParameterValue / RangeNotes
Output FormatWebM (VP8 / VP9)Browser-dependent codec selection
Canvas Stream FPS1 - 60Higher values increase file size linearly
Max Resolution4096 ร— 4096GPU texture limit on most devices
Typical Bitrate (720pโ€‰30fps)โ‰ˆ 2.5 MbpsVP8 default quality
Color SpacesRGB (8-bit)Canvas 2D default; no HDR
Alpha ChannelNot supportedMediaRecorder drops alpha
Audio TrackNone (silent)Can be muxed post-export
captureStream() SupportChrome 51+, Firefox 43+, Edge 79+Safari 14.1+ partial
MediaRecorder SupportChrome 47+, Firefox 25+, Edge 79+Safari 14.1+ (WebM limited)
Max Duration (practical)โ‰ˆ 300 sLimited by available RAM for blob chunks
VP8 ProfileConstrained BaselineHardware-accelerated on most GPUs
VP9 ProfileProfile 0Better compression, slower encoding
Chunk Interval100 mstimeslice parameter for ondataavailable
File Size (10s @ 720p)โ‰ˆ 3 - 5 MBVaries with scene complexity
Particle Animation200 particlesConfigurable count
Wave AnimationSine superposition3 overlapping waves
Geometry AnimationRotating polygons3 - 8 sided
Gradient AnimationHSL rotation360ยฐ cycle
Browser Memory Limitโ‰ˆ 2 GBChrome per-tab limit; long recordings may OOM

Frequently Asked Questions

The MediaRecorder API encodes frames as they arrive from captureStream(). If the browser's compositor drops frames under GPU pressure, those gaps appear in the output. The WebM container stores per-frame timestamps rather than enforcing a fixed cadence. For strict constant-FPS output, post-process the WebM with FFmpeg using the filter -vf "fps=30" to re-time frames uniformly.
Browser MediaRecorder implementations overwhelmingly support only WebM with VP8 or VP9 codecs. Safari has partial support for MP4/H.264 via MediaRecorder, but it is unreliable. The recommended workflow is to export WebM from this tool, then transcode to MP4 offline: ffmpeg -i output.webm -c:v libx264 -crf 20 -preset fast output.mp4. This yields a universally compatible file.
MediaRecorder accumulates encoded chunks in memory as Blob objects. At approximately 2 GB of accumulated data (Chrome's per-tab limit), the tab will crash or the recording will silently fail. For a 720p canvas at default VP8 quality (~2.5 Mbps), this translates to roughly 100-120 minutes of recording. For safety, keep recordings under 5 minutes or monitor the chunk count displayed in the UI.
captureStream() is defined on HTMLCanvasElement only. OffscreenCanvas does not expose it. For WebGL contexts rendered on a regular , captureStream() works but you must set preserveDrawingBuffer: true in the WebGL context attributes, otherwise captured frames may appear blank. This tool uses Canvas 2D, which has no such restriction.
During recording, the browser may throttle requestAnimationFrame if the tab is backgrounded or if GPU load spikes from simultaneous encoding. The delta-time normalization in this tool compensates for timing variations, but visual stuttering can still occur. Keep the tab focused and avoid other GPU-intensive tasks during capture for best results.
The MediaRecorder's start(timeslice) parameter controls how frequently ondataavailable fires. This tool uses 100ms intervals. Smaller values increase the number of Blob chunks but do not affect encoding quality. Larger values reduce event overhead but increase memory per chunk. The codec bitrate and canvas resolution are the primary quality determinants, not the timeslice.