programmatic-video
Skill0 starsChanged 20 days agoMITView on GitHub
Build and render deterministic 60fps 1080p MP4 animated videos, motion graphics, release recaps, product demos, and data-driven "Wrapped" videos using HTML5 Canvas, SVG, Playwright frame-stepping (window.__setFrame), multimodal contact-sheet visual self-review, procedural Python/NumPy audio synthesis, WAV SFX cue mixing, and FFmpeg. Use whenever the user asks to "make an animated video", "generate an MP4 video from code", "build a release recap / Wrapped video", "render HTML/Canvas/SVG to MP4", "create a programmatic video without Remotion boilerplate", "make a demo or farewell video with sound effects", or "animate metrics/charts into a 60fps video".
2 other projects use a version of this.
Adopted by
Most recently taken up by
- AlleninTaipei/my-codex-skillstheir own version, first seen Oct 25, 2026
- badgids/Story-Film-Skillstheir own version, first seen Aug 19, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- badgids/Story-Film-Skills★ 4same name
- AlleninTaipei/my-codex-skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repositoryOne other file it gives its agents.
- llms.txtllms.txt
The file
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 2 are distinctive, and 8 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
8
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 34
Never use real-time browser screen recording (MediaRecorder, requestAnimationFrame wall-clock capture, or CSS transitions running in real …
- Distinctive: line 39
Instead, every video built with this skill obeys three rules:
- Very specific: line 41
Rule 2 — Multimodal Contact-Sheet QA Before Full Render: Before encoding the full 60fps MP4, capture 8–12 key timestamps (render.mjs …
- Very specific: line 61
Write a self-contained 1920x1080 HTML file using HTML5 <canvas> (and/or inline <svg> + DOM overlays) that exposes:
- Very specific: line 74
Always include a seeded PRNG (mulberry32(seed)) for stars, particles, confetti, or noise so frame f is bit-identical across runs.
- Very specific: line 75
Wait for document.fonts.ready (handled automatically by render.mjs).
- Distinctive: line 80
Never run a full 60fps render first.
- Very specific: line 100
Call your image Read / View tool on ./contact-sheet.png (and any individual ./qa-frames/t-*.png that looks dense).
- Very specific: line 105
If you spot any issue in contact-sheet.png, fix scene.html and re-run Step 3 before moving on.
- Very specific: line 137
Verify the output container with ffprobe:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Programmatic Video Generation Skill
A deterministic, zero-boilerplate workflow for AI coding agents to design, visually QA, score, and render 60fps 1080p MP4 animated videos directly from a single HTML5 Canvas/SVG file, a Python procedural audio script, and a headless Playwright → FFmpeg pipe.
Paths. ${CLAUDE_SKILL_DIR} is the directory containing this SKILL.md. In Claude Code it expands automatically; in Cursor, Codex, OpenCode, or other agents, replace ${CLAUDE_SKILL_DIR} with the resolved path to skills/programmatic-video/.
Why Deterministic Frame-Stepping?
Never use real-time browser screen recording (MediaRecorder, requestAnimationFrame wall-clock capture, or CSS transitions running in real time) to produce videos with an AI agent:
- Wall-clock capture drops frames whenever CPU load spikes, causing audio/video drift and stutter.
- CSS animations run on wall-clock time, making it impossible to seek to
t = 14.20sfor instant visual QA. - Blind rendering wastes minutes: rendering 5,000 frames before checking if a title overflows its card guarantees wasted work.
Instead, every video built with this skill obeys three rules:
- Rule 1 — Pure Function of Frame Index: The entire scene is driven by
window.__setFrame(frameIndex, timeSeconds, fps)wheret = frameIndex / fps. Every position, opacity, counter, and particle is a deterministic math function oft(using a seeded PRNG likemulberry32, neverMath.random()). - Rule 2 — Multimodal Contact-Sheet QA Before Full Render: Before encoding the full 60fps MP4, capture 8–12 key timestamps (
render.mjs --timestamps ...), stitch them into a singlecontact-sheet.png(contact-sheet.py), and inspect that image using your multimodal Read/View tool to fix text clipping, overlap, or low contrast. - Rule 3 — Sample-Accurate Audio + Zero-Disk-Bloat FFmpeg Pipe: Generate a multi-segment stereo WAV soundtrack + timestamped SFX cues (
synth-audio.py), then stream PNG buffers from Playwright directly intoffmpeg -f image2pipe(render.mjs).
End-to-End Agent Workflow (6 Steps)
Step 1: Storyboard & Scene Budget
Design a concrete timeline table before writing code. Group the video into 4–8 second scenes with explicit transition timestamps (T_cut) that both scene.html and synth-audio.py share:
| Scene | Time (t) | Frames (60fps) | Visual Focus | Audio / SFX Cue |
| 01 — Hook / Alert | 0.0s – 7.0s | 0 – 420 | CRT terminal boot, typewriter logs, CTA button click at 2.7s | Sub pulse + UI click/unlock cue at 2.7s, riser into 3.4s |
| 02 — Hero Metrics | 7.0s – 15.0s | 420 – 900 | 3D perspective synthwave grid + 3 spring-physics counter cards | Full 124 BPM synthwave bass + stereo arpeggiator drop at 7.0s |
| 03 — Deep Telemetry | 15.0s – 23.0s | 900 – 1380 | Split-screen progress bars + animated semi-circular gauge | Filter sweep + high-hat drive, sub impact at 15.0s |
| 04 — Roll Call & Finale | 23.0s – 30.0s | 1380 – 1800 | Bento grid of contributor cards + "JOB'S DONE!" banner & confetti | Finale chord + voice/SFX cue at 25.2s, master fade-out 28.5–30.0s |
Step 2: Author scene.html with window.__setFrame(f, t, fps)
Write a self-contained 1920x1080 HTML file using HTML5 <canvas> (and/or inline <svg> + DOM overlays) that exposes:
window.__setFrame = function(frameIndex, timeSeconds, fps = 60) {
if (window.__rafId) {
cancelAnimationFrame(window.__rafId);
window.__rafId = null;
}
const t = typeof timeSeconds === 'number' ? timeSeconds : frameIndex / fps;
renderSceneAtTime(frameIndex, t);
};- Always include a seeded PRNG (
mulberry32(seed)) for stars, particles, confetti, or noise so framefis bit-identical across runs. - Wait for
document.fonts.ready(handled automatically byrender.mjs). - See references/visual-patterns.md for copy-pasteable recipes (3D perspective grid, spring counters, CRT terminal, gauges, bento cards, confetti physics).
Step 3: Run Fast Timestamp Snapshots & Build contact-sheet.png
Never run a full 60fps render first. Sample 1–2 timestamps per scene (plus transition midpoints) and build a single contact sheet:
# 1. Capture 9 keyframe PNGs in ~3 seconds
node "${CLAUDE_SKILL_DIR}/scripts/render.mjs" \
--html ./scene.html \
--timestamps 1.8,3.0,5.2,8.5,12.5,16.5,20.5,24.5,28.0 \
--out-dir ./qa-frames
# 2. Stitch them into a labeled grid image
python3 "${CLAUDE_SKILL_DIR}/scripts/contact-sheet.py" \
--dir ./qa-frames \
--cols 3 \
--thumb-width 560 \
--title "VISUAL QA CONTACT SHEET" \
--out ./contact-sheet.pngStep 4: Multimodal Self-Review Loop (Mandatory!)
Call your image Read / View tool on ./contact-sheet.png (and any individual ./qa-frames/t-*.png that looks dense). Check every tile against the checklist in references/visual-qa-loop.md:
- Does any text overflow or collide with card borders, badges, or progress bars?
- Are all numbers, labels, and HUD headers high-contrast and legible at 1080p?
- Did every scene transition land cleanly without an unintended empty/black frame?
If you spot any issue in contact-sheet.png, fix scene.html and re-run Step 3 before moving on.
Step 5: Synthesize Procedural Soundtrack & Mix WAV SFX Cues
Generate a stereo 44.1 kHz WAV soundtrack whose transition risers and SFX cues match the exact timestamps in scene.html:
python3 "${CLAUDE_SKILL_DIR}/scripts/synth-audio.py" \
--duration 30.0 \
--bpm 124 \
--style synthwave \
--transitions 3.4,7.0,15.0,23.0,25.2 \
--cue "25.2:./sfx/jobs-done.wav:+1.5" \
--out ./soundtrack.wavFor custom multi-segment compositions or integrating themed sound packs (such as jblxo/claude-code-sound-packs), read references/audio-synthesis.md.
Step 6: Render Final 60fps H.264 MP4 via FFmpeg Pipe
Once visual QA and audio synthesis pass, run render.mjs in full pipe mode:
node "${CLAUDE_SKILL_DIR}/scripts/render.mjs" \
--html ./scene.html \
--duration 30 \
--fps 60 \
--audio ./soundtrack.wav \
--crf 18 \
--out ./final-video.mp4Verify the output container with ffprobe:
ffprobe -v error -show_entries format=duration,size:stream=codec_name,width,height,r_frame_rate -of default=noprint_wrappers=1 ./final-video.mp4Reference Playbooks (Loaded on Demand)
| Topic | Reference File |
| Canvas/SVG visual primitives, easing functions, seeded PRNG, 3D synthwave grid, gauges, bento cards | references/visual-patterns.md |
| Multimodal contact-sheet QA loop, common layout defects, timestamp selection strategy | references/visual-qa-loop.md |
| Procedural Python/NumPy audio synthesis, chord progressions, risers, ducking, WAV SFX cue mixing | references/audio-synthesis.md |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

