Skill zur Programmatischen Videoerstellung
Ein deterministischer, boilerplate-freier Workflow für KI-Codierungsagenten, um 60fps 1080p MP4-Animationsvideos direkt aus einer einzigen HTML5-Canvas/SVG-Datei, einem Python-prozeduralen Audio-Skript und einer Headless-Playwright→FFmpeg-Pipe zu entwerfen, visuell zu QA-en, zu bewerten und zu rendern.
Pfade. ${CLAUDE_SKILL_DIR} ist das Verzeichnis, das dieses SKILL.md enthält. In Claude Code wird es automatisch expandiert; in Cursor, Codex, OpenCode oder anderen Agenten ersetzen Sie ${CLAUDE_SKILL_DIR} durch den aufgelösten Pfad zu skills/programmatic-video/.
Warum Deterministisches Frame-Stepping?
Verwenden Sie niemals Echtzeit-Bildschirmaufzeichnung (MediaRecorder, requestAnimationFrame-Wall-Clock-Capture oder CSS-Übergänge in Echtzeit), um Videos mit einem KI-Agenten zu produzieren:
- Wall-Clock-Capture verliert Frames, wenn die CPU-Last steigt, was zu Audio/Video-Drift und Ruckeln führt.
- CSS-Animationen laufen nach Wall-Clock-Zeit, was es unmöglich macht, zu
t = 14.20szu springen, um sofort eine visuelle Qualitätskontrolle durchzuführen. - Blindes Rendern verschwendet Minuten: Das Rendern von 5.000 Frames, bevor geprüft wird, ob ein Titel seine Karte überläuft, garantiert verschwendete Arbeit.
Stattdessen befolgt jedes mit dieser Skill erstellte Video drei Regeln:
- Regel 1 – Reine Funktion des Frame-Index: Die gesamte Szene wird durch
window.__setFrame(frameIndex, timeSeconds, fps)gesteuert, wobeit = frameIndex / fps. Jede Position, Deckkraft, Zähler und jedes Partikel ist eine deterministische mathematische Funktion vont(unter Verwendung eines gesäten PRNG wiemulberry32, niemalsMath.random()). - Regel 2 – Multimodale Kontaktbogen-QA vor dem vollständigen Render: Vor der Kodierung des vollständigen 60fps MP4s erfassen Sie 8–12 wichtige Zeitstempel (
render.mjs --timestamps ...), fügen sie zu einem einzigencontact-sheet.pngzusammen (contact-sheet.py) und inspizieren dieses Bild mit Ihrem multimodalen Lese-/Ansichtswerkzeug, um Textüberläufe, Überlappungen oder geringen Kontrast zu beheben. - Regel 3 – Sample-genaues Audio + Null-Plattenplatz-FFmpeg-Pipe: Generieren Sie eine mehrsegmentige Stereo-WAV-Soundtrack + zeitgestempelte SFX-Cues (
synth-audio.py), streamen Sie dann PNG-Puffer von Playwright direkt inffmpeg -f image2pipe(render.mjs).
End-to-End-Agenten-Workflow (6 Schritte)
Schritt 1: Storyboard & Szenenbudget
Entwerfen Sie eine konkrete Zeitplantabelle, bevor Sie Code schreiben. Gruppieren Sie das Video in 4–8 Sekunden dauernde Szenen mit expliziten Übergangs-Zeitstempeln (T_cut), die sowohl scene.html als auch synth-audio.py gemeinsam nutzen:
| Szene | Zeit (t) | Frames (60fps) | Visueller Fokus | Audio / SFX-Cue |
|---|---|---|---|---|
| 01 – Hook / Alert | 0,0s – 7,0s | 0 – 420 | CRT-Terminal-Boot, Schreibmaschinen-Logs, CTA-Button-Klick bei 2,7s | Sub-Puls + UI-Klick/Entsperr-Cue bei 2,7s, Riser bis 3,4s |
| 02 – Hero-Metriken | 7,0s – 15,0s | 420 – 900 | 3D-Perspektiv-Synthwave-Grid + 3 Federphysik-Zählerkarten | Vollständiger 124 BPM Synthwave-Bass + Stereo-Arpeggiator-Drop bei 7,0s |
| 03 – Deep Telemetry | 15,0s – 23,0s | 900 – 1380 | Geteilte Bildschirm-Fortschrittsbalken + animiertes halbkreisförmiges Messgerät | Filter-Sweep + High-Hat-Drive, Sub-Impact bei 15,0s |
| 04 – Roll Call & Finale | 23,0s – 30,0s | 1380 – 1800 | Bento-Grid aus Mitwirkenden-Karten + "JOB'S DONE!"-Banner & Konfetti | Finale-Akkord + Sprach-/SFX-Cue bei 25,2s, Master-Fade-Out 28,5–30,0s |
Schritt 2: Erstellen von scene.html mit window.__setFrame(f, t, fps)
Schreiben Sie eine eigenständige HTML-Datei in 1920x1080 unter Verwendung von HTML5 <canvas> (und/oder Inline-<svg> + DOM-Overlays), die Folgendes bereitstellt:
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);
};
- Fügen Sie immer einen gesäten PRNG (
mulberry32(seed)) für Sterne, Partikel, Konfetti oder Rauschen ein, damit Framefüber alle Ausführungen hinweg bit-identisch ist. - Warten Sie auf
document.fonts.ready(wird automatisch vonrender.mjsbehandelt). - Siehe references/visual-patterns.md für kopierbare Rezepte (3D-Perspektiv-Grid, Federzähler, CRT-Terminal, Messgeräte, Bento-Karten, Konfetti-Physik).
Schritt 3: Schnelle Zeitstempel-Snapshots ausführen & contact-sheet.png erstellen
Führen Sie niemals zuerst einen vollständigen 60fps-Render durch. Nehmen Sie 1–2 Zeitstempel pro Szene (plus Übergangs-Mittelpunkte) auf und erstellen Sie einen einzigen Kontaktbogen:
# 1. 9 Keyframe-PNGs in ~3 Sekunden erfassen
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. Zu einem beschrifteten Rasterbild zusammenfügen
python3 "${CLAUDE_SKILL_DIR}/scripts/contact-sheet.py" \
--dir ./qa-frames \
--cols 3 \
--thumb-width 560 \
--title "VISUELLER QA-KONTAKTBOGEN" \
--out ./contact-sheet.png
Schritt 4: Multimodale Selbstprüfung (Pflicht!)
Rufen Sie Ihr Bild-Read/View-Werkzeug für ./contact-sheet.png (und für einzelne ./qa-frames/t-*.png, die dicht aussehen) auf. Überprüfen Sie jede Kachel anhand der Checkliste in references/visual-qa-loop.md:
- Läuft Text über oder kollidiert er mit Kartenrändern, Abzeichen oder Fortschrittsbalken?
- Sind alle Zahlen, Beschriftungen und HUD-Kopfzeilen kontrastreich und bei 1080p lesbar?
- Ist jeder Szenenübergang sauber gelandet, ohne einen unbeabsichtigten leeren/schwarzen Frame?
Wenn Sie ein Problem in contact-sheet.png entdecken, korrigieren Sie scene.html und führen Sie Schritt 3 erneut aus, bevor Sie fortfahren.
Schritt 5: Prozeduralen Soundtrack synthetisieren & WAV-SFX-Cues mischen
Generieren Sie einen Stereo-44,1-kHz-WAV-Soundtrack, dessen Übergangs-Riser und SFX-Cues mit den exakten Zeitstempeln in scene.html übereinstimmen:
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.wav
Für benutzerdefinierte Mehrsegment-Kompositionen oder die Integration thematischer Soundpakete (wie jblxo/claude-code-sound-packs) lesen Sie references/audio-synthesis.md.
Schritt 6: Finales 60fps H.264 MP4 über FFmpeg-Pipe rendern
Sobald die visuelle QA und die Audio-Synthese bestanden sind, führen Sie render.mjs im vollständigen Pipe-Modus aus:
node "${CLAUDE_SKILL_DIR}/scripts/render.mjs" \
--html ./scene.html \
--duration 30 \
--fps 60 \
--audio ./soundtrack.wav \
--crf 18 \
--out ./final-video.mp4
Überprüfen Sie den Ausgabecontainer mit ffprobe:
ffprobe -v error -show_entries format=duration,size:stream=codec_name,width,height,r_frame_rate -of default=noprint_wrappers=1 ./final-video.mp4
Referenz-Playbooks (auf Abruf geladen)
| Thema | Referenzdatei |
|---|---|
| Canvas/SVG-Visual-Primitiva, Easing-Funktionen, gesäter PRNG, 3D-Synthwave-Grid, Messgeräte, Bento-Karten | references/visual-patterns.md |
| Multimodaler Kontaktbogen-QA-Loop, häufige Layout-Fehler, Strategie zur Zeitstempelauswahl | references/visual-qa-loop.md |
| Prozedurale Python/NumPy-Audio-Synthese, Akkordfolgen, Riser, Ducking, WAV-SFX-Cue-Mixing | references/audio-synthesis.md |