Court métrage cartoon : idée → script → voix off → MP4 final
Le style : personnages cartoon 2D plats à tête de haricot (cartes dessinées aux contours prune) dans un monde 3D coloré avec contours à l'encre noire, textures peintes, profondeur de champ et caméras glissantes. La sortie est en 1080×1920, 30 ips, d'une durée exacte égale à celle de la voix off. La voix de l'utilisateur reste inchangée. La musique de fond et les effets sonores sont synthétisés et réglés à 50 % du niveau vocal. Testé sur « Le soldat qui n'est jamais parti » (19,7 s, 8 plans).
Règles
- Les histoires, personnages et plans sont toujours originaux. Ne recréez jamais la vidéo d'un autre créateur plan pour plan. Proposez plutôt une version originale de la même idée.
- Pas de personnes réelles nommées comme personnages, ni de mascottes de marque ou logos.
- Pas de sous-titres sauf demande de l'utilisateur. Le texte diégétique (message gravé, enseigne) est autorisé et doit être correctement orienté (non inversé).
- Ne modifiez jamais le timing de la voix. L'image est synchronisée avec elle, et chaque réaction visuelle se produit 0 à 3 images avant le mot correspondant.
- Niveaux audio : la musique de fond est à 50 % du niveau vocal (−6 dB, RMS fenêtré). Les SFX sont à 50 % ou légèrement moins, avec des pics limités pour qu'aucun son ne dépasse la narration. Toujours mixer avec
mix.py, jamais à la main. Pas de ducking ni de compression qui modifieraient ce ratio ; un seul gain linéaire plus un limiteur de crête est appliqué à l'ensemble du mix. - Tenez l'utilisateur informé avec une liste de tâches. Envoyez une planche contact d'images fixes avant le rendu long.
Étape 1 : Réception (toujours en premier)
Si un fichier audio est déjà joint, passez à l'étape 4. Si un script a également été fourni, utilisez-le pour le timing. Sinon, posez une question (ou texte simple si l'outil est absent) : « D'où partez-vous ? »
- Voix off prête : demandez à l'utilisateur de la télécharger, ainsi que le texte du script s'il l'a (le script rend le timing exact). Passez à l'étape 4 à réception.
- J'ai un script, besoin de la voix off : peaufinez le script selon l'étape 3 si nécessaire, renvoyez-le avec des conseils d'enregistrement, demandez le fichier audio, puis passez à l'étape 4.
- Besoin d'idées vidéo et d'un script : passez à l'étape 2. Demandez aussi la durée cible si elle n'a pas été donnée. La valeur par défaut est 20-30 s ; 45-60 s est autorisé.
Étape 2 : 10 idées de vidéos
Donnez exactement 10 idées en une seule réponse, numérotées, et demandez à l'utilisateur de répondre avec un numéro (ou « plus »). Chaque idée comprend :
- Titre (5-8 mots, suscitant la curiosité, ex. « Le soldat qui n'est jamais parti »).
- Phrase d'accroche : la première phrase parlée, un paradoxe énoncé comme un fait (« Un homme a vendu la tour Eiffel. Deux fois. »).
- Le retournement en une ligne (la chute ironique qui conclut la vidéo).
- Pourquoi ça s'anime bien : les 2-3 grands moments visuels (effondrement, révélation, poursuite).
- Vrai ou légende : dites clairement s'il s'agit d'histoire documentée, d'un récit contesté ou de folklore.
Ce qui rend une idée « parfaite » pour ce format :
- Une histoire surprenante avec une cause et un effet physiques que l'on peut montrer.
- Un personnage ordinaire clair, des enjeux qui montent, et un retournement dans la dernière ligne.
- Un décor pouvant être construit à partir de formes 3D simples plus des cartes dessinées (villes, ponts, navires, châteaux, déserts, laboratoires, palais).
- Mélangez les 10 idées à travers époques et thèmes : antique, médiéval, 1800s, moderne, science, animaux, inventions, catastrophes, lois étranges, accidents heureux.
- Pour tout ce qui est présenté comme vrai, vérifiez les faits clés par une recherche web avant de proposer. Ne présentez pas une légende virale comme un fait. Si l'utilisateur la veut quand même, encadrez-la par « la légende dit ».
- Pas de personnes réelles comme cible d'une blague, rien de graphique ni de politique.
Étape 3 : Script (après le choix)
Écrivez la narration uniquement (pas d'indications scéniques dans le texte parlé), à environ 3,7 mots/s : 20 s ≈ 75 mots, 30 s ≈ 110, 60 s ≈ 220. Formule :
- Accroche (phrase 1, sans préparation) : le fait absurde.
- Contexte en 1-2 lignes : quand, où, qui, un détail concret.
- Montée en tension, 2-4 temps, chacun plus fort. Les autres doutent ou se moquent. Utilisez une blague par exagération.
- Mystère ou pivot : « Mais quand... » / « Vous voyez, » introduit le vrai mécanisme, souvent avec une analogie quotidienne.
- Retournement / chute : court, ironique, et ce sont les derniers mots de la vidéo. Utilisez un français oral simple, des contractions, des phrases de 8 à 15 mots, et les nombres écrits en toutes lettres. Ne décrivez jamais ce que le spectateur voit déjà.
Ensuite, répondez avec :
- Le script dans un bloc copiable, avec le nombre de mots et la durée estimée.
- Un paragraphe de plan visuel (les plans que vous allez animer).
- Conseils d'enregistrement : une voix posée et chaleureuse de narrateur ; ElevenLabs fonctionne bien (voix grave de narrateur, vitesse environ 1.05-1.1, stabilité environ 45-55 %). Le format Mp3 ou wav convient. Laissez des pauses naturelles en fin de phrase. Exportez sans musique.
- La demande : « Téléchargez la voix off quand elle est prête et je réaliserai la vidéo complète. » Conservez le texte final du script. Il pilote le timing à l'étape 4, donc aucune reconnaissance vocale n'est nécessaire. Si l'utilisateur a enregistré une version modifiée, demandez le texte final.
Étape 4 : Construction de la vidéo (après téléchargement de la voix off)
Faites tout à partir d'ici sans vous arrêter. Ne demandez que si le timing ne peut pas être résolu.
4.0 Obtenir la trousse à outils
La trousse à outils se trouve dans ce dossier de skill sous kit/ (moteur, outils, exemple travaillé, plus three.js r160 fourni et la bibliothèque toon.ts de github.com/mromidev/claude-animated-shorts, tous deux sous licence MIT). Localisez le dossier avec find / -name SKILL.md -path "*cartoon-audio-short*" 2>/dev/null et traitez son kit/ comme en lecture seule.
Exécutez ensuite bash <skill>/kit/tools/setup.sh ~/shorts/<slug>. Il copie le moteur et les outils dans le projet, installe le three.js fourni, supprime les types de toon.ts avec Node 22 module.stripTypeScriptTypes, et lie Playwright. Aucun réseau nécessaire. Si les fichiers fournis sont absents, il utilise npm ou un clone git.
- Prérequis : Node 22.6+, Python 3 avec numpy + Pillow, ffmpeg, et Playwright avec Chromium (
npm i -g playwright && npx playwright install chromiumsi manquant). - Si les registres de paquets sont bloqués, git via GitHub fonctionne généralement. Ne désactivez jamais TLS et ne contournez pas le proxy.
- Chromium : utilisez le navigateur Playwright préinstallé avec
--use-angle=swiftshader --enable-unsafe-swiftshader --ignore-gpu-blocklist. Cela donne du WebGL CPU à environ 3-10 s par image.
4.1 Timing
Exécutez python3 timing.py voice.mp3 script.txt --out work.
- Si whisper ou faster-whisper est installé, il utilise les horodatages des mots.
- Sinon, il aligne les phrases du script (scindées à la ponctuation) aux segments de parole détectés par silence, avec une programmation dynamique qui fait correspondre les syllabes à la durée et pénalise les fins de phrase à l'intérieur d'un segment et les longs intervalles à l'intérieur d'une phrase.
- Sans ASR ni script, demandez le script. Claude ne peut pas entendre l'audio.
- Vérifiez
work/phrases.json: les pauses doivent tomber en fin de phrase. Images totales = round(durée × 30).
4.2 Plan des plans (work/PLAN.md avant le code)
Faites une ligne par plan : images, mots, décor, lumière, mouvement de caméra, personnages/poses/expressions, effets et repère SFX.
- L'image 0 est déjà l'image d'accroche.
- En général, un plan par phrase. Fusionnez les toutes petites phrases dans le plan suivant.
- Illustrez chaque phrase littéralement. Les accessoires portent les blagues.
- Variez les tailles de plan : accroche en PM → plan large de révélation → plan à deux → gros plan d'insert sur l'objet clé → gros plan de réaction → mouvement d'environnement pour la chute.
- Utilisez la lumière pour les temps : jour pour normal, doré pour déclin ou drame, bleu nuit pour explication. Un saut dans le temps provoque un flash blanc de 6 images.
- La ligne de retournement reçoit une note piquée (musique qui s'arrête, coup faible, zoom avant avec roulis). La chute physique du dernier plan tombe sur le dernier mot.
4.3 Monde (web/main.js)
Conservez les sections du moteur : matériaux toon, contrat d'encre, add/tbox, ciel, lumières, cartes, cibles de rendu/post, applyLight, drawActors, swapForNd, renderFrame. Remplacez le monde d'exemple entre // ---------- world ---------- et // ---------- cards ----------, ainsi que les parties de l'histoire dans worldState().
- Construisez à partir de primitives avec des textures peintes sur toile (
paint.js: planches, poutres, bois pourri, pierre, mousse/lierre, herbe, terre, plâtre, tuiles, marbre, bannières, texte gravé). Écrivez de nouveaux peintres dans le même style plat avec coutures sombres. - Utilisez
tboxpour une densité de texel constante, un dégradé toon en 2 étapes, et du brouillard = couleur d'horizon. - Arrière-plan : collines (demi-sphères enterrées), montagnes (cônes + calottes neigeuses), cyprès/pins, maisons lointaines, panneaux peints de nuages.
- Éléments de décor (effondrements, chutes, portes) sont des groupes pivotés pilotés par une progression 0..1 depuis
worldAt(f), avec des parties adoucies et décalées. - Le texte diégétique courbe utilise des UVs planaires. Vérifiez qu'il n'est pas inversé.
4.4 Distribution (web/roman.js → web/toon.js)
romanFront(p, outfitKey, opts)dessine sur une toile de conception 600×1000 avec les semelles à y=975. La carte mesure 2,25 m de haut, donc 1 unité = 0,00225 m.- Ajoutez des tenues à
OUTFITS(tunique/cape/armure/casque/cheveux/bonnet/barbe/tablier/robe/toge) et de nouvelles coiffes et accessoires dans le même style. - Poses de bras : pendre, lance, pointer, haut, agiter, hanche, ventre, tempe (+tourbillon), lever, atteindre (+lever), joue, bouclier, croiser, pouce.
- Expressions : l'ensemble FACE de toon.ts plus ronfler, têtu, plisser. Étendez FACE pour plus.
- Reconstruisez après modifications avec
cat web/toonbase.js web/roman.js > web/toon.js. Rendez une feuille de test des personnages avant d'utiliser de nouveaux designs. - Les panneaux tournent uniquement sur le lacet, obtiennent une tache de contact et une ombre avec test alpha, et ne sont jamais encrés par le passage monde.
- Construisez les clés de carte à partir de valeurs arrondies avec
q()(afin que la toile ne se redessine que lors d'un changement visible). - Une partie détachée (par exemple un casque soulevé) est sa propre carte, alignée avec
headCenter(seed): y = DECK + (partY − hc) × 0,00225.
4.5 Mouvement : fluide et vivant (web/motion.js)
- Caméras :
camFromKeys(keys, f, {kicks}). Utilisez des glissades smootherstep (18-45 f),easeOutpour les révélations et les fouettés, etpathvia des points de passage (Catmull-Rom) pour les mouvements courbes. Chaque tenue dérive et rien n'est statique pendant 4+ images. Utilisez des roulis de 3-5° pour le drame et des secousses de retournement de 7 images sur les impacts. - Continuité : privilégiez les mouvements continus (recul d'un gros plan vers un plan large, mise au point progressive, grue à travers le plateau, zoom avant sur un objet). Coupure franche uniquement lors de sauts de lieu ou de temps, avec un flash.
- Les personnages ne gèlent jamais : appliquez
idle(f, seed)à chaque carte,blinkAtpour les clignements, et hochements de tête sur les mots accentués. - Actions : anticipation → dépassement
back→ stabilisationspring. Un coup de pied est un trempage de 2 images + bouffée de poussière + coup de pied. Les rires sont une inclinaison + hochement alternés. - Mouvement secondaire : vagues de bannière en tissu, feuilles/poussière/gouttes/effets Zzz, eau courante. Quelque chose bouge toujours.
- Marches :
walk()donne la distance + la phase de pas. Pieds plantés, hochement de 3-7 %. - Objectif : profondeur de champ sur les gros plans et plans moyens (cInf 8-14 px), mise au point sur les yeux. Les plans larges sont nets. Les mises au point progressives prennent ~14 f.
4.6 Vérification visuelle (avant le rendu complet)
Rendez des images fixes au milieu de chaque plan plus les transitions et actions clés : node render.mjs stills/a "5,40,..." puis python3 sheet.py stills/a stills/sheet_a.jpg. Examinez la feuille et corrigez ces pièges :
- Cadre vertical étroit : demi-largeur horizontale = d·tan(hfov/2), avec hfov = 2·atan(tan(vfov/2)·0,5625). À 4 m et fov 40, cela donne ±0,8 m, donc placez les personnages en profondeur.
- Garde-corps ou poteaux devant les visages (caméra à l'intérieur du garde-corps ou ~2,5 m de haut). Trajectoire de caméra à travers maisons, toits ou buissons. Accessoires au premier plan à moins de ~2 m. Héros caché derrière un pilier.
- Texte inversé. Décalage d'une carte de partie détachée dans le mauvais sens.
- Groupes de matériaux extrudés : 0 = chapeaux, 1 = côtés+dessus.
- Encre manquante : déboguer la sortie de bord uniquement. Rayon d'encre ~2,5 px à 1080. Le ciel compte comme profondeur lointaine, pas une carte. Envoyez la feuille à l'utilisateur avec un résumé d'une ligne de chaque plan, puis commencez le rendu complet.
4.7 Son (audio.py → pistes → mix.py)
Réécrivez le tableau des repères pour l'histoire ; les synthés restent. audio.py n'écrit que des pistes (music.wav, sfx.wav).
- Musique : une courte boucle de marche (kick/caisse claire, basse pincée, nappe de cuivres). Elle s'arrête à la ligne de retournement, puis un drone grave continue.
- SFX sur les événements (en images/30) : swish sur les grands mouvements, bruit sourd sur les coups de pied, grondement+fracas sur les effondrements, grincement sur le métal, tintement sur les révélations, note piquée sur le retournement, craquements, claquement, éclaboussure, ronflement, feuilles, ambiance d'eau.
- Mix avec
python3 mix.py voice.mp3 music.wav sfx.wav. Il règle la musique à exactement 50 % du RMS fenêtré de la voix (−6 dB) et les SFX à 50 % avec des pics limités à 0,7× le pic de la voix. Il affiche les niveaux mesurés : confirmez que la musique montre −6,0 dB par rapport à la voix et que les SFX sont à ce niveau ou en dessous. - Verrouillez le timing de l'image avant de créer le son. Tout changement de timing implique de réexécuter audio.py et mix.py.
4.8 Rendu + finition
- Exécutez
node render.mjs frames "0-<N-1>"avec Bashrun_in_background, surveillé par une boucle Monitor qui rapporte la progression et capture les erreurs ou la sortie du processus.RESUME=1continue après une interruption. Ne lancez pas de Python lourd en même temps sur les petites machines. - Exécutez
bash finish.sh "Titre". Il applique un gain linéaire jusqu'à environ −14 LUFS plus un limiteur de crête à −1 dBFS, encode H.264 CRF 17 + AAC, effectue les contrôles de gel/image noire et de volume, et écritout/qa_sheet.jpg. Examinez la feuille. Les périodes de gel ≥0,4 s ou les images noires nécessitent une correction. - Livrez le MP4 avec SendUserFile et quelques lignes sur ce que montre chaque plan. Proposez des sous-titres, des ajustements ou l'idée suivante de la liste.
Pièges du moteur (conservés dans la trousse ; conservez-les si vous reconstruisez)
#include <fog_vertex>/<fog_fragment>doivent être sur leurs propres lignes.- Le passage final écrit
linearToOutputTexel(...)(les cibles de rendu sont en HalfFloat linéaire). - Le passage normal+profondeur échange les matériaux par maillage : monde → normal/profondeur, cartes → masque avec test alpha (rgb 0, a = profondeur), taches/nuages/ciel cachés, eau → normale plate. Le brouillard et les ombres sont désactivés pendant ce passage.
- L'encre est appliquée uniquement sur le côté proche des sauts de profondeur. Les plis proviennent du produit scalaire de la normale. Les voisins de carte sont ignorés. L'encre s'estompe à ~140-520 m.
- Profondeur de champ : 48 échantillons avec un test CoC par échantillon (pas de débordement du premier plan).
- Le soleil provient de az/el selon le préréglage lumineux. La caméra d'ombre est centrée sur l'action de chaque plan.
Architecture (référence pour modifier la trousse)
web/index.htmlchargemain.js(module ES) via un serveur HTTP local
…
[Version tronquée pour la traduction]