Que fait make-video ?
Transforme une idée en un MP4 rendu et vérifié en utilisant uniquement des outils gratuits et locaux. Un projet réalisé avec cette compétence a ses propres règles dans AGENTS.md, donc suivez-les (pureté d'animation, useScale, sec(), structure de dossiers).
0. Configurer un projet vidéo (une fois)
Si le dossier actuel n'a pas de fichier tools/make-story.sh, ce n'est pas encore un projet vidéo :
-
Vérifiez la machine avant tout :
uname -sm(nécessite Darwin arm64),node --version(20+),brew --version,df -h ~(environ 8 Go libres). Sur un autre OS, dites ce qui ne fonctionnera pas (Chatterbox et le vérificateur de prise fonctionnent sur le GPU Apple) avant d'aller plus loin. Si Node ou Homebrew manque, donnez à l'utilisateur la seule commande d'installation et attendez. -
Dites à l'utilisateur ce qui sera téléchargé, et attendez son accord. Ne commencez jamais les téléchargements sans cela. Montrez ce tableau (tout est gratuit, provenant des sources officielles) :
Téléchargement Taille Utilisé pour Destination Paquets npm (Remotion etc.) ~500 Mo rendu node_modules/ffmpeg, uv, FluidSynth (Homebrew, seulement si manquant) ~150 Mo outils audio/vidéo Homebrew Paquets Python (PyTorch, Chatterbox…) ~1,5 Go voix, QA .venv/Soundfont GeneralUser GS ~30 Mo musique tools/soundfonts/Poids Chatterbox ~3 Go la voix Cache Hugging Face ( ~/.cache/huggingface), partagé par tous les projetsWhisper small.en ~590 Mo sous-titres tools/models/Whisper large-v3-turbo (vérificateur de prise optionnel) ~1,6 Go réenregistre les lignes peu claires Cache Hugging Face Total environ 6 Go et 10-20 minutes. Proposez l'option plus légère :
SKIP_TAKE_CHECK=1ignore le vérificateur de prise (4,4 Go au total). Demandez où créer le projet (par défaut~/videos). -
Après son accord, copiez le dossier
template/qui se trouve à côté de ce SKILL.md dans le projet, y compris les fichiers dotfiles (cp -R <dossier compétence>/template/. <dest>/), puisgit init. -
Exécutez
tools/setup.shen arrière-plan et tenez l'utilisateur informé : dites sur quelle étape il se trouve (il imprime des lignes▶) et, pendant le gros téléchargement, à quel point il en est (du -shL ~/.cache/huggingface/hub/models--ResembleAI--chatterbox, objectif ~3 Go). Il est sûr de relancer : les étapes terminées sont sautées et les téléchargements interrompus reprennent. Si un téléchargement stagne (taille qui n'augmente pas pendant 5 minutes), arrêtez-le et relancez l'installation. Si elle échoue, lisez l'erreur, corrigez la cause (outil manquant, espace disque, réseau) et relancez ; ne contournez pas un modèle manquant. -
Prouvez que ça fonctionne :
tools/make-story.sh stories/fridge-drama FridgeDramacrée l'exemple de 33 s (trois légumes se disputent dans un frigo) en environ 4 minutes. Montrez à l'utilisateurout/FridgeDrama.mp4, puis demandez ce qu'il veut créer.
Les outils trouvent les modèles eux-mêmes (Chatterbox et le vérificateur de prise depuis le cache Hugging Face, les sous-titres depuis tools/models/), donc rien n'a besoin d'être configuré après l'installation. Un deuxième projet réutilise les poids mis en cache, donc son installation est beaucoup plus rapide.
1. Verrouiller le brief (demander uniquement si manquant)
| Champ | Défaut |
|---|---|
| Plateforme / format | Reel/Short : 1080×1920, 30 ips · YouTube : 1920×1080, 30 ips · Publication de fil d'actualité : 1080×1350 |
| Durée | Reel/Short : 15-45 s · YouTube : 3-10 min |
| Type | Histoire (des personnages parlent, donc utilisez §3B) ou Graphiques animés (texte, données, diagrammes, donc utilisez §3A) |
| Sujet + seul point à retenir | La seule chose que le spectateur doit retenir |
| Audio | Voix (Chatterbox), musique + SFX (tools/music.py), ou musique uniquement |
| Voix | Voix intégrée de Chatterbox, ou un clone de l'enregistrement de l'utilisateur (§3B). Ne clonez jamais quelqu'un sans son consentement. |
2. Écrire le script avant tout code
Budget de durée : la parole en anglais au rythme de Chatterbox tourne à environ 2,6 mots/s. Durée cible ≈ mots ÷ 2,6 + Σ pauses + outro. Vérifiez-la avant de générer. (Fridge Drama : 62 mots + 6,4 s de pauses + 3 s d'outro = 33 s.)
Règles de rythme pour le format court vertical :
- Accroche à l'écran et audible dès l'image 0. La première 1,5 s décide de la rétention, et l'image 0 est souvent la vignette, donc ne commencez jamais par une image vide ou en fondu.
- Chaque ligne ≤ 12 mots. Les sous-titres montrent ≤ 3 mots à la fois.
- Quelque chose bouge chaque seconde.
- Zone de sécurité pour 1080×1920 : rien d'important au-dessus de y=220 ou en dessous de y=1540 (interface utilisateur de la plateforme), et rien à droite de x≈940 en dessous de y≈1000 : les boutons like/comment/partager descendent le long du bord droit (
tools/qa.py --layoutéchoue). Placez un présentateur en bas à gauche. - Terminez par une récompense ou une chute, puis une carte d'appel à l'action de 2-3 s.
Modèle d'explication ("comment ça marche" et reels d'astuces de développement, 45-60 s, 120-160 mots) :
- Accroche (≤ 3 s) : un fait ou résultat surprenant vrai.
- "Voici comment ça fonctionne vraiment" : une ligne qui ouvre l'explication.
- 2-4 temps, chacun avec un nombre + une analogie ("une vidéo n'est que 30 photos par seconde, comme un flipbook").
- "Mais voici le hic" : le rebondissement, l'écueil ou l'erreur courante.
- Récompense en une ligne, puis un appel à l'action clair (sauvegarder, partager ou suivre).
Ensuite listez chaque affirmation factuelle avec un lien source sous le script, marquez tout ce que vous ne pouvez pas vérifier, et corrigez-le ou coupez-le avant de mettre en voix. Montrez la source à l'écran (petite, en bas de la carte) lorsqu'un nombre ou une affirmation apparaît.
Liste de contrôle de création pour les Shorts/Reels :
- Progression visible. Les vidéos étape par étape obtiennent
<StepCard steps={[{at: 0, title: "Téléchargez-le"}, …]} />(src/components/StepCard.tsx) : un badge "ÉTAPE 2/4" et une barre segmentée. - Sous-titres karaoké (style optionnel).
<Karaoke words={captions} keywords={["gratuit"]} style={{left: 60, right: 140, top: 1180}} />(src/components/Karaoke.tsx) : le bloc entier de 2 à 5 mots est à l'écran, les mots parlés sont pleins, les mots à venir sont gris, les mots-clés et mots accentués dans la couleur d'accent, pour que les spectateurs puissent lire à l'avance en lecture automatique muette.backgrounddonne un aspect carte légère ; passezqapour que la vérification de mise en page le voie. - Badge de série. Un marqueur d'épisode en haut à gauche ("PARTIE 2") rend les publications attrayantes à regarder en série.
- Montrez le contraste. Un avant/après ou "nous contre eux" fonctionne mieux en carte à deux colonnes qu'en discours.
- Les rebondissements battent les listes. "Tentative 1 échouée → tentative 2 échouée → ce qui a fonctionné" retient mieux l'attention qu'une liste de fonctionnalités.
- La chute avant l'appel à l'action. Une ligne humaine, puis l'appel à l'action.
- Ne promettez une récompense "commentez MOT-CLÉ et je vous enverrai un MP" que si quelque chose de réel (un guide, une invite, un dépôt) vous attend derrière.
Écrire pour la synthèse vocale :
- Ne commencez pas une ligne par "…" : Chatterbox improvise un mot de remplissage.
- Ne commencez pas une ligne par un nombre en toutes lettres seul ("Deux. Le visage" a donné "to the face"). Écrivez "Deuxièmement, …".
- Écrivez les nombres et noms étranges comme ils sont prononcés ("cinq virgule six", "X Z"), et mettez le vrai texte dans le champ
captionde la ligne. - Arrondissez les grands nombres ("plus de 600") ; la synthèse vocale déforme "646" et "87 000".
- Les mots courts dans les accroches deviennent flous ("Ce dépôt" a été entendu comme "The three"). Reformulez jusqu'à ce que le vérificateur de prise les entende correctement.
- N'ayez pas plusieurs voix qui crient le même mot court ensemble ; le mélange le brouille.
- La ponctuation dirige la livraison : "?" lève, "." atterrit, MAJUSCULES ajoutent de l'emphase.
3A. Vidéo en graphiques animés
- Copiez
src/compositions/_Template→src/compositions/<Nom>, avec un composant par type de temps (Hook, Point, Stat, List, CTA). - Calculez la durée à partir du script (somme des temps − transitions), comme le fait
getSampleIntroDuration. - Enregistrez-la dans
src/Root.tsxavecdefaultPropsen ligne. - Musique uniquement : écrivez un JSON de chronologie avec
totalMs,outroStartMsetevents, puis exécuteztools/music.py.
3B. Histoire avec voix (personnages + sous-titres + musique)
Créez stories/<slug>/script.json (copiez stories/fridge-drama/script.json) :
characters:color,exaggeration(0.3 calme → 0.9 dramatique), et optionnellementrefVoice: un WAV propre de 10-30 s danstools/voices/à cloner. Sans cela, la voix intégrée de Chatterbox est utilisée. Pour cloner la voix de l'utilisateur : il enregistre 60-90 s en parlant naturellement dans une pièce calme, puis coupe un morceau propre de 10-15 s sans musique ni écho (ffmpeg -ss <start> -t 12 -i note.m4a -af highpass=f=80,loudnorm=I=-18 -ar 24000 tools/voices/me.wav).lines:speaker,text,pauseAfter(s), optionnelevent+eventAt: "start"pour marquer les temps de l'histoire (porte qui s'ouvre, se cache…) que l'animation et la musique exploitent.- Direction vocale optionnelle par ligne :
emotion(calm|neutral|warm|excited|dramatic|whisper),pace(slow|normal|fast),emphasis(mots prononcés en MAJUSCULES et mis en évidence dans les sous-titres),pauseBefore(s)."pace": "slow"avec des pauses de 0,4 s rend chaque mot clair.
Exécutez ensuite une commande :
tools/make-story.sh stories/<slug> <CompositionId> # voix → sous-titres → musique/SFX → lint → rendu → master → QA
SKIP_VOICE=1 tools/make-story.sh … # itérer sur les visuels uniquement
SAMPLE=15 tools/make-story.sh … # rendre les 15 premières s pour validation, puis s'arrêter
| Outil | Sortie |
|---|---|
tools/voice.py | public/<slug>/lines/*.wav (mis en cache par texte + paramètres vocaux), public/<slug>/voice.wav, stories/<slug>/timeline.json (temporisations des lignes, événements, enveloppes de bouche par image). Avec le vérificateur de prise installé, Whisper écoute chaque phrase et réenregistre celles peu claires (VOICE_TAKES, par défaut 3). |
tools/captions.mjs | public/<slug>/captions.json (temporisations des mots de Whisper, orthographe du script), stories/<slug>/captions-report.json (taux d'erreur de mots et mots correspondants par ligne, les tronçons "remplis" que Whisper a manqués, matchRate global) |
tools/music.py | public/<slug>/music.wav (MIDI → FluidSynth, ajusté aux coupures), public/<slug>/sfx.wav |
tools/qa.py | stories/<slug>/qa/report.md : PASS / FIX / FAIL |
Construisez la composition à partir de timeline.json / captions.json (voir src/compositions/FridgeDrama/data.ts). Pilotez les bouches avec mouthOpen(), le regard vers le locuteur actif, les événements via timeline.events.*, et la durée depuis timeline.durationInFrames.
Tout changement de temporisation (texte ou pauses) nécessite de refaire les sous-titres. Les temps des sous-titres sont absolus, donc ils dérivent sinon. make-story.sh relance toujours les sous-titres.
4. Vérifier (toujours, avant de dire que c'est fait)
tools/make-story.sh se termine par tools/qa.py, qui se termine avec un code non nul en cas d'échec (FAIL). Il vérifie le fichier, l'intensité sonore (-14 ±1 LUFS, crête vraie ≤ -1), la précision des sous-titres, les coupures sur le rythme (≤ 120 ms), les étendues figées (≤ 3 s), la variété visuelle (plus longue séquence identique ≤ 5 s), et les sous-titres qui répètent le texte à l'écran. LAYOUT=<CompId> vérifie également les sous-titres par rapport aux zones mortes et au visage (la composition a besoin d'une propriété qa qui délimite les sous-titres #FF00FF et le visage #00FFFF). Lisez stories/<slug>/qa/report.md et corrigez chaque FAIL et FIX.
Vérifiez ensuite à l'œil :
npm run lint.- Toute ligne dans
stories/<slug>/captions-report.jsonavec un WER > 0,2 est probablement marmonnée : reformulez et régénérez (peu coûteux, grâce au cache). Les mots que Whisper a manqués sont placés sur la partie parlée de l'écart uniquement, les mots plus longs obtenant plus de temps, et listés sousfilled: écoutez ces endroits. En dessous de 70 % dematchRate, le script et l'audio diffèrent, donc refaites la voix avant de continuer. - Rendez des images fixes aux temps clés (accroche, chaque locuteur, chaque événement, outro), assemblez-les en une seule planche contact, et regardez-la :
Vérifiez la taille des personnages, la zone de sécurité, les superpositions couvrant les personnages, les résidus derrière l'outro, la synchronisation des sous-titres, et la taille du texte (puces ≥ 28 px, corps ≥ 54 px pour 1080 de large).npx remotion still <Id> out/stills/f<N>.png --frame=<N> --scale=0.4 ffmpeg -i a.png -i b.png … -filter_complex hstack=inputs=K out/stills/contact.png - Extrayez 4-5 images du MP4 final et regardez-les.
- Pour tout ce qui est important, demandez à un sous-agent frais de critiquer la planche contact sans contexte. Des yeux neufs trouvent des problèmes que le constructeur manque.
5. Livrer
Donnez à l'utilisateur le MP4, un titre, une légende, 3 à 5 hashtags et une vignette. Ne publiez et ne téléchargez jamais rien sans approbation explicite. Rappelez-leur de cocher l'étiquette "contenu modifié ou synthétique" de YouTube lorsqu'une voix clonée ou un visage IA est utilisé.
Règles qui font gagner des heures
- Un rendu à la fois. Plusieurs rendus Remotion en même temps ont surchargé la machine pendant des heures. Le pipeline passe déjà
--timeout=180000 --concurrency=2. - Ajoutez des paquets Remotion avec
npx remotion add <pkg>, jamais avecnpm isimple, pour que les versions restent appariées. - Intensité sonore : dialogue -16 LUFS, lit musical environ -24, master final -14 (deux passes, déjà dans
make-story.sh). Gardez la voix au moins 10 dB au-dessus de la musique. - Studio ne peut enregistrer les modifications de props que lorsque
defaultPropsest un objet en ligne dansRoot.tsx. - Écrivez les boucles zsh sur les lignes sous la forme
while read -r a b c; do …; done <<EOF, carfor x in "a b c"se brise.
Plus de leçons, et comment ajouter les vôtres : reference/lessons.md.
Coûts mesurés (M1 Max, 64 Go)
| Étape | Durée |
|---|---|
| Chargement du modèle Chatterbox | ~20 s par exécution (ignoré lorsque chaque ligne est en cache) |
| Génération de voix | première ligne ~55 s (préchauffage), puis ~3× le temps réel |
| Vérification de prise | ~20-30 s par phrase nécessitant une reprise |
| Sous-titres (Whisper small.en, WebGPU) | ~10 s pour 11 lignes |
| Musique + SFX | 2-5 s |
| Rendu 1080×1920, 33 s | ~97 s (~3 s par seconde de vidéo) |
| Pipeline complet | ~2 min avec voix en cache ; ~4 min à partir de zéro |
make-video est par TheNoumanDev, de zero-dollar-studio. C'est le pipeline derrière la chaîne YouTube @0x45.dev.