explainer-video-pipeline (auto-généré)
Quand l'utiliser
L'utilisateur souhaite une vidéo explicative narrée de 1 à 3 minutes sur un sujet (science, produit, technologie), livrée en un seul fichier MP4 avec voix off, sous-titres, musique et effets sonores.
Paramètres et valeurs par défaut
Ne demander que le sujet ; prendre toutes les autres valeurs par défaut sauf si l'utilisateur en précise une. Indiquer en une ligne les valeurs utilisées.
| Paramètre | Valeur par défaut | Autres valeurs |
|---|---|---|
topic | obligatoire | — |
storyboard_model | claude-opus-5.5 écrit le script, la narration et le storyboard | tout ID de modèle de kiro-cli chat --list-models |
video_engine | opus-5.5 : claude-opus-5.5 écrit chaque scène sous forme de code qui dessine chaque image | un autre modèle de code, ex. claude-sonnet-5.5 ; seedance (API BytePlus ModelArk, nécessite ARK_API_KEY) ; hybrid (clips Seedance dans des scènes codées) |
renderer | remotion (React/SVG ; Remotion pilote un Chromium sans tête image par image) | html (page Canvas 2D / SVG / GSAP / p5.js, capturée avec Playwright) ; manim (scènes Manim Community ; idéal pour géométrie, graphiques, vecteurs et dérivations pas à pas) |
seedance_model | seedance-1-5-pro-251215 | tout modèle Seedance activé dans le compte ModelArk de l'utilisateur |
tts | polly, voix neurale Zhiyu, cmn-CN, us-east-1 | gtts (gratuit, sans clé, voix plus plate) ; toute autre voix/langue Polly |
captions | activé : horodatage Whisper par mot, incrusté sous forme de sous-titres mot par mot surlignés | désactivé |
whisper_model | small (CPU, int8 ; environ 5 s pour 10 s de parole) | base (plus rapide), medium (horodatage plus précis) |
music | synth (fond sonore libre de droits généré avec ffmpeg) | none ; chemin vers un fichier musical possédé par l'utilisateur |
sfx | activé : les événements listés dans scenes.json sont synthétisés et placés sur leurs images | désactivé : omettre sfx de chaque scène |
language | narration en chinois mandarin | toute langue prise en charge par Polly et Whisper |
size, fps | 1920×1080, 30 ips | 1080×1920 pour le format vertical |
« Créé avec Opus 5.5 » signifie qu'Opus 5.5 est l'auteur : il écrit le script et le code de dessin, et un moteur de rendu transforme ce code en pixels. Aucun modèle de texte ne produit directement la vidéo ; seul Seedance le fait. Le mentionner une fois dans la première réponse. Si la session utilise déjà claude-opus-5.5, effectuer l'écriture soi-même. Sinon, lancer une tâche avec model="claude-opus-5.5" et keep=true pour le storyboard (étape 2) et continuer le même déroulement avec spawn_continue pour le code de scène (étape 5), puis examiner sa sortie soi-même.
Configuration (une fois par machine)
Conserver les outils dans un répertoire de cache stable (ex. ~/.cache/explainer-video/), jamais dans $KIROCREW_SCRATCH, qui est récupéré entre les sessions.
- ffmpeg : une version statique complète avec
aevalsrc,anoisesrc,tremolo,sidechaincompressetass/libass. Le ffmpeg fourni par Remotion ne les possède pas. PointerFFMPEG/FFPROBEvers cette version. - Environnement Python venv (
boto3 gTTS playwright faster-whisper pillow numpy), puispython -m playwright install chromium-headless-shelldepuis ce venv. faster-whisper 1.2.x se casse avec PyAV 19 (unexpected keyword argument 'metadata_errors') : épinglerav==16.1.0. DéfinirHF_HOMEvers le répertoire de cache pour que le modèle Whisper soit téléchargé une seule fois. - Manim (uniquement pour
renderer=manim) : pip ne peut pas le construire sur aarch64 (pas de wheels pour pycairo, manimpango, moderngl). Sans root, utiliser micromamba :micromamba create -p <cache>/manim-env -c conda-forge python=3.12 manim.Text()avec une police CJK fonctionne.MathTex/Texnécessitent une distribution LaTeX plusdvisvgm;texlive-corede conda-forge sur aarch64 n'a paslatex.fmt, donc les formules échouent là. Écrire les formules avecText()(Unicode : F = m·a, x², √, →), ou installer un TeX Live système là où l'utilisateur le peut.
Étapes
Les aides se trouvent dans le dossier scripts/ de cette compétence.
- Projet. Créer un dossier de projet dans un dépôt git sous l'espace de travail de l'utilisateur. Pour
renderer=remotion, générerpackage.json,tsconfig.json(resolveJsonModule: true),src/index.ts,src/Root.tsxà la main etnpm i remotion @remotion/cli react react-dom. - Script et storyboard (par
storyboard_model). Écrirescenes.json: un objet par scène avecid,narration(la phrase parlée),visual(ce qui est à l'écran), optionnelmanim(nom de la classe Scene) et optionnelsfx:[{"at": IMAGE_DANS_SCENE, "kind": "whoosh|hiss|pop|rise|thud|CHEMIN"}]. Utiliser 6 à 10 scènes, une idée chacune, avec une scène titre et un carton de fin. Vérifier les faits avec une recherche web et citer les sources dans le README. - Images de référence. Quand la vidéo montre un objet réel, demander ou trouver une photo claire et la conserver dans
ref/. Ne jamais dessiner la forme d'un objet réel de mémoire : exécuter une détection de contours sur la photo, mesurer les points clés, et générer les formes à partir de ces points avec un petit script conservé dans le dépôt. - La narration pilote le timing. Exécuter
narrate.py scenes.json . --tts polly. Cela écritdurations.json(images par scène, à partir de la longueur réelle de la voix plus une marge),narration.wavetaudio/sNN.mp3. Le code de chaque scène litdurations.json, donc chaque scène dure exactement aussi longtemps que sa phrase. - Code de scène (par
video_engine).remotion: un composant React par scène, animé avecuseCurrentFrameetinterpolate/springrelatif au début de la scène.html: unindex.htmlavecwindow.seek = async (frame) => {...}qui dessine exactement cette image à partir du numéro d'image et du tableaudurations.json. Pas derequestAnimationFrame, pas d'horloge réelle, pas deMath.randomnon ensemencé. Coller le tableaudurations.jsondans la page comme constante : une page ouverte enfile://ne peut pasfetch()un fichier local, et l'échec est silencieux. GSAP : timeline en pause +tl.seek(frame / fps). p5.js :noLoop()+redraw()dansseek.manim: unscenes.pyavec une classe Scene par scène. Lire la durée cible depuisos.environ["SCENE_SECONDS"]et terminer avecself.wait(max(0.04, secs - self.renderer.time)); dimensionner les animations longues avecsecsaussi. Garder les 15 % inférieurs de l'image libres pour les sous-titres.seedance:seedance_clips.py scenes.json .avecARK_API_KEYdéfinie ; téléchargeclips/<id>.mp4(les URL expirent après 24 h).
- Vérifier les images fixes avant le rendu complet. Rendre 4 à 6 images, une par scène clé, les combiner en une seule planche contact réduite, et examiner cette image unique. Pour une vérification indépendante, lancer un nouveau réviseur avec seulement la planche et
scenes.json. - Son. Si une scène a
sfx, exécutersfx.py scenes.json .. Puismix_bgm.py . --music <music>: il réduit la musique sous la voix, ajoutesfx.wav, écritnarration_bgm.wavet affiche les niveaux RMS. L'introduction uniquement musicale devrait être d'environ −20 à −30 dB ; −55 dB ou moins signifie qu'elle est inaudible. - Sous-titres.
captions.py scenes.json . --size <LxH>transcrit chaque ligne avec les horodatages de mots de faster-whisper et les fait correspondre aux caractères du script, car Whisper se méprend sur les homophones (il a entendu 气体 comme 漆体). Il écritcaptions.ass(chaque caractère se surligne lorsqu'il est prononcé) etwords.json(temps par caractère, utilisables pour l'accentuation à l'écran à l'étape 5). - Rendu (image silencieuse).
remotion:npx remotion render src/index.ts <Comp> out/silent.mp4.html:capture_html.py index.html out/silent.mp4 --frames <somme des durations.json>.manim:manim_scenes.py scenes.py . --manim <manim-env>/bin/manim --quality h. Il rend chaque classe et ajoute ou rogne pour atteindre exactement son nombre d'images.
- Composition avec FFmpeg. Avec sous-titres :
ffmpeg -i silent.mp4 -i narration_bgm.wav -vf "ass=captions.ass" -c:v libx264 -crf 18 -pix_fmt yuv420p -c:a aac -b:a 192k -shortest final.mp4(sans sous-titres, utiliser-c:v copyet supprimer-vf). Vérifier que les durées vidéo et audio correspondent à environ 0,1 s près, puis extraire 4 à 5 images du MP4 final et les examiner, dont une au milieu d'une phrase pour voir le surlignage du sous-titre. - Livraison. Commiter dans une branche de fonctionnalité, ouvrir une PR, et après fusion, confirmer avec
gh api repos/<o>/<r>/git/trees/<base>?recursive=1que les fichiers sont bien présents.
Pièges
- Ne jamais mettre de commentaires
/* */dans une chaîned=de chemin SVG ; Chromium arrête l'analyse au/. Utiliser des couleurs hexadécimales à 6 chiffres. - Un code avec des numéros d'image absolus codés en dur peut placer un point culminant après la fin de sa scène.
- Dans Manim, positionner les étiquettes et les flèches après que l'objet a bougé (ou les attacher avec
always_redraw/add_updater), sinon elles restent à l'ancien emplacement.DashedVMobjectn'a pas de points propres : prendre les positions à partir d'une forme simple. - Un Playwright installé via pip peut vouloir une version plus récente de Chromium que celle en cache.
- Ne pas éditer un même fichier avec plusieurs appels
strReplaceen parallèle ; les modifications sont perdues. Ne pas écrire de code via des heredocs shell ; les garde-fous peuvent les bloquer. - Les modèles Seedance 2.x nécessitent une activation du compte et rejettent les images de référence contenant de vrais visages humains. Les clips Seedance 1.5 pro durent 4 à 12 s.
- Licence Remotion : gratuite pour les particuliers et les entreprises de 3 personnes maximum ; les entreprises plus grandes ont besoin d'une licence payante.
htmletmaniml'évitent.