Que fait novel-storyboard ?
Générateur de storyboard pour mini-séries AI — première couche du pipeline qui s'adresse directement aux modèles vidéo. Prémisse gravée dans le marbre : les plans sont générés, le coût d'un plan supplémentaire est quasi nul, donc on ne lésine pas sur le nombre de plans ; la seule limite est la durée maximale de génération d'un segment par le modèle vidéo (15 s par défaut).
Mécanisme central : les plans revendiquent des battements. Chaque plan déclare les battements consécutifs d'une scène qu'il couvre (sceneIndex + beats: [début, fin]). Un plan ne peut pas traverser deux scènes — changement de décor = changement de plan. Cela rend la relation storyboard-script vérifiable mécaniquement :
| Livrable | Problème résolu |
|---|---|
| Revendication des battements | Chaque battement est revendiqué par exactement un plan, dans l'ordre — si le script change, revalider et les plans invalides sont signalés immédiatement |
| Plan ≤ 15 s | Limite de génération d'un segment AI ; les longs dialogues sont forcés d'être découpés (params.maxShotSeconds ajustable par modèle) |
| Dialogues contenus | Durée des dialogues revendiqués ≤ durée du plan — vérifié plan par plan, pas au doigt mouillé |
| Prompt d'image-clé + texte du plan | Prompt d'image-clé (frame, en chinois, nommant directement les personnages) pour le modèle d'image avec les design sheets ; texte du plan (shot, en chinois, identité générique) décrivant ce qui se passe en quelques secondes. Les échelles de plan sont énumérées, les termes chinois doivent figurer dans le prompt d'image-clé |
| Prompt vidéo H3 (un par segment) | Structure I2VA de MiniMax H3 : instruction d'alignement fixe + integrated_multimodal_description + overall_soundscape + non_diegetic_music. Les dialogues revendiqués sont placés mot pour mot dans des blocs <d>[Chinese] …</d> — dialogues, soundscape, musique, tout dans un seul prompt |
| Prompt vidéo Seedance (un par segment, assemblé par script) | Parallèle à H3. Assemblé par le script selon la structure officielle : déclaration des images de référence, mouvement au niveau du segment, champs quantifiés par plan, dialogues {}, sons <>, musique (), contrainte de numérotation. Le modèle n'écrit que le shot de chaque plan, pas les durées, numéros ni références d'images |
| Champs de composition quantifiés | Par segment blocking (qui est à gauche/droite, distance), par plan : focale / position caméra / composition / direction du regard / point de netteté / stabilité — en l'absence d'image-clé, ils sont la seule source de composition |
| Lot de génération | Plans de même scène + même éclairage regroupés, partageant la même image de référence d'environnement — version AI du bordereau de continuité, assemblé automatiquement par le script |
| Feuille de synchronisation des voix | Chaque réplique assignée à un numéro de plan — où coller le fichier TTS sur la vidéo, assemblé automatiquement par le script |
{baseDir} = répertoire de ce fichier. Script {baseDir}/scripts/novel-storyboard.mjs, zéro dépendance, s'exécute directement avec node.
Limites (ce qu'on ne fait pas) : on n'écrit pas les dialogues ni ne modifie le script (c'est le travail de novel-script), on ne génère pas les design sheets des décors/personnages/accessoires (c'est novel-art / novel-characters), on ne fait pas de génération vidéo ni de montage. La synchronisation labiale/forme de bouche n'est pas gérée pour l'instant — c'est le travail de la pipeline de génération.
Étape 0 — Définir l'entrée et le périmètre
script.json est un prérequis absolu — un storyboard n'a pas de sens sans script. Les validateurs et render nécessitent --script. Les autres entrées sont facultatives :
--outline/--cast: vérification de l'absence de noms de personnages dans les prompts + affichage des noms réels dans C01 du rapport--art: affichage des noms de scènes dans S01 du rapport + intégration des design sheets de décor dans les lots--shots <répertoire de fiches>: optionnel — monte le catalogue de fiches de plans de shot-recipes (pointe versshot-recipes/references/cards, n'accepte que le répertoire, pas le JSON exporté), active la 18e porteshot-recipe. Ne pas utiliser si shot-recipes n'est pas installé — ce skill est autonome, ne le nécessite pas
Combien d'épisodes traiter : suit le lot du script (jusqu'où le script est écrit), par défaut ≤ 3 épisodes par lot.
Étape 1 — Générer le document de travail (seed)
node {baseDir}/scripts/novel-storyboard.mjs seed <script.json> --eps 1-3 > <workdir>/storyboard.json
Déploiement déterministe : pour chaque scène, la liste des battements (numéro, action/dialogue, durée estimée, locuteur) entre dans seedScenes — c'est le document de travail pour le découpage en plans. Les durées des battements sont calculées, pas estimées par le modèle. Le tableau shots est vide ; le découpage est le travail du modèle.
Étape 2 — Découpage par épisode et par segment
Chaque épisode est une tâche, exécutable en parallèle si possible. Chaque tâche reçoit :
{baseDir}/references/storyboard-pass.mdet{baseDir}/references/schema.md(les lire et les suivre)- Le document de travail
seedScenesde l'épisode + fiches de scène (points d'ancrage et prompt d'éclairage de art.json) + fiches de personnages (points clés d'apparence de cast.json)
Processus : d'abord découper en segments selon les unités narratives (9–15 s, ne pas traverser de scène), puis découper chaque segment en plans de 2–5 s (champ/contre-champ pour dialogues, insert sur action clé, entrée en trois plans — la grammaire de découpage est dans storyboard-pass.md). Pour chaque plan, écrire un prompt d'image-clé (chinois, nommer directement le personnage), un bloc shot (chinois, identité générique) et six champs de composition. Par segment, écrire blocking, soundscape, et éventuellement music.
Le bloc shot de chaque plan suit {baseDir}/references/shot-writing.md (indépendant du protocole : un plan = un mouvement de caméra, l'action doit être réalisable, dialogues mot pour mot, couches sonores, pas de style visuel). Selon le service vidéo utilisé, ajouter la syntaxe du protocole correspondant : MiniMax H3 voir {baseDir}/references/h3-prompt.md, Seedance voir {baseDir}/references/seedance-prompt.md.
Pour chaque segment, écrire un h3Prompt selon {baseDir}/references/h3-prompt.md (version internalisée de la méthodologie officielle, ne dépend d'aucun skill externe). Langue par défaut : anglais (promptLang peut passer en chinois), chaque plan sur une ligne indépendante. Points clés : la première ligne (instruction d'alignement et moment de coupe [Shot k]) est déduite des durées des plans, pas un seul caractère ne doit dériver (validate vérifie mot pour mot) ; les dialogues revendiqués sont placés mot pour mot dans des blocs <d>[Chinese] …</d> ; les mots de mouvement de caméra de chaque plan vont dans sa ligne ; soundscape et musique dans les deux champs suivants — le soundscape est aussi une instruction d'action ; si l'image change, le soundscape change aussi.
Les prompts Seedance ne sont pas à écrire : le panneau de prompts du rapport render et export --protocol seedance les assembleront à partir des champs ci-dessus. Le style visuel est ajouté par l'appelant, les contraintes globales via --constraints <fichier>.
Une fois le découpage terminé, supprimer seedScenes.
Étape 3 — Validation ⛔ ne pas sauter
node {baseDir}/scripts/novel-storyboard.mjs validate <storyboard.json> \
--script <script.json> --outline <outline.json> --cast <cast.json> \
[--shots </path/to/cards>]
18 portes qualité entièrement codées : couverture des battements (au niveau du plan, exactement une fois, dans l'ordre, contigus), segment 0 < durée ≤ 15, chaque plan 2–5 s, dialogues contenus dans les plans, durée totale par épisode dans ±15 % de la cible du script, ≤ 3 personnages dans le même plan (sinon explication obligatoire), numéros de segment au format E01-01 consécutifs, termes d'échelle de plan en chinois présents dans le prompt d'image-clé, mouvements de caméra dans le vocabulaire H3 et dans leur propre paragraphe [Shot k], instruction d'alignement H3 déduite de la structure du storyboard vérifiée mot pour mot + moments de coupe vérifiés un par un, dialogues revendiqués placés mot pour mot dans les blocs <d>, langue du prompt cohérente avec promptLang (contrôle bidirectionnel : chinois écrit en anglais, anglais infiltré dans le chinois, bloqué), prompt d'image-clé en chinois non vide, prompt vidéo sans nom de personnage (vérifié pour H3 quelle que soit la langue, et pour le bloc shot Seedance ; les prompts d'image-clé avec noms directs sont autorisés), champs de composition quantifiés complets, bloc shot Seedance conforme (chinois non vide, sans indication de temps, numéro de plan, référence d'image ni symbole de protocole), vérification des scènes/personnages/accessoires avec le script, vérification des fiches de plans (porte optionnelle, voir ci-dessous).
Corriger chaque violation une par une, puis relancer jusqu'à validation complète.
18e porte shot-recipe (montage optionnel) : ne s'active qu'avec --shots ; sans, elle est explicitement ignorée. Sur une coupe, on peut écrire un recipe optionnel (id de fiche, au niveau de la coupe, pas du segment, les recettes multi-cases s'expriment par des plans consécutifs avec le même id, pas par un tableau). La porte vérifie trois points : l'id existe dans le catalogue, chaque must_phrases de la fiche apparaît dans le frame du plan (après mise en minuscules, includes), et si la fiche a cuts min ≥ 2, le nombre de plans consécutifs avec le même id ne doit pas être inférieur à ce seuil. Les échelles de plan suggérées et les mouvements de caméra ne sont pas verrouillés — seulement signalés comme écart dans la colonne « Recette » du rapport et en fin de checkup : la recette est un vocabulaire, pas une loi ; si une porte optionnelle devient trop stricte, personne ne la monte.
Étape 4 — Sortie et rapport
cd <répertoire de sortie>
node {baseDir}/scripts/novel-storyboard.mjs render <nom-série>-storyboard.json --md \
--script <script.json> --outline <outline.json> --art <art.json> > <nom-série>-storyboard.md
node {baseDir}/scripts/novel-storyboard.mjs render <nom-série>-storyboard.json --html \
--script <script.json> --outline <outline.json> --art <art.json> > storyboard-report.html
La langue de l'interface du rapport est spécifiée par --lang zh|en (priorité --lang > champ lang du JSON > chinois par défaut) — ne modifie que les libellés de l'interface, indépendante de promptLang (langue des prompts H3). render utilise --frames <répertoire> pour trouver les images-clés (<répertoire>/<numéro segment>/f<numéro coupe>.png, par défaut répertoire courant) et --images <répertoire> pour les design sheets de décor des lots (<répertoire>/<slug scène>-sheet.png, par défaut ./images). Les deux peuvent pointer vers n'importe quel chemin — ce skill ne génère pas ces fichiers ; il suffit de relancer render après que les images sont produites en aval pour les intégrer au rapport. export --frames <répertoire> copie les images-clés trouvées dans le paquet de production, sans les ajouter manuellement. Le rapport contient : bande KPI, bande de rythme du storyboard (séparateurs grossiers = limites de segment, largeur proportionnelle à la durée des plans, couleur = échelle de plan, clic pour aller au segment), tableau des plans par épisode (vignette principale + barres des sous-plans + lignes détaillées + boutons de copie des prompts d'image-clé/H3), lots de génération, feuille de synchronisation des voix, portes qualité, export JSON. La version Markdown inclut le prompt H3 complet de chaque segment, prêt à copier-coller.
Le résumé indique : nombre d'épisodes et de plans, durée totale vs cible, nombre de lots de génération, chemin du rapport ; les portes non validées sont mentionnées explicitement.
Ne pas dire « Images générées » — cette étape n'existe plus, on livre des prompts et une liste d'images de référence.
Livrables finaux :
<répertoire de sortie>/
├── <nom-série>-storyboard.json
├── <nom-série>-storyboard.md
├── storyboard-report.html ← s'ouvre en double-cliquant
├── manifest.json ← généré par export
└── E01-01/ ← un dossier par segment = tout le matériel pour une génération H3
├── f1.png ← vignette principale (à placer ici après génération en aval)
├── f2.png … ← sous-vignettes
└── prompt.md ← prompt H3 (généré par export)
Relais des cinq skills (bouclage du pipeline)
novel-outline → outline.json (quoi : structure et épisodes)
novel-characters → cast.json (qui : design sheets des personnages)
novel-art → art.json (où : design sheets des décors/accessoires)
novel-script → script.json (dialogue : scènes, battements, répliques)
novel-storyboard → storyboard.json (comment : plans, premières images, lots)
Le storyboard est le consommateur final : seed lit script.json, les images-clés (en aval) utilisent les design sheets de art et characters comme références, le prompt H3 commande directement le modèle vidéo, la feuille de synchronisation des voix prépare l'assemblage TTS du script. Les cinq rapports JSON ont chacun un bouton d'exportation, et peuvent être réinjectés dans leur propre render/validate après modification.
Limites
- Interface du rapport intégrée en chinois et anglais (
--lang, par défaut chinois) ; langue des prompts contrôlée séparément parpromptLang(par défaut anglais) - Les durées sont les durées de génération envoyées au modèle vidéo, pas des estimations — modifier
params.maxSegmentSecondspour la limite du segment selon le modèle, etmin/maxCutSecondspour la plage de découpage - La synchronisation labiale/forme de bouche n'est pas gérée pour l'instant — c'est le travail de la pipeline de génération
- Les images-clés ne visent pas la perfection dès le premier jet — ce sont des ancres de composition pour le modèle vidéo. Si la composition et les assets sont corrects, c'est suffisant ; les ajustements fins sont laissés à la régénération
Accumulation des échecs de porte
validate et checkup ajoutent à chaque exécution les résultats des portes dans .gates.jsonl du répertoire courant ; stats les résume :
node {baseDir}/scripts/novel-storyboard.mjs stats
Répond à trois questions : quelle porte sonne le plus souvent (règle que le modèle ignore le plus, c'est la formulation qu'il faut améliorer), quelle porte n'a jamais sonné (porte morte ou règle déjà internalisée), à quoi ressemblent les échecs en détail (problèmes récurrents sans porte dédiée, qu'on ne peut détecter qu'humainement).
Pour ne pas journaliser, ajouter --no-log ; si l'écriture échoue, elle est silencieusement ignorée, sans affecter la validation.
Auto-test
node {baseDir}/scripts/selftest.mjs
323 assertions, sans appeler de modèle, sans utiliser de crédits. Chacune des 18 portes qualité a un cas de test de pénétration. Exécuter après toute modification du script.
Exemple fourni
{baseDir}/examples/渡口-storyboard.json : storyboard complet de l'épisode 1 de « Traversée » — 10 segments, 34 plans revendiquant les 35 battements du script, durée moyenne 3,5 s par plan, 119 s / objectif 120 s, 2 lots de génération, chaque segment avec prompt H3 complet (alignement multi-image + vérification des moments de coupe passée). Utilisé comme référence qualité et comme fixture d'auto-test.