Compétence de Génération Vidéo Programmatique
Un processus déterministe, sans code superflu, pour les agents IA de codage afin de concevoir, valider visuellement, noter et rendre des vidéos MP4 animées en 1080p à 60fps directement à partir d'un seul fichier HTML5 Canvas/SVG, d'un script audio procédural Python et d'un pipeline Playwright → FFmpeg.
Chemins. ${CLAUDE_SKILL_DIR} est le répertoire contenant ce SKILL.md. Dans Claude Code, il se développe automatiquement ; dans Cursor, Codex, OpenCode ou d'autres agents, remplacez ${CLAUDE_SKILL_DIR} par le chemin résolu vers skills/programmatic-video/.
Pourquoi un Pas-à-Pas d'Image Déterministe ?
N'utilisez jamais l'enregistrement d'écran en temps réel (MediaRecorder, capture horloge murale requestAnimationFrame, ou transitions CSS en temps réel) pour produire des vidéos avec un agent IA :
- La capture horloge murale perd des images lorsque la charge CPU augmente, provoquant une dérive audio/vidéo et des saccades.
- Les animations CSS se basent sur le temps réel, ce qui rend impossible de chercher
t = 14.20spour une validation visuelle instantanée. - Le rendu aveugle fait perdre des minutes : rendre 5 000 images avant de vérifier si un titre déborde de sa carte garantit un travail gaspillé.
Au lieu de cela, chaque vidéo construite avec cette compétence obéit à trois règles :
- Règle 1 — Pure Fonction de l'Index d'Image : La scène entière est pilotée par
window.__setFrame(frameIndex, timeSeconds, fps)oùt = frameIndex / fps. Chaque position, opacité, compteur et particule est une fonction mathématique déterministe det(utilisez un GNA ensemencé commemulberry32, jamaisMath.random()). - Règle 2 — Validation Visuelle par Planche-Contact Multimodale Avant le Rendu Complet : Avant d'encoder le MP4 60fps complet, capturez 8 à 12 horodatages clés (
render.mjs --timestamps ...), assemblez-les en une seulecontact-sheet.png(contact-sheet.py), et inspectez cette image à l'aide de votre outil multimodal de Lecture/Visualisation pour corriger les problèmes de débordement de texte, chevauchement ou faible contraste. - Règle 3 — Audio à Échantillon Exact + Pipeline FFmpeg Sans Encombrement Disque : Générez une bande-son stéréo WAV multi-segments + des repères SFX horodatés (
synth-audio.py), puis diffusez les tampons PNG de Playwright directement dansffmpeg -f image2pipe(render.mjs).
Processus de l'Agent de Bout en Bout (6 Étapes)
Étape 1 : Storyboard & Budget de Scène
Concevez un tableau chronologique concret avant d'écrire du code. Regroupez la vidéo en scènes de 4 à 8 secondes avec des horodatages de transition explicites (T_cut) que scene.html et synth-audio.py partagent :
| Scène | Temps (t) | Images (60fps) | Focus Visuel | Audio / Repère SFX |
|---|---|---|---|---|
| 01 — Accroche / Alerte | 0.0s – 7.0s | 0 – 420 | Démarrage terminal CRT, logs de machine à écrire, clic CTA à 2.7s | Impulsion basse + clic UI / signal de déverrouillage à 2.7s, crescendo vers 3.4s |
| 02 – Métriques Clés | 7.0s – 15.0s | 420 – 900 | Grille synthwave 3D + 3 cartes de compteurs à physique de ressort | Ligne de basse synthwave complète 124 BPM + arpège stéréo qui débute à 7.0s |
| 03 – Télémétrie Approfondie | 15.0s – 23.0s | 900 – 1380 | Barres de progression en écran partagé + jauge semi-circulaire animée | Balayage de filtre + hi-hat, impact basse à 15.0s |
| 04 – Appel Nominatif & Final | 23.0s – 30.0s | 1380 – 1800 | Grille Bento de cartes contributeurs + bannière "JOB'S DONE!" & confettis | Accord final + repère vocal/SFX à 25.2s, fondu sortant maître 28.5–30.0s |
Étape 2 : Créez scene.html avec window.__setFrame(f, t, fps)
Écrivez un fichier HTML autonome en 1920x1080 utilisant <canvas> HTML5 (et/ou <svg> en ligne + superpositions DOM) qui expose :
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);
};
- Incluez toujours un GNA ensemencé (
mulberry32(seed)) pour les étoiles, particules, confettis ou bruit afin que l'imagefsoit bit-identique d'une exécution à l'autre. - Attendez
document.fonts.ready(géré automatiquement parrender.mjs). - Consultez references/visual-patterns.md pour des recettes copiables (grille 3D, compteurs à ressort, terminal CRT, jauges, cartes Bento, physique de confettis).
Étape 3 : Exécutez les Captures d'Instantanés Rapides & Construisez contact-sheet.png
N'exécutez jamais un rendu 60fps complet en premier. Échantillonnez 1 à 2 horodatages par scène (plus les points de transition) et construisez une seule planche-contact :
# 1. Capturez 9 PNGs clés en ~3 secondes
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. Assemblez-les en une image quadrillée étiquetée
python3 "${CLAUDE_SKILL_DIR}/scripts/contact-sheet.py" \
--dir ./qa-frames \
--cols 3 \
--thumb-width 560 \
--title "PLANCHE DE VALIDATION VISUELLE" \
--out ./contact-sheet.png
Étape 4 : Boucle d'Auto-Validation Multimodale (Obligatoire !)
Appelez votre outil de Lecture / Visualisation d'image sur ./contact-sheet.png (et tout fichier ./qa-frames/t-*.png qui semble dense). Vérifiez chaque vignette par rapport à la liste de contrôle dans references/visual-qa-loop.md :
- Un texte déborde-t-il ou entre-t-il en collision avec les bordures de carte, les badges ou les barres de progression ?
- Tous les nombres, étiquettes et en-têtes HUD sont-ils à contraste élevé et lisibles en 1080p ?
- Chaque transition de scène s'est-elle réalisée proprement sans image vide/noire non intentionnelle ?
Si vous repérez un problème dans contact-sheet.png, corrigez scene.html et ré-exécutez l'Étape 3 avant de continuer.
Étape 5 : Synthétisez la Bande-Son Procédurale & Mixez les Repères SFX WAV
Générez une bande-son WAV stéréo 44.1 kHz dont les crescendos de transition et les repères SFX correspondent aux horodatages exacts dans 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.wav
Pour des compositions multi-segments personnalisées ou l'intégration de packs sonores thématiques (comme jblxo/claude-code-sound-packs), lisez references/audio-synthesis.md.
Étape 6 : Rendez le MP4 H.264 Final à 60fps via le Pipeline FFmpeg
Une fois la validation visuelle et la synthèse audio réussies, exécutez render.mjs en mode pipeline complet :
node "${CLAUDE_SKILL_DIR}/scripts/render.mjs" \
--html ./scene.html \
--duration 30 \
--fps 60 \
--audio ./soundtrack.wav \
--crf 18 \
--out ./final-video.mp4
Vérifiez le conteneur de sortie avec 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
Guides de Référence (Chargés à la Demande)
| Sujet | Fichier de Référence |
|---|---|
| Primitives visuelles Canvas/SVG, fonctions d'assouplissement, GNA ensemencé, grille synthwave 3D, jauges, cartes Bento | references/visual-patterns.md |
| Boucle de validation visuelle par planche-contact multimodale, défauts de mise en page courants, stratégie de sélection d'horodatage | references/visual-qa-loop.md |
| Synthèse audio procédurale Python/NumPy, progressions d'accords, crescendos, ducking, mixage de repères SFX WAV | references/audio-synthesis.md |