What render.mjs does that the article's version doesn't
- Network sandbox: every request is served from disk under a fake origin, and anything else is blocked and fails the render.
- Parallel workers: six pages render interleaved frames. That's only valid because
seek(t)is pure. Proof:--workers 1and--workers 6gave 720/720 identical frame hashes. - Consistent Chromium: forced sRGB, no font hinting, no LCD text, CPU rasterization.
- Ready signal: a
window.filmReadyhandshake after explicitdocument.fonts.load().fonts.readyalone misses fonts that only a canvas uses. - Exclusive end frame: loop-correct by construction.
Four bugs found in audit and fixed
new URL(import.meta.url).pathnamekeeps%20, which breaks paths with spaces. Fix:fileURLToPath.p.startsWith(ROOT)letsmotion-studio-secrets/through. Fix:ROOT + path.sep.- Color.
-colorspace bt709only tags the file; the RGB→YUV math is a separate step. Test: on ffmpeg 6.1,#10b981decoded as (0, 163, 126), visibly duller. ffmpeg 9 was fine. Fix: explicitscale=out_color_matrix=bt709, plussetparams(Claude found PNG frames arrive tagged "unspecified"). - Page errors kept rendering broken frames. Fix: fail fast with the frame time.
Fact-check of the article
- ⚠️
tmixwith 4 subframes is a 270° shutter, looking forward from each frame time; film convention is 180°. - ⚠️ The article's spring treats overdamped as critical (see Lesson 6).
- ✅ The Remotion and HyperFrames commands match their docs. HyperFrames uses Puppeteer, not Playwright.
Sources for this lesson are in the references. The lesson’s source file is docs/course/05-renderer.md.