Communitygithub.com

daoge96/dsh-skills

Produire un artéfact vidéo avec du code — un pur moteur de rendu temps→image plus un pipeline de rendu/encodage/muxage validé (graphiques animés, animations de données, vidéos explicatives, bandes-annonces, boucles génératives, pièces réactives à l'audio). À utiliser lorsque le livrable est un fichier vidéo, une animation en boucle, une séquence d'images à multiplexer avec de l'audio, ou lorsque vous devez vérifier la durée/fps/les spécifications du conteneur, les coutures de boucle, un seuil « rien n'est jamais figé », des revues par planche-contact, les cibles de loudness/crête réelle, ou le débit de rendu. Chargez-le avant d'écrire la première ligne de code de dessin.

Qu'est-ce que dsh-skills ?

Ce skill transforme la production vidéo en une fonction mathématique pure `render(t)` et un pipeline vérifiable. Il est conçu pour les développeurs et les utilisateurs d'agents IA qui doivent générer des vidéos de manière déterministe et vérifiable, que ce soit pour des graphiques animés, des animations de données, des vidéos explicatives ou des boucles génératives. Le skill s'applique à tout outil capable d'exécuter du code et de lancer des processus (Claude Code, Cursor, Codex, etc.) et repose sur ffmpeg/ffprobe pour l'encodage et la vérification technique. Son fonctionnement est simple : l'utilisateur écrit une fonction `render(t)` qui produit une image pour un instant donné, et le skill orchestre le rendu image par image, le mélange, l'encodage, l'audio et le multiplexage, en vérifiant chaque étape avec des assertions précises (durée, fps, résolution, codec, loudness, etc.). Le bundle `av_audit.mjs` et `mux_normalize.mjs` fournissent des audits automatisés. Ce skill est essentiel pour éviter les bugs silencieux de décalage temporel, de valeurs dépassant les limites, de format ou de loudness qui ruinent une production vidéo.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/daoge96/dsh-skills/tree/HEAD/video-production

Demander à votre IA préférée

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

Documentation

Production vidéo avec du code

Traitez une vidéo comme une fonction pure render(t) plus un pipeline par étapes et vérifiable. Presque tous les modes de défaillance dans cette classe de tâches sont des bugs d'unités/de signe/de canal/de métrique qui passent inaperçus — donc le flux de travail ci-dessous est construit pour rendre chacun d'eux observable.

0. Figez le contrat avant de dessiner quoi que ce soit

  1. Une source temporelle unique. Tout se trouve dans render(t) ; le mappage image↔temps (t = image/fps) constitue toute l'API publique. Pas d'animation CSS, pas de temporisateurs, pas d'état d'image à image. Résultat : les images sont parallélisables, reprises, comparables, et un bug est localisable à une plage temporelle.
  2. Déterminisme. PRNG ensemencé (hash(i)/mulberry32), jamais Math.random ; jamais Date.now ; intégrez les polices et les textures sous forme de data URI afin qu'aucun réseau/remplacement de police ne puisse modifier les pixels en cours d'exécution.
  3. Rédigez les spécifications sous forme d'assertions, pas de prose. Durée, fps, résolution, codec, format de pixel, loudness, crête réelle, zone de sécurité/marges, techniques interdites, chemins de fichiers, indicateurs CLI, codes de sortie, forme de sortie JSON. Si un nombre figure dans le brief, il doit aboutir à une vérification.
  4. Décidez de la politique de couture à l'avance — tir unique / boucle / segments concaténés. Pour une boucle : tout oscillateur est sin(2π·k·t/D) avec k entier ; le film converge vers son propre premier état (pas « se ressemble ») ; les tables d'événements et les compteurs/libellés à l'écran se réinitialisent dans la transition finale ; vérifiez render(0) vs render(D).
  5. Budget par image. Mesurez render(t) avant de construire le contenu (un dessin sur canevas 1080p prend 2 à 30 ms ; 3 sous-images × 5400 images multiplie ce temps). Enregistrez le budget et respectez-le.
  6. Figez l'interface, puis hachez-la. Taille du canevas, surface de la page/API, CLI du worker, chemins de sortie. Tout contrôle qualité est lié à ce hachage de révision — un rendu contrôlé par rapport à un hachage obsolète ne vaut rien.
  7. Enregistrez les écarts délibérés. Chaque endroit où la réalité s'écarte du brief (une ondulation de grille sur des lignes « propres », une micro-typographie plus petite que le minimum indiqué, un taux d'amortissement en dehors de la plage indiquée) est consigné dans une courte liste avec une raison, afin qu'un examinateur puisse juger plutôt que découvrir.

1. Trois sondes le premier jour

