Communitygithub.com

video-talkcraft

Skill ultime pour la création de vidéos de présentation orale (口播). Il transforme un script en une vidéo cinématographique complète avec voix off, sous-titres synchronisés, transitions fluides et une esthétique visuelle de type Apple.

Qu'est-ce que video-talkcraft ?

Ce skill est conçu pour les développeurs et créateurs de contenu qui souhaitent automatiser la production de vidéos de présentation orale. Il prend en charge l'ensemble du processus, de la rédaction du script à la vidéo finale. La pipeline commence par un script parlé (口播稿) et une piste audio (voix off enregistrée ou synthétisée). Le système génère des horodatages précis au niveau des caractères en utilisant un modèle ASR local (FireRedASR2-CTC ou faster-whisper), garantissant une synchronisation parfaite entre la parole et les animations. Ensuite, chaque phrase est annotée sémantiquement pour guider la sélection des cartes d'effets dynamiques (108 recettes). Le cœur du rendu est basé sur Remotion, permettant de créer des compositions complexes avec des caméras virtuelles, des transitions fluides et un système de sept couches. Le skill intègre des vérifications automatiques rigoureuses (preflight, beat_lint, card_lint) pour garantir la qualité. La plateforme cible est Remotion avec Node.js sur le poste local, et les scripts Python pour le traitement audio et l'annotation. L'utilisateur fournit le script, la voix off (ou choisit la synthèse Fish Audio) et les assets (B-roll, images, captures d'écran). Le skill gère ensuite la création du storyboard, l'application des effets, le rendu et la validation.

Compatible avec✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/NengShuo/video-talkcraft/tree/main

Demander à votre IA préférée

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

Documentation

video-talkcraft — Skill pour vidéos de présentation orale

Trois sources fusionnées : Pipeline (voix → horodatages au niveau des caractères → Remotion) + Lexique (108 fiches de recettes d'animations, démos diffusables + tsx autonomes) + Plans (système anti-PPT à sept couches) + Langage visuel (par défaut, paradigme Apple).

Paradigme central : Le texte pilote les visuels. Chaque phrase doit avoir une réponse visuelle vivante (travelling lent de la caméra / modification d'éléments existants). Mais un nouvel élément n'entre qu'aux limites des paragraphes sémantiques. Il est interdit d'avoir mécaniquement "un nouvel élément par phrase" (un élément par phrase est la source du fouillis ; le découpage des plans se fait par paragraphes sémantiques, le budget de mise en page voir cinematography.md §4.5) ; Un temps fort n'a qu'un seul protagoniste, une fois fini, il cède la place ; les limites des phrases de sous-titres sont les points d'ancrage temporels de l'ensemble du film.

Déroulement

① Script → ② Voix + Horodatages (CPU local) → ③ Ressources → ④ Matrice de couches SHOTBOOK → ⑤ Implémentation (Système global → Premier plan d'abord, confirmation → Plans restants)
                                → ⑥ Rendu → ⑦ Triple validation (toutes les vérifications automatiques + 1 relecture pour corriger P0/P1) → ⑧ Livraison (relecture optionnelle ≤3 rounds)

⓪ Bilan de santé préalable : Dépendances unifiées + Format d'image et langage visuel

Une seule dépendance : Tous les remotion/node_modules et workbench/node_modules des projets de présentation orale sont des liens symboliques pointant vers <racineSkill>/runtime/node_modules. Les versions sont verrouillées uniquement dans runtime/package.json (toute la famille @remotion/* à la même version). Première action pour un nouveau projet (décision utilisateur du 2026-09-15 : vérifier les mises à jour à chaque nouveau projet) :

bash <racineSkill>/runtime/check-runtime.sh --upgrade   # Installe les dépendances partagées + le navigateur headless partagé + lie le workbench ; si une nouvelle version de Remotion est disponible, met à jour toute la famille et effectue un rendu de test d'une image. En cas d'échec, annule automatiquement.

Ne continuer qu'après avoir vu [runtime] OK en dernière ligne ; si une mise à jour a eu lieu, commiter les modifications de runtime/package.json / package-lock.json. Ne pas mettre à jour en cours de production (le cache des segments ne reconnaît pas les versions de dépendances, les segments rendus avec des versions mélangées sont inconsistants). Ne jamais exécuter npm install dans le répertoire du projet (cela écrirait dans le répertoire partagé) ; pour ajouter un package → l'ajouter dans runtime/package.json, exécuter npm ci, puis commiter.

Format d'image et langage visuel (à définir avant de commencer, référence tout au long du processus)

  • Format par défaut : paysage 1920×1080 (préférence utilisateur) ; utiliser 1080×1920 uniquement si la destination est clairement TikTok/portrait.
  • Langage visuel : Si l'utilisateur spécifie clairement un style, suivre son choix (remplacement de l'ensemble des tokens) ; sinon, déterminer d'abord le domaine à partir du script, puis en déduire le style du film (references/design-language.md §0 : lire tout le script, répondre "De quoi parle-t-on ? / À qui ? / Quel ton ?" → domaine → tableau des styles pour la couleur de fond, l'accent, la typographie, les matériaux, la forme des cartes, le langage graphique, l'ambiance des ressources, le niveau d'énergie. Écrire dans SHOTBOOK §0 G0 Fiche de style), le squelette reste le paradigme Apple (une couleur d'accent, une ombre portée, une alternance de fonds pour séparer les actes, deux graisses de police, fond d'acte par défaut : clair pastel-mesh-flow / foncé mesh-flow-dark — 12 fonds d'acte voir §1.1, code template/motion-systems/backdrop.tsx), les tokens dérivés pour ce film sont placés dans theme.ts. Une seule règle s'applique à tous les styles : il est interdit de choisir une couleur au coup par coup pour chaque scène. Les cartes sont une UI neutre, elles doivent être habillées pour le film : les démos/tsx des cartes d'effets sont une présentation neutre et sans style. Après copie dans le projet, les modifier selon la fiche de style (couleur / police / rayon de bord / matériau / axes et marqueurs des graphiques / formes de substitution), mais ne pas modifier les éléments vitaux du mouvement (timing / easing / proportions géométriques / hiérarchie), contrat et contre-exemples voir design-language §0.4 ; chaque plan du SHOTBOOK doit avoir une ligne d'habillage

① Script de présentation orale

  • Chaque phrase doit contenir un point d'information, l'accroche est dans la première phrase (chiffre/conflit) ; 13 phrases ≈ 95s
  • Les chiffres doivent être écrits en toutes lettres (les horodatages sont ancrés caractère par caractère dans le texte, 197747 ne peut pas correspondre à la prononciation de "cent quatre-vingt-dix-sept mille sept cent quarante-sept") ; les noms de marques en anglais sont écrits directement (l'alignement mixte chinois-anglais a été validé)
  • Faire d'abord des recherches pour vérifier les faits, établir une "liste rouge des faits" (chiffres qui ne doivent pas être faux / données non vérifiées ne pas citer)

② Entrée audio → Prémontage → Horodatages au niveau des caractères (CPU local par défaut ; Fish Audio optionnel)

Par défaut, utiliser un fichier audio finalisé : tout enregistrement vocal réel ou TTS, entrée = une piste audio complète (wav/mp3) + un script parlé identique caractère pour caractère. S'il n'y a pas d'enregistrement et que l'utilisateur choisit la synthèse, le plan B ci-dessous peut être utilisé ; il ne remplace pas une piste audio existante ni le flux CPU local par défaut.

②-0 Prémontage audio (obligatoire pour les enregistrements réels ; pour le TTS, ne sert qu'à supprimer les bruits de bouche, peut être sauté) — Supprimer les mots de remplissage (euh / hum / du coup…), les bégaiements, les répétitions, les pauses trop longues, à effectuer avant de créer les horodatages (si l'on modifie l'audio après les horodatages, le timing / les beats sont tous décalés ; prémontage → horodatages → tout le reste, l'ordre ne peut pas être changé) :

python3 scripts/voice_trim.py audio/raw.wav script.json --dry-run --words-out audio/asr_words.json   # D'abord, uniquement le rapport : liste [filler / repeat / pause] début+fin + temps total coupé ; résultat ASR écrit sur le disque
python3 scripts/voice_trim.py audio/raw.wav script.json --words audio/asr_words.json --out audio/full.wav \
    [--video dh/host_raw.mp4 --video-out dh/host.mp4]               # Après approbation de l'utilisateur, écrire sur le disque (réutilise la liste de mots de l'étape précédente, ne relance pas l'ASR) ; la vidéo de la personne pour le même enregistrement est coupée avec le même EDL (même longueur image par image pour l'audio et la vidéo)
  • Le script est la vérité, mieux vaut omettre que se tromper : ne couper que les segments insérés qui ne sont pas dans le script dans l'ASR — ceux qui sont entièrement composés de mots de remplissage (filler), ou des bégaiements/répétitions (repeat) qui sont égaux au texte adjacent du script ; ne jamais couper les caractères du script mal compris par l'ASR (les couper supprimerait la prononciation réelle de ce caractère) ; les répétitions dues à une reformulation hors du script sont seulement signalées, coupées uniquement avec --cut-unmatched. La source par défaut de la liste de mots est FireRed (même backend que les horodatages ci-dessous), mais accepte également les SRT caractère par caractère exportés par CapCut, etc. (--srt) ou les JSON au niveau des mots (--words) ; Les SRT au niveau des phrases ne peuvent pas localiser les mots de remplissage, le script générera un avertissement. Sans script, ne couper que les mots de remplissage dont le texte entier du token est exactement la liste conservatrice (euh / hum / du coup / um…) — comparaison textuelle normalisée, pas par similarité phonétique (五≠唔, 饿≠呃) ; les mots courts adjacents répétés sans script sont seulement signalés, pas coupés (au niveau des tokens caractère par caractère, il est impossible de distinguer les mots composés des bégaiements). Lors du montage d'un webm transparent enregistré simultanément, une image clé alpha sera résolue ; si le nombre d'images est correct mais que la transparence est perdue, cela compte comme FAIL.
  • Pauses : comprimer le silence ≥0.7s à 0.35s (conserver la portion la plus calme du bruit ambiant réel à l'intérieur du segment, ne pas ajouter de zéros numériques), garder 0.25 / 0.5s de blanc au début et à la fin ; d'abord trouver les creux d'énergie, puis aligner sur la grille d'images 30fps ; cuts.json est l'EDL (contient la table de mappage source → nouvelle timeline, utilisée pour la vidéo de la personne et toute vérification ultérieure).
  • Le rapport dry-run doit être présenté à l'utilisateur avant d'écrire sur le disque : les entrées marquées « Le point de coupe n'est pas dans le silence, écouter » doivent être vérifiées par l'utilisateur ; le script ne fait que supprimer, ne pas recomposer, ne pas modifier la vitesse ou la hauteur. Après avoir monté la vidéo de la personne, exécuter preflight.py --media-only de ③ pour vérifier la durée — le même EDL n'est valable que pour le même enregistrement.

Horodatages au niveau des caractères (pour audio/full.wav après prémontage) :

# Plan A (enregistrement existant, alignement CPU local) :
pip install zhconv pypinyin sherpa-onnx soundfile numpy   # Toutes les dépendances pour le backend par défaut FireRedASR2-CTC int8
# Première fois : télécharger le modèle 767MB (model.int8.onnx + tokens.txt) dans ~/.cache/koubo/<nom_modèle>/, l'adresse se trouve dans le commentaire en tête du script
python3 scripts/timestamps_cpu.py audio/full.wav script.json audio/timestamps.json
# Alternative (évite le téléchargement manuel du modèle) : pip install faster-whisper puis ajouter --backend whisper (téléchargement automatique de 460MB au premier lancement)
python3 scripts/make_timing.py audio/timestamps.json remotion/src/timing.json

# Plan B (génération optionnelle de la voix + horodatages, par défaut requête s2.1-pro-free ; disponibilité selon Fish Audio) :
pip install requests python-dotenv   # Nécessite aussi ffmpeg, vérification avant génération
# Configurer dans .env FISH_AUDIO_API_KEY=xxx et optionnellement FISH_AUDIO_REFERENCE_ID=xxx (voir .env.example)
python3 scripts/tts_fishaudio.py script.json audio/full.wav audio/timestamps.json --timing-out remotion/src/timing.json
  • tts_fishaudio.py : par défaut --mode sentence une requête par phrase, insère le silence réel spécifié par --pause-sec (par défaut 0.25 seconde) ; --mode stream une seule requête pour tout le script, conserve les pauses naturelles. Les deux modes reçoivent du SSE UTF-8, écrivent le fichier seulement après la fin de la génération, ne fournissent pas de lecture en continu. Décoder d'abord le PCM, puis concaténer, le décalage est calculé en nombre d'échantillons. En cas d'audio vide, d'alignement manquant/invalide ou de non-correspondance du texte, une erreur est signalée ; seuls la ponctuation, la casse et la largeur des caractères sont ignorés, pas de conversion automatique de la lecture des chiffres. Pour le chinois, utiliser les points d'ancrage au niveau des caractères de l'API ; pour les mots anglais, interpolation à l'intérieur du mot ; match/ok confirme uniquement le mappage du texte, une écoute reste nécessaire. Si un prémontage est effectué après la synthèse, le ré-alignement CPU doit être relancé.
  • timestamps_cpu.py : Horodatages ASR au niveau des mots → alignement caractère par caractère avec le script parlé (Les CJK sont des points d'ancrage fiables, clé de correspondance = normalisation simplifié/traditionnel + pinyin sans ton ; les homophones ne sont pas considérés comme des erreurs ; les mots latins sont souvent mal orthographiés par les ASR, interpolation entre les points d'ancrage) → vérification de la qualité match pour chaque phrase, si <0.90 marquer pour vérification manuelle. Backend par défaut : FireRedASR2-CTC (le plus stable en fin de fichier, zéro faux positif ; l'injection complète du fichier ~200s plantera, la mémoire augmentera quadratiquement, le script divise par défaut par segments de ≤75s en fonction du silence, puis rajoute le décalage, --chunk-sec ajustable), alternative faster-whisper ; les données d'évaluation comparatives des différents backends et les adresses de téléchargement des modèles se trouvent dans les commentaires en tête du script.
  • Schéma timestamps.json : {sr, total, sentences:[{i,text,start,end,match,ok,words:[{text,start,end}]}]} — words sont token par token pour CJK + token entier pour les segments latins (ponctuation ignorée) ; tout outil d'alignement respectant ce schéma peut être utilisé.
  • make_timing.py : Convertit en timing.json (chars en correspondance 1:1 avec le texte caractère par caractère, durée de ponctuation nulle), pour la requête des points d'ancrage tSay/msSay
  • Vérification de la voix (écoute) : pas de saturation/coupure/erreur de lecture ; laisser ~0.3s de respiration entre les phrases, rend les points d'ancrage temporels plus stables

②-1 Annotation sémantique (obligatoire à partir du 2026-09-22, référence references/semantic-annotation.md)

Annoter phrase par phrase du script « ce que fait cette phrase », écrire dans semantics.json à la racine du projet — c'est le résultat du besoin de sélection des cartes. Sans cela, la sélection des cartes ne dispose que d'un seul filtre (le type d'entrée), et les dizaines de cartes restantes sont choisies au souvenir (dans la vidéo du 2026-09-21, « Je suis Wanli » a ainsi reçu la carte textuelle la moins énergétique de toute la bibliothèque, alors que la carte de nom de personne P0 n'a été trouvée par personne).

python3 <racineSkill>/scripts/semantic_annotate.py --init     # Générer le squelette à partir de timestamps.json (avec des indices lexicaux hint)
#    Remplir sem (vocabulaire fermé de 26 mots, voir taxonomy.md « Index sémantique ») / weight (main phrase principale = autorise l'entrée de nouveaux éléments, sub phrase secondaire) / entities / need
python3 <racineSkill>/scripts/semantic_annotate.py --stats    # Validation : cohérence caractère par caractère avec les horodatages · vocabulaire fermé · règles lexicales strictes (Je suis X → présentation, J'aime Abonnez-vous → appel à l'action, quantificateur → données) · au moins un main par plan

L'annotation est dérivée : prémontage → horodatages → annotation → tout le reste ; si le script est modifié ou remonté et que text ne correspond plus, l'annotation est invalide, recommencer avec --init. ②-1 est avant le découpage, donc le champ shot est vide à ce stade (le SHOTBOOK n'est pas encore écrit) : après ④, il faut obligatoirement le remplir, sinon la vérification au niveau du plan en aval ne trouvera rien —

python3 <racineSkill>/scripts/semantic_annotate.py --sync-shots   # Après ④ : remplit shot en fonction des secondes de début-fin (ou shots.json) du titre SHOTBOOK, ne modifie que shot, ne perd pas l'annotation

③ Ressources

  • La liste des ressources est générée à partir de l'annotation sémantique de ②-1, pas au hasard : les phrases dont need est preuve vont chercher des captures d'écran réelles / trouver la source, identité nécessite un avatar et des informations de compte, quantification nécessite un graphique ou une source de données, les noms / marques / lieux / URLs dans entities sont les termes de recherche.
  • D'abord, attribuer un mode de ressource à chaque plan (choix multiples, combinables) : B-roll (vidéo réelle) / Image (photo / affiche / illustration) / Capture d'écran (page web / preuve visuelle) / Animation pure — par exemple « B-roll en arrière-plan + carte de preuve par capture d'écran ». Pour les sujets d'actualité/informatifs, la preuve est prioritaire : les captures d'écran en temps réel avec Playwright apportent plus d'informations que du B-roll générique. Les quatre niveaux correspondent aux codes de type d'entrée dans taxonomy.md V / Image / Capture / Texte, chaque plan du SHOTBOOK doit avoir une ligne Ressources : V (chemin) · Image (chemin) · Texte (format voir ④)
  • Les ressources filmées sont obligatoires, pas optionnelles (règle stricte du 2026-09-06) : zéro B-roll / image dans tout le film = seulement des animations + le présentateur = le spectateur voit « un PowerPoint ». preflight.py vérifie le SHOTBOOK : les plans avec zéro V / Image sont directement FAIL, la proportion de plans V / Image < 1/3 génère un WARN (doit être justifié dans le SHOTBOOK, par exemple pour les sujets de preuve principalement basés sur des captures d'écran). « Ce film n'aura pas de B-roll » n'est pas autorisé comme décision de design ; si aucune source vidéo n'est trouvée, dégradation en image (photos Pexels → Pixabay), si aucune image non plus, alors entrer dans la « Liste des éléments non terminés / non collectés ». Les images et les vidéos ont la même clé de source. Les spécifications de collecte (résolution minimale, répertoire de destination, enregistrement) voir references/broll-sources.md « Collecte d'illustrations »
  • Règle stricte pour les images réelles : lorsqu'il existe une page réelle à capturer pour le sujet (site web officiel du produit / GitHub / documentation / galerie), il est interdit d'utiliser une maquette de code pour remplacer une capture d'écran dans les plans de type navigateur/page du film final — les fausses barres grises de l'UI de la carte de démonstration sont des placeholders, le film final doit remplacer tout le bloc par une <img> réelle, en suivant les « Instructions de réutilisation » de la carte ; les maquettes sont autorisées uniquement pour représenter une UI schématique sans équivalent réel, et le SHOTBOOK doit annoter plan par plan « Pourquoi pas d'image réelle ». Par extension : lorsque la présentation orale dit « un résultat/un effet comme celui-ci », l'image d'exemple doit être un extrait de film réel (<OffthreadVideo> intégrant un clip existant / un enregistrement réel découpé, en muted) ; lorsque l'on parle de « longue page / tableau de bord / page de paramètres », utiliser Playwright pour une capture d'écran longue de toute la page (les animations de loupe/croisière utilisent directement les coordonnées de l'image réelle). Les coordonnées des annotations sur les images réelles doivent être mesurées par la machine, jamais à l'œil nu : utiliser getBoundingClientRect du DOM pour les éléments de la page, et la mesure pixel par pixel pour l'image finale (une estimation à l'œil nu d'±30px peut placer le cercle sur un autre élément) ; pour les images réelles qui défilent/bougent, les annotations (cercle/cadre/pill) doivent être épinglées dans le système de coordonnées du contenu et se déplacer avec lui, les épingler à une position fixe à l'écran est la source du décalage.
  • Les plans avec une seule vidéo doivent avoir un cadre thématique (décision utilisateur du 2026-09-07) : Lorsque le seul sujet d'un plan est une vidéo (enregistrement d'écran / B-roll unique / citation d'un film ou d'une interview d'autrui), il est interdit de l'afficher nu en plein écran, de le poser nu sur une carte blanche, ou d'ajouter un faux lecteur (pas de barre de progression, de bouton de lecture, de code temporel — si ce n'est pas un vrai lecteur, ce serait un mensonge), la zone vidéo doit être encadrée par <ThemeFrame kind> de template/components/theme-frame.tsx : huit styles (Fenêtre de navigateur rétro / Cadre photo de magazine / Film 35 mm / Polaroid / Plan d'ingénierie / Cahier / Bord dentelé de timbre / Double fil d'araignée), choisir un style selon l'ambiance du film, un seul style par film, l'écrire dans la ligne d'habillage du SHOTBOOK ; les cartes avec plusieurs vidéos (bed-echo-blur en avant-plan / split-60-40-story à gauche / gallery-wall-dolly) utilisent également le même style pour leurs zones vidéo. Le cadre ne gère que sa propre forme et la relais décoratif ; l'entrée / sortie / travelling lent de la vue d'ensemble sont du ressort de la couche caméra ; l'image à l'intérieur du cadre n'est pas retouchée (pas de filtre / pas de zoom / pas de fondu entrée-sortie). Il n'y a que deux exceptions : lorsque la vidéo sert de fond et non de sujet (bed-echo-blur / §1.2 fond réel filmé), et les cartes d'interface produit (chat-gpt / claude-code, où l'interface est le contenu). Les images fixes n'entrent pas dans le cadre (le cadre dit « c'est une vidéo », si l'image ne bouge pas, c'est immédiatement faux ; utiliser media-pop-in / slow-push-in pour les images). Règles et tableau des huit styles : design-language §1.3
  • Ne pas coller d'images fixes pour les pages web : lorsqu'une page web disponible est trouvée lors de la recherche de documents/ressources, il est interdit de l'afficher sous forme de capture d'écran statique dans le film final, il faut la « filmer » comme avec une caméra tenue à la main — défiler (evidence-scroll-tour◆ : défilement vers le haut à vitesse constante ≈10% de la hauteur de page/s, ralentir et s'arrêter 1~2s avant d'arriver à une information clé) / tourner (stage-keyframe-tour◇ : page longue posée immobile sur une scène, la caméra s'arrête tour à tour sur les points d'intérêt) / zoomer (magnifier-detail loupe ronde qui jette un coup d'œil puis disparaît, pip-zoom-box◈ la sort pour l'afficher en permanence) / souligner (highlighter-sweep balayer une phrase entière, ink-underline◇ souligner un mot, scribble-annotation entourer/flécher, corner-bracket-frame◈ encadrer une zone) ; pour une page qui tient sur un écran, utiliser au moins slow-push-in comme bruit de fond. Un plan = un mode principal : ne pas ouvrir de loupe, ne pas tracer de ligne en direct pendant le défilement/la visite, l'ordre est « défiler jusqu'à → s'arrêter → souligner/zoomer → défiler à nouveau » ; tableau de sélection des modes de prise de vue voir shot-design.md §2④ « Prise de vue de page web ». Les ressources sont enregistrées selon les spécifications de broll-sources.md « Collecte des ressources pour prise de vue web » : Playwright capture d'écran longue 2× de toute la page + JSON des coordonnées des cibles, mesurées par DOM dans la même session (la loupe/le soulignement/les points d'arrêt utilisent tous ces coordonnées, en lien avec la règle « pas d'estimation à l'œil nu » ci-dessus). La prise de vue est entièrement effectuée par Remotion sur la capture d'écran longue (seek-safe, alignable sur les mots), pas d'enregistrement d'écran avec le navigateur (images par seconde instables, décalage du lazy loading et des en-têtes sticky, impossible de correspondre aux horodatages au niveau des caractères). Seule exception : une petite capture d'écran qui tient sur un écran et qui n'est qu'un rôle secondaire (une image parmi plusieurs empilées dans media-pop-in) peut entrer statiquement dans la carte, mais doit tout de même avoir un Ken Burns, et ne doit pas être le sujet principal de la prise de vue.
  • Pour les plans marqués B-roll, lister 2–3 mots-clés de concept visuel en anglais et lancer Pexels + Pixabay API en parallèle, les candidats sont placés dans assets/broll/ ; la hiérarchie des sources et les règles strictes de licence (utiliser uniquement des sources sans attribution) voir references/broll-sources.md
  • Comptabilité de la recherche : chaque page source contenant un fait clé doit être capturée et archivée, sources.md doit contenir le lien et la capture d'écran locale correspondante (interdit de ne conserver que le lien sans preuve) ; lors de la citation dans le film final, utiliser de préférence la capture d'écran archivée comme preuve visuelle + ligne de source au niveau micro.
  • Lorsqu'il y a du B-roll/de la capture d'écran + le matériau du présentateur correspondant à la voix (enregistrement / résultat du digital human), le présentateur est toujours réduit à un badge en incrustation permanente — avatar rond (host-shrink-to-chip◆) ou personne détourée collée dans un coin, placé en bas à gauche / bas à droite ; ne pas couper vers le présentateur, ne pas lui faire occuper tout le cadre. Les choix pour les deux pistes et toutes les contraintes strictes sont dans references/host-footage.md §5, les préréglages de plan voir shot-design.md §2⑦
  • Graphiques Manim : après --transparent --format=mov, obligatoirement convertir en VP9 webm (-c:v libvpx-vp9 -pix_fmt yuva420p)
  • Tout placer dans public/, interdiction de charger à distance pendant le rendu.
  • À la fin de ③, exécuter obligatoirement un bilan de santé des ressources (transformer les règles strictes d'entrée de host-footage / broll-sources en assertions ; la réponse était déjà écrite dans la référence, mais personne ne va la vérifier au bon moment, c'est le mode de défaillance commun des deux plus gros trous de la rétrospective du 2026-09-06 — donc au lieu d'ajouter de la documentation, l'exécuter obligatoirement avant de commencer) :
python3 scripts/preflight.py --media-only --host remotion/public/dh/host.webm --fps 30 --voice audio/full.wav
# Vérifie : Cohérence des images par seconde du matériau du présentateur (VFR) · Pas de signature d'image dupliquée dans la source · fps du matériau = fps du film final (sinon → adapter le film final au fps du matériau, interdiction d'utiliser directement -r pour convertir) ·
#     Durée alignée image par image avec la voix · Ratio d'aspect réel · Inventaire des ressources (nombre de vidéos réelles / images / captures d'écran longues de pages web) · sources.md enregistré. Si l'un d'eux est FAIL, ne pas passer à ④.

④ SHOTBOOK (obligatoirement produit, relecture avant implémentation)

D'abord, utiliser references/shot-design.md pour remplir la fiche de travail à trois faces (fond / sujet / texte + animations de chaque face

  • sept types de plans prédéfinis), puis développer en matrice de couches selon references/cinematography.md §4, exemple references/shotbook-example.md. Chaque scène : une phrase d'intention + ligne de relais des sujets + matrice de couches temps par temps (les temps sont ancrés aux horodatages au niveau des caractères ; chaque action doit pouvoir répondre « Avec qui ? »). Chaque plan doit obligatoirement avoir une ligne « Ressources : » (lisible par la machine, preflight vérifie chaque fichier avec stat) : - Ressources : V (public/broll/gpu.mp4) · Image (public/stills/a.jpg, public/stills/b.jpg) · Capture d'écran (public/pages/gh/page.png) · Texte — V / Image / Capture doivent avoir un chemin entre parenthèses, écrire « à collecter » = FAIL ; les plans purement animés doivent aussi écrire Ressources : Texte. Obligatoire : Section « ## Liste des éléments non terminés / non collectés » : tout « Ce film ne fera pas X » est soit une décision de design dans §0 (avec justification), soit dans cette section (avec raison du blocage + si la source de repli a été essayée) ; « Rien » est autorisé, la section ne doit pas manquer. Cette section sert spécifiquement à bloquer les « éléments non terminés déguisés en principe de design, qui deviennent ainsi des prémisses non remises en question » (le véritable mode de défaillance de la rétrospective du 2026-09-06). G0 doit avoir une ligne « Plan modèle : sNN » (à utiliser pour ⑤-1 : faire d'abord le premier plan pour confirmer) : par défaut s01 ; si s01 est une carte de chapitre / un plan sans animation de sujet, choisir le premier plan qui a une carte, un sous-titre, et une personne ou des ressources. Les temps doivent être vérifiables par la machine : chaque accent visuel de la phrase est placé dans remotion/beats.json ({t, anchor, sentence, what}, t est toujours obtenu par timing.json/atChar(), interdiction de saisir manuellement des secondes approximatives — les erreurs de saisie manuelle ne sont pas détectables par le contrôle qualité des images statiques), le tableau des temps du SHOTBOOK doit être cohérent avec beats.json, la vérification machine utilise scripts/beat_lint.py pour valider |Δ|≤0.1s avec timestamps.json. Ne pas apparaître avant le temps : les chiffres/graphiques dont le temps d'ancrage du mot n'est pas atteint doivent être totalement invisibles (opacité 0), interdiction de les assombrir/les griser pour « prévisualiser » ; les chiffres dans le texte doivent être cachetés avec leurs caractères suivants (l'espace vide de « il y a __ catégories » qui reste accroché est aussi un défaut). Ne pas ouvrir un plan vide : si le délai entre le début du plan et le premier point d'ancrage de l'effet est >1.5s, il doit y avoir une image porteuse (B-roll réel / continuation d'un élément du plan précédent / mur de ressources réelles), ne pas laisser la toile vide attendre le point d'ancrage du mot. Zone de protection en fin de plan : si le point d'arrivée de l'effet du point d'ancrage du mot est à <0.7s du point de sortie du plan, soit l'avancer, soit le déplacer dans le plan suivant — le point d'arrivée sera avalé par la transition ; beat_lint.py --shots shots.json vérifie une base minimale de ≥0.5s par la machine. Les événements de transition entre actes sont également dans beats.json : le moment du pic de masquage du shape wipe/changement d'acte est également généré par le point d'ancrage du mot et ajouté au tableau — les événements de transition dont les secondes absolues sont tapées manuellement flottent en dehors du système vérifiable par la machine, ni le contrôle qualité des images statiques ni beat_lint ne peut les voir. Budget de mise en page (tableau complet cinematography.md §4.5) : couper les plans par paragraphes sémantiques, chaque plan a un primary visual job ; Les plans purement textuels doivent obligatoirement avoir un graphique d'accompagnement (retour utilisateur du 2026-09-07 : « il est trop monotone de n'avoir que des animations de texte ») : pour les plans dont la ligne Ressources n'a que « Texte » (sauf les cartes de chapitre), la matrice de couches doit avoir une ligne supplémentaire « G5 Schéma ← Parle de X donc dessine Y » (references/schematic.md, code template/motion-systems/schematic.tsx), preflight génère un WARN pour les plans purement textuels qui n'ont pas cette ligne ; les effets des phrases pivot (« Mais cette fois ce n'est pas X », tournant/question rhétorique) appartiennent au plan suivant qu'elles initient ; à tout moment, ≤3 groupes de sujets à l'écran (les gardiens en retrait sont comptés), chaque plan doit laisser au moins un quadrant vide ; un seul hero à l'écran. Règles de mise en page (tableau complet references/layout.md) : le budget gère « combien placer », les règles gèrent « où, combien grand, comment aligner » — chaque plan du SHOTBOOK doit avoir une ligne de format (portée de colonne + boîte englobante du groupe + base d'alignement + échelle typographique), à la validation, utiliser debugOverlay pour vérifier les neuf points, un seul échec = P1 ; le hero à phrase unique est centré mais ne doit pas couvrir le visage (y compris les visages dans le B-roll, modifier verticalement pour prendre la ligne des tiers en dehors du visage). Rotation des mises en page (utilisateur du 2026-09-21 : les films finis ont « la personne en bas à gauche, les ressources au milieu en carré, le texte à droite, trop fixe » ; tableau complet cinematography.md §4.5 article 9) : avant d'écrire la matrice plan par plan, écrire d'abord dans G0 un « Tableau de rythme de mise en page » (| Plan | Forme·Position de la personne | Conteneur de ressources | Carte principale |, format cinematography.md §4) — ne pas utiliser la même carte de présentation (présentation de ressources / données / mouvement de caméra) 3 plans de suite, ≤1/3 du film total (pour les films ≥6 plans) ; la forme de la personne (plan américain / badge bas à gauche / badge bas à droite / à l'intérieur d'un split-screen / personne détourée collée dans un coin / brève sortie) change avec le conteneur de ressources (plein écran / encadré / split-screen / fond / composition multi-images / mur 3D / page longue) au moins tous les 3 plans consécutifs ; une même séquence B-roll n'entre pas dans deux plans adjacents. Une séquence B-roll unique est choisie parmi les sept modes de shot-design.md §2⑦, les plans adjacents ne doivent pas avoir le même mode ; les ressources multiples suivent le tableau de relations §2④′ ; preflight vérifie (utilisation consécutive / proportion FAIL) en fonction du tableau de rythme + ligne d'habillage. La rotation est un changement de composition, pas un ajout de mouvement — à l'intérieur de chaque mode, il n'y a toujours qu'un travelling lent de la caméra. Chaque plan doit avoir une « ligne de sélection de carte » (sémantique de ②-1 → carte ; les candidats sont donnés par la machine) :
python3 <racineSkill>/scripts/card_match.py --out qa/card-candidates.md   # sémantique × ligne de ressources × index des cartes → pour chaque sémantique de phrase principale de chaque plan, liste des candidats possibles + raison du classement + raison de non-sélection

Avant de l'exécuter, d'abord semantic_annotate.py --sync-shots pour remplir shot (②-1 ne connaît pas encore le découpage). En plus des candidats listés par sémantique, le tableau ajoutera une ligne pour chaque plan qui a déclaré des ressources : Candidats pour la reprise des ressources — si V / Image / Capture sont déclarés sans carte de présentation / mouvement pour les reprendre, c'est une ressource mise à nue, preflight juge FAIL. Chaque plan du SHOTBOOK doit avoir - Ligne de sélection de carte : <sémantique> → <carte>, <sémantique> → <carte> (les cartes de la ligne de sélection doivent effectivement entrer dans la ligne d'habillage, preflight vérifie) ; si une carte en dehors des candidats est choisie, le plan doit avoir une ligne - Écart sémantique : Présentation ← déjà identifié en ouverture, s11 ne se répète pas (raison ≥4 caractères, preflight reconnaît cette ligne et laisse passer). Ajouter une colonne sémantique aux lignes de temps de la matrice de couches (valeur tirée de semantics.json, pas de nouveaux mots inventés), ainsi « ce que fait ce temps » est lisible par la machine dans le découpage. Lire obligatoirement les retours d'expérience des cartes : pour chaque carte sélectionnée, copier les « Pièges connus » et « Auto-vérification avant placement » de references/cards/<slug>.md ligne par ligne dans la colonne d'auto-vérification de la matrice de couches de ce plan, et vérifier point par point après implémentation (exemple : pour les cartes de type viseur / annotation / soulignement, vérifier obligatoirement que l'annotation entoure bien la cible ; gooey-morph n'est utilisé que pour les images, pas pour le texte, et s'il n'y a pas de personne, il est centré ; chapter-title-card doit avoir un jeu de couleurs par chapitre + un motif de trait en lien avec le contenu du chapitre, le SHOTBOOK doit écrire la ligne thématique du chapitre — quatre cartes de chapitre de la même couleur et du même motif donnent l'impression « encore » pas « tourner la page ») — si les retours d'expérience des cartes ne sont pas dans le SHOTBOOK, équivaut à ne pas les avoir lus. Les mots d'animation sont choisis parmi 108 fiches de recettes (voir references/taxonomy.md), deux filtres qui consultent tous deux l'index généré par la machine (la source est les cinq champs « entrée / sémantique / forme de la ressource / position / props » du frontmatter de chaque carte, généré par scripts/cards_index.py --write, validé par --check, la modification manuelle de l'index est invalide) : d'abord filtrer par l'entrée de ce plan (Personne / V / Image / Capture / Texte / Interface / Champ — « Index des types d'entrée »), puis filtrer par la sémantique de cette phrase (Présentation / Données / Comparaison / Énumération / Citation / Appel à l'action … vocabulaire fermé de 26 mots — « Index sémantique », une carte n'est listée que sous la sémantique pour laquelle elle a été spécialement conçue) ; les cartes marquées ◦ dans l'index n'ont pas de prop de contenu modifiable (ne font que de la ressource / peau, ou rien), pour modifier le texte/les données, il faut toucher au tsx (les props de la ligne de réutilisation de chaque carte indiquent quoi modifier). Les deux lots de nouvelles cartes ◉◎ (29 cartes) ont en plus un tableau « Type d'entrée » + quatre « Scénarios courants » en début de md. Ensuite, references/taxonomy.md index de classification → references/cards/<slug>.md paramètres et pièges → template/cards/<slug>.tsx code source Remotion autonome (l'implémentation fait foi, copier dans le projet, modifier CONFIG et utiliser) ; demos/<slug>/index.html est un aperçu HTML de la même image (open gallery/index.html pour naviguer en un écran, les démos démarrent automatiquement en défilant ; les cartes de production marquées ★ ont leur matrice de production dans template/motion-systems|components). Règle stricte de fidélité : chaque carte utilisée doit exister réellement dans le projet sous src/cards/<slug>.tsx (copiée depuis template avec CONFIG modifiée) — lire le md et écrire à la main une version « ressemblante » simplifiée est la plus grande source de dérapage (perte du rebond/du claquement/de la densité, parenthèses du viseur dessinées à l'envers, carte de visite devenue bloc de couleur), la vérification machine utilise scripts/card_lint.py pour valider l'existence et la similarité slug par slug (≥0.55, la modification de CONFIG/du texte est tolérée). Habillage n'est pas réécriture : la carte copiée est une UI neutre, elle doit être habillée selon la fiche de style SHOTBOOK §0 — remplacer toutes les couleurs par des tokens theme, la pile de polices et la graisse, le rayon / le contour / l'ombre portée / le matériau, les axes / la grille / les marqueurs / la police des chiffres des cartes graphiques, les graphiques de substitution des cartes-cadres par de vraies ressources ou des graphiques stylisés — ne modifier que la couche, pas le timing / l'easing / les proportions géométriques / la hiérarchie ; à côté de la matrice de couches de chaque plan, écrire la ligne d'habillage (Nom de la carte → quelles skins modifiées), au sein du même film, les cartes du même type partagent le même ensemble de skins ; contrat, exceptions (les cartes d'interface produit ne sont pas habillées, les couleurs sémantiques ne changent pas de teinte) et contre-exemples voir design-language §0.4. La marge de 0.55 de card_lint est justement pour l'habillage : changer la peau passe, réécrire le mouvement fait tomber en dessous. Règle stricte en trois temps : entrée 0.20.8s → tenue (juste immobile suffit — le mouvement de l'image est assuré par le travelling lent de la caméra de la scène) → sortie 0.150.5s ; l'entrée est toujours plus intense que la sortie ; un seul accent fort à l'écran à la fois. Si vous choisissez une animation, vous devez aussi prendre ses effets sonores : chaque carte a une table de repères (cue) dans demos/_lib/sfx-map.js ({t, name, vol, rate?, clip?}, t est en secondes relatives à la carte) — lors de la sélection de la carte dans le SHOTBOOK, recopier les repères dans la matrice de couches du plan concerné (convertir en secondes absolues ; vol doit être re-marqué à ≤0.35 selon le calibre du film final, la limite supérieure de 0.65 dans la bibliothèque de démos est un calibre d'écoute, pas un calibre de film final). Mettre en œuvre selon l'étape sfx de ⑤. Couverture du calibre : couverture totale des entrées des effets principaux, alignée sur la densité de la bibliothèque de démos (environ 26 coups par carte ≈ 0.4 coups/s, pour un film de 100s environ 4050 coups) — « Peu mais précis » gère le fait de ne pas superposer deux coups sur un même point, le volume modéré (≤0.35), les cartes de révélation continue (travelling lent/mise au point/dévoilement mot par mot) et les cartes purement textuelles pour les phrases percutantes, le silence pour le logo final, les transitions ne doivent avoir qu'une préparation, pas un point d'impact, pas de jingle de fin ni d'impact lourd ; ce n'est pas une réduction de la couverture. Les vrais échantillons (pk-

… (tronqué)

Skills associés