Articles / Viewpoints and methods
4 minFor tool users

Export HTML Animation to MP4 with Playwright and FFmpeg

Render a six-second HTML animation at 24 fps, encode 144 frames with FFmpeg, and verify the dimensions, duration and animation timing.

Aaron HuangSystems, product and AI practice

To export HTML animation as MP4, capture the page at successive animation times, then encode those frames as video. Start with a short animation at a fixed size and controllable times before attempting a whole website with login, interaction or external assets.

A page moving in the browser does not guarantee a correct video export. Late-loading fonts, inconsistent animation timing or a changed aspect ratio can alter the result. A six-second example separates the problem into appearance, timing and encoding.

Choose between recording interaction and rendering animation

Desired resultStarting point
Preserve mouse movement, scrolling and live interaction.Screen recording, with attention to the action sequence and playback environment.
Render the same animation repeatedly with controlled dimensions and timing.Browser rendering at specified times, followed by frame encoding.
Generate a complete animated video from an article or idea.Add scripting and animation production; this is more than file conversion.

This tutorial covers the second case: exporting an original HTML animation to a silent MP4 using Playwright screenshots and FFmpeg encoding. It is not a general website recorder or an installation tutorial for nexu-io/html-video.

Start with six seconds and one moving object

The exercise contains demo.html and render.cjs. The HTML uses local fonts and a simple block, without external images, audio or login data. The renderer uses 960 × 540 pixels, 24 frames per second and six seconds, so the expected output is 144 PNG frames.

You need Node.js, the Chromium version used by Playwright and FFmpeg. Check existing installations with node --version and ffmpeg -version. Use the following setup only in a new exercise folder; package and browser downloads require network access and disk space.

npm init -y
npm install playwright
npx playwright install chromium
node render.cjs

Node.js and FFmpeg installation varies by operating system. Obtain them from official sources rather than running an unidentified all-in-one installer. If FFmpeg cannot be found, fix the installation or PATH before rendering again.

Set each frame’s time explicitly

Frame zero represents zero seconds, and frame one represents 1/24 of a second. The exercise pauses its Web Animations API animation and sets currentTime for each screenshot. FFmpeg then reads the frames in filename order.

This controls only the animation in the exercise. A page using JavaScript timers, Canvas, video playback or live network data needs its own reproducible time controls. The same capture code does not automatically synchronize every kind of content.

Do not force all animations to finish merely to obtain a clean screenshot. You need the frames of a time sequence, not 144 identical final states.

Encode the frames and inspect the output

The exercise encodes numbered PNGs as H.264 MP4 using yuv420p, with playback metadata moved to the beginning of the container. These are compatibility choices, not a guarantee for every player. The example adds no audio track.

ffmpeg -n -framerate 24 -i frames/%04d.png -c:v libx264 -pix_fmt yuv420p -movflags +faststart demo.mp4
ffprobe -v error -show_entries stream=codec_name,width,height,r_frame_rate,nb_frames -show_entries format=duration -of json demo.mp4

-n stops when the output already exists instead of overwriting it. The exercise renderer also requires a fresh output directory. For a second attempt, a new directory name preserves the record more clearly than deleting files whose contents you have not checked.

Check the animation, not only whether the file opens

  • Check the actual dimensions, duration and frame rate: 960 × 540, six seconds and 24 fps, with 144 expected frames.
  • Inspect the beginning, middle and end to confirm the block changes position rather than remaining on the first frame.
  • Play the entire file to check for flicker, cropping and missing glyphs. Main content should remain recognizable at mobile size.
  • If adding audio, separately check its duration and alignment. A silent sample is not a complete audiovisual deliverable.

If size and duration are correct but nothing moves, check whether animation time is actually controlled. For text problems, check fonts and resource loading. Once the small example exports reliably, introduce your own layout one source of complexity at a time.

Exercise files and verification limits

Download the original exercise files attached to this page and test under the same conditions. Technical references are the Playwright screenshot documentation and official FFmpeg documentation, checked on September 14, 2026. A separate record documents the local exercise run. It does not establish that arbitrary pages or third-party tools have passed testing.

Download the exercise HTML and renderer · Local render verification record