Skills

HTML To Video Pipeline

Reliable HTML-to-MP4 rendering via headless browser recording (Playwright/Puppeteer) +...

Install

npx skills add XiaomiMiMo/MiMo-Code --skill html-to-video-pipeline -g -a claude-code -y
Repository
XiaomiMiMo/MiMo-Code13.7k
Category
Design
Updated
3d ago
License
MIT
Context cost
Mediumabout 3,000 tokens
Runs scripts
No, instructions only

What it does

Reliable HTML-to-MP4 rendering via headless browser recording (Playwright/Puppeteer) + ffmpeg, the ordering, gotchas, and verification steps you MUST get right or the output silently rots. Trigger whenever the user is building or debugging any pipeline that turns an HTML/CSS/JS page (single-file, multi-composition, GSAP-driven, or `@keyframes`-driven) into a video file, including headless recording, screen capture of a web page, deterministic frame-by-frame capture, multi-scene concatenation, or engine-mixed video output. Also trigger when the symptom sounds like: font swap flashing in the opening frames (FOUT), the first few seconds of the video are frozen/dead, animations play during page load and get truncated, concatenated segments produce a video whose duration is wildly wrong (e.g., 8s becomes 35s), `file://` loaded HTML fails to fetch its sub-scenes, the exported video is soft/blurry compared to the browser, or playback stutters/looks choppy despite passing a high `-r` fps to ffmpeg. Use even for one-off scripts, the failure modes here are subtle enough that starting from scratch usually reintroduces them.

HTML → Video: the pipeline that actually works

Turning a live HTML page into an MP4 sounds like a one-liner ("Playwright records, ffmpeg encodes") and the first draft always looks fine, until you play back the export and notice text flashing in a fallback font, three dead seconds at the start, or a "10-second" clip that clocks in at 35s. This skill captures the specific ordering, waits, and encoder flags that make the output trustworthy.

Think of the pipeline as five phases with a single invariant between them:

launch  →  hold @ frame 0  →  align capture start with animation start  →  record  →  trim & encode

The invariant: no pixel of the animation should render before capture is ready, AND capture must not start before every asset that affects layout has loaded. Every gotcha below is a violation of that invariant.

Quick checklist (each item is expanded below):

  1. viewport must exactly equal recordVideo.size, mismatch silently rescales the output soft/blurry.
  2. Freeze CSS animations via addInitScript before goto().
  3. goto with domcontentloaded, never load.
  4. Pre-inline data-composition-src sub-scenes, file:// blocks client-side fetch.
  5. Font wait = stylesheet <link> load → face.load() per face → fonts.ready → 2 rAFs.
  6. Probe duration with infinite-iteration / repeat: -1 guards.
  7. Unfreeze = t=0; trim leadInMs − 120ms with -ss before -i.
  8. Concat: same engine → demuxer -c copy; mixed engines → concat filter + re-encode.
  9. Verify with ffprobe duration + full decode + sampled frames. Always.

There are two capture modes, and picking the wrong one wastes a day:

Read the whole SKILL.md on GitHub

More in Design