SondeAssertionPourquoi
Intégrité de la capturepixels exacts, alpha == 255, gamme de couleurs, première/dernière image présentel'accumulation translucide, les erreurs de gamme/espace colorimétrique ruinent silencieusement tout le film
Coûtdistribution de render(t) en ms par scène, mémoireles changements d'architecture sont bon marché maintenant, chers plus tard
Mouvementsérie de différences inter-images sur toute la durée + la plus longue séquence figéemontre immédiatement les plages de temps mort

Règles issues de vrais échecs :

  • Le piège de la composition sur blanc. Examiner des images via un visualiseur qui compose l'alpha sur du blanc cache la translucidité ; l'encodage compose sur du noir. Faites en sorte que le chemin de révision compose exactement comme le chemin de livraison, et différenciez un pixel entre les deux.
  • Sachez ce qu'une métrique peut voir. Après un sous-échantillonnage 12×, le mouvement sous-pixel d'une ligne fine modifie la différence absolue moyenne d'environ 0,03/255, tandis qu'un changement de luminosité sur toute l'image la déplace d'environ 1,5/255. Si la métrique d'acceptation est une moyenne sous-échantillonnée, le véritable levier le moins coûteux est un canal de valeur global (par exemple une impulsion de luminance de ±3 % à 2 Hz au rythme de la pulsation), pas une plus grande ondulation.
  • Vérifiez la métrique avant l'actif. Lorsqu'une vérification échoue, videz d'abord le signal brut (enveloppe à 1 ms, profil de ligne de pixels, série d'images). La moitié des cas où « l'actif est erroné » s'avère être le détecteur.
  • Rendez les détecteurs auto-descriptifs. Modélisez et compensez le biais systématique (retard de groupe du filtre, retard de la fenêtre d'analyse causale) ; préférez le candidat le plus proche de l'événement au plus fort ; ne réglez jamais un seuil avant qu'il ne passe.
  • Affirmations exactes vs approximatives. « render(0) ≡ render(D), PSNR ∞ » est une preuve ; « la première et la dernière image encodée diffèrent de 2/255 (une image de mouvement) » est une observation. Ne brouillez jamais les deux dans un rapport.

Inclus : scripts/av_audit.mjs implémente la moitié conteneur/mouvement/boucle/loudness/planche-contact de ceci (ffmpeg uniquement, sans dépendances npm).

2. La boucle de révision est une fonctionnalité, pas une surcharge

  • Mettez en grille : des centaines d'images fixes → une douzaine de planches-contact, examinées en un seul passage.
  • Incorporez les guides : zone de sécurité, croix centrale, timecode, identifiant d'événement. L'examinateur ne doit pas avoir à garder la disposition en tête.
  • Échantillonnez par événement, pas à intervalle fixe : une image sur chaque événement prévu et une à mi-mouvement.
  • Regardez le plus attentivement les coutures : transitions de scène, bouclage, limites de segment, première/dernière image.
  • Isolez et zoomez un élément suspect sur un canevas vierge à 4–6× ; la plupart des bugs sont invisibles dans l'image complète.
  • Les artéfacts sont jetables : une commande les régénère ; ne corrigez jamais manuellement une image de révision.
  • Tenez une liste de problèmes (encombré / décalé / chevauchant / hors zone de sécurité / illisible / figé) et réexaminez après chaque série de corrections.

3. Conception du mouvement et de la boucle

  • Ambiant ≠ action. Chaque scène a besoin d'un canal continu à une fréquence différente de l'action (dérive, onde, rotation au ralenti, impulsion de valeur) avec des passages à zéro alignés sur le rythme pour que les actions atterrissent encore proprement. C'est ce qui satisfait à « rien n'est jamais figé ».
  • Une seule famille d'assouplissements. Ressort à amortissement critique 1-(1+x)e^-x (ne dépasse jamais) pour les mouvements ; assouplissement exponentiel pour les fondus, pressions, sorties. Faites en sorte que l'atterrissage coïncide avec l'événement : début = événement − durée, et normalisez pour que progress = 1 exactement à l'événement.
  • Flou de mouvement à deux endroits : à l'intérieur de la fonction image (2 à 4 échantillons d'obturateur moyennés avec une moyenne glissante — alpha = 1/(k+1) — qui se termine complètement opaque), plus dense autour des événements ; plus un mélange temporel côté encodeur. Prouvez la sémantique de la fenêtre de filtre avec un accessoire codé par indice (fournissez des images dont les pixels encodent le numéro d'image et lisez quels indices ont été moyennés), jamais à partir de la documentation.
  • Continuité par construction. Portez un modèle de géométrie/état à travers les scènes et transformez-le (morphose, échange de matériau, inondation de transition franche, ligne de balayage) au lieu de couper ou de fondre.
  • Morphoses préservant la longueur : paramétrez les formes par angle/longueur d'arc afin que les mélanges grandissent plutôt que d'évoluer.
  • Liste interdite par défaut (supprimez sauf demande contraire) : particules, lueurs, flares d'objectif, secousses de caméra, division RVB, fondus enchaînés, dégradés génériques, dépassement rebondissant.

4. Rendu et encodage

  • Format vs cible : mesurez d'abord le débit. Les images PNG sans perte font plusieurs Mo et stressent le pipeline ; le JPEG de haute qualité est ~1,5× plus rapide. Décidez une fois, puis tenez-vous-y.
  • Canalisez, ne stockez pas : alimentez ffmpeg via stdin (-f image2pipe -framerate <fps*sub> -vcodec png -i -). Mélangez avec tmix, sélectionnez la dernière image du groupe, re-timing, -frames:v <n> pour rogner.
  • Parallélisez par coût, pas par nombre d'images. Mesurez le ms par scène, puis partitionnez en blocs de temps à peu près égal ; des nombres d'images uniformes font que le worker le plus lent fixe l'horloge murale.
  • Les segments doivent pouvoir être concaténés en toute sécurité : répétez 2 images de limite à chaque extrémité, paramètres d'encodeur et base de temps identiques, vérifiez images/durée avec ffprobe, puis concaténez avec -c copy.
  • Étalez le pipeline de sorte qu'un échec ne coûte qu'une étape : rendu → mélange → encodage → audio → muxage → mesure ; chaque étape écrit un fichier.
  • Conservez un master vidéo sans perte entre les étapes (-c copy partout), et faites le loudness en dernier.
  • Sondez une chaîne d'outils inconnue avant de vous y fier : listes de filtres/encodeurs, exécutables du navigateur, versions ; autorisez les surcharges $FFMPEG/$FFPROBE ; préférez les binaires locaux épinglés aux suppositions de PATH. Un ffmpeg « média » allégé livré avec un navigateur manque généralement de x264/tmix/loudnorm.
  • Capturez la sortie enfant via des descripteurs de fichier, pas des pipes. Dans un sandbox confiné, spawn/execSync avec stdio: 'pipe' peut échouer avec EPERM alors que le même binaire fonctionne parfaitement depuis un shell. Passez plutôt des descripteurs de fichier ouverts : spawnSync(cmd, a, { stdio: ['ignore', fdOut, fdErr] }), puis lisez les fichiers — et utilisez stdio: 'ignore' pour les sondes pures d'existence/version. Acheminez stdout et stderr vers des fichiers séparés afin que les données d'image binaires ne soient pas entrelacées avec le texte du journal.
  • Terminez par une reconstruction de bout en bout à partir de la source, afin que le fichier livré ne soit pas un cache chanceux.

5. Audio et multiplexage

  • Même base de temps et même déterminisme que l'image (rendu hors ligne, ensemencé, sans dépendance temps réel).
  • Une table de repères ({t, name}) comme source unique de vérité pour chaque événement audible/visible ; les effets sonores vivent sur leur propre bus, plus silencieux que la musique.
  • Normalisez avec loudnorm en deux passes (print_format=json → measured_* → seconde passe avec linear=true), puis vérifiez avec une troisième mesure indépendante ; affirmez une loudness intégrée à ±0,5 LU et une crête réelle ≤ cible.
  • Boucles : fondez la queue (~40 ms) à zéro exact, premier échantillon non cliquable ; mesurez l'alignement des coups percussifs sur la grille et rapportez-le.
  • Muxez -c:v copy -c:a aac -b:a <spec>, puis sondez le conteneur avec ffprobe comme une assertion, pas une inspection.
  • -b:a Nk est une cible, pas un plancher pour l'encodeur AAC natif de ffmpeg (mesuré ~180–250 kbps contre une demande de 320k sur du matériel calme ; -aac_coder twoloop aide). Lisez le bit_rate déclaré et rapportez la moyenne mesurée au lieu de répéter le nombre demandé, et dites-le explicitement lorsque le cahier des charges exige un débit binaire.

Inclus : scripts/mux_normalize.mjs.

6. Gardez la couche de dessin peu coûteuse et déterministe

  • Mettez en cache tout ce qui est invariant dans le temps : arrière-plans pré-calculés, masques de texte, motifs, Path2D. Les clés de cache contiennent tous les paramètres qui peuvent modifier les pixels.
  • Les pools de canevas doivent être dimensionnés à partir des dimensions du canevas source, pas de la taille logique du contenu — sinon drawImage étire ou recadre silencieusement (cela a produit du type tronqué/déformé).
  • Évitez shadowBlur/filter dans la boucle d'image ; préférez la géométrie.
  • Mémoire : un canevas 1080p fait ~8 Mo ; limitez le pool.
  • N'oubliez pas que le nombre de sous-images multiplie linéairement le budget d'image.

7. Collaboration

  • Séparez l'auteur du vérificateur. Le vérificateur possède les scripts de contrôle qualité et l'autorité de faire échouer le livrable, et vérifie indépendamment les dimensions que l'auteur n'a pas vérifiées (alpha, fidélité par rapport à la page, loudness, fermeture de boucle). C'est ce qui attrape la classe de bug à laquelle l'auteur est aveugle.
  • Portées d'écriture disjointes + une interface figée afin que le travail parallèle ne puisse pas entrer en collision ; hachez la révision et relancez le contrôle qualité après tout changement.
  • Échouez bruyamment : sorties non nulles, une ligne PASS/FAIL par affirmation, JSON pour tout ce qui est lu par machine, pas de repli silencieux.

8. Anti-patrons

  1. Juger la couleur à travers une image de révision composée sur blanc.
  2. Modifier l'actif pour satisfaire une métrique que vous n'avez jamais caractérisée.
  3. Ajuster le seuil d'un détecteur au lieu de corriger son modèle.
  4. Relancer le rendu complet pour répondre à une question à laquelle une sonde de 20 secondes côté page répond.
  5. Découpage uniforme du nombre d'images entre des scènes de coûts très différents.
  6. Un chemin de révision qui diffère du chemin de livraison (échelle, gamme de couleurs, composition).
  7. « Ça avait l'air bien » au lieu d'une assertion ; des échecs qui sortent avec le code 0.
  8. Chirurgie de texte/actif avec des outils qui déforment les caractères non ASCII (vérifiez l'encodage après l'édition).
  9. Corriger les images de révision à la main au lieu de corriger la source.
  10. Cacher une discontinuité d'état derrière un fondu enchaîné.

9. Listes de contrôle

Pré-vol — cahier des charges → assertions ; signature render(t) figée ; politique de couture + algèbre de boucle ; actifs intégrés ; trois sondes existent ; budget par image défini ; FFMPEG/FFPROBE résolu et capacités testées.

En vol — après chaque scène : sonde de coût, série de mouvements, grille de révision échantillonnée par événement ; liste de problèmes fermée ; vérification syntaxique/type plus une vérification non ASCII sur les sources éditées ; hachez la révision.

Pré-livraison — reconstruire à partir de la source ; rendu complet (pondéré par le coût, images limites, concaténation vérifiée) ; loudness en deux passes + troisième vérification ; script de mesure indépendant → PASS/FAIL ; rapportez explicitement les affirmations exactes vs approximatives ; supprimez les scripts/temporaires et documentez la commande de régénération unique pour chacun.

Définition de fini — métadonnées du conteneur exactes ; comportement des coutures prouvé ; limite de séquence figée atteinte ; loudness/crête réelle atteints ; texte à l'écran correspond mot pour mot au brief ; une commande reconstruit à partir de la source ; tout le QC vert sur le hachage figé.

10. Scripts inclus

Les deux sont des fichiers uniques, sans dépendance (ffmpeg/ffprobe uniquement), résolvent leurs outils depuis $FFMPEG/$FFPROBE → PATH → emplacements courants, impriment une ligne PASS/FAIL par affirmation, émettent du JSON avec --json, et se terminent avec un code non nul en cas d'échec. Résolvent leur répertoire à partir du chemin de cette compétence elle-même.

# QC d'un fichier fini : conteneur vs attentes, limite de séquence figée, couture de boucle,
# loudness/crête réelle, planches-contact optionnelles pour révision humaine
node av_audit.mjs film.mp4 --expect-duration 30 --expect-fps 60 --expect-size 1920x1080 \
     --static-limit 0.5 --sheets ./sheets        # exit 0 = toutes les vérifications réussies

# Normaliser un WAV vers une cible et le muxer sur une vidéo encodée (flux vidéo copié),
# puis vérifier avec un troisième passage de mesure indépendant
node mux_normalize.mjs silent.mp4 score.wav film.mp4 --lufs -14 --tp -1 --abr 320k

av_audit.mjs utilise délibérément une série MAD basse résolution (160×90) : elle voit les changements de valeur sur toute l'image et les mouvements de blocs, pas le mouvement sous-pixel des lignes fines — associez-la à la règle de sensibilité métrique du §1. Pour une boucle, traitez first_vs_last_psnr_db comme une observation concernant une image de mouvement et prouvez l'exactitude séparément en comparant deux rendus du moteur de rendu lui-même.

Résumé en une ligne — le succès repose sur trois choses, dont aucune n'est une compétence de dessin : la fonction temporelle est pure et vérifiable, les métriques sont comprises avant d'être optimisées, et les chemins de révision et de livraison sont le même chemin.

Skills associés