Communitygithub.com

jblxo/programmatic-video-skill

Génère et rend des vidéos MP4 animées, des motion graphics, des récapitulatifs de version et des vidéos Wrapped, en utilisant HTML5 Canvas, SVG, Playwright, la synthèse audio Python/NumPy et FFmpeg.

Qu'est-ce que programmatic-video-skill ?

Cette compétence permet aux agents IA de concevoir et de produire des vidéos MP4 60fps en 1080p de manière déterministe, sans configuration superflue. Elle automatise le pipeline complet : de l'écriture d'une scène HTML5 Canvas/SVG avec `window.__setFrame` pour un contrôle image par image, à la capture de « contact-sheets » pour une revue visuelle multimodale, en passant par une synthèse audio procédurale en Python/NumPy et le rendu final via FFmpeg. L'agent peut ainsi itérer rapidement sur la conception grâce à des captures d'écran de référence, corriger les défauts de mise en page et générer un fichier final avec bande-son échantillonnée avec précision. L'outil est conçu pour Claude Code, Cursor, Codex et tout agent exploitant Playwright et FFmpeg. Il évite l'enregistrement temps réel et l'écriture de code répétitive en utilisant des règles déterministes (image index comme pure fonction) et des scripts de rendu dédiés.

Compatible avec✓Claude Code✓Codex CLI✓Cursor✓Gemini CLI✓OpenCode
npx skills add https://github.com/jblxo/programmatic-video-skill/tree/HEAD/skills/programmatic-video

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

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 :

  1. La capture horloge murale perd des images lorsque la charge CPU augmente, provoquant une dérive audio/vidéo et des saccades.
  2. Les animations CSS se basent sur le temps réel, ce qui rend impossible de chercher t = 14.20s pour une validation visuelle instantanée.
  3. 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 de t (utilisez un GNA ensemencé comme mulberry32, jamais Math.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 seule contact-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 dans ffmpeg -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èneTemps (t)Images (60fps)Focus VisuelAudio / Repère SFX
01 — Accroche / Alerte0.0s – 7.0s0 – 420Démarrage terminal CRT, logs de machine à écrire, clic CTA à 2.7sImpulsion basse + clic UI / signal de déverrouillage à 2.7s, crescendo vers 3.4s
02 – Métriques Clés7.0s – 15.0s420 – 900Grille synthwave 3D + 3 cartes de compteurs à physique de ressortLigne de basse synthwave complète 124 BPM + arpège stéréo qui débute à 7.0s
03 – Télémétrie Approfondie15.0s – 23.0s900 – 1380Barres de progression en écran partagé + jauge semi-circulaire animéeBalayage de filtre + hi-hat, impact basse à 15.0s
04 – Appel Nominatif & Final23.0s – 30.0s1380 – 1800Grille Bento de cartes contributeurs + bannière "JOB'S DONE!" & confettisAccord 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'image f soit bit-identique d'une exécution à l'autre.
  • Attendez document.fonts.ready (géré automatiquement par render.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)

SujetFichier de Référence
Primitives visuelles Canvas/SVG, fonctions d'assouplissement, GNA ensemencé, grille synthwave 3D, jauges, cartes Bentoreferences/visual-patterns.md
Boucle de validation visuelle par planche-contact multimodale, défauts de mise en page courants, stratégie de sélection d'horodatagereferences/visual-qa-loop.md
Synthèse audio procédurale Python/NumPy, progressions d'accords, crescendos, ducking, mixage de repères SFX WAVreferences/audio-synthesis.md

Skills associés