Communitygithub.com

liangruibupt/explainer-video-pipeline

Crée une vidéo explicative narrée (storyboard Opus, images codées, voix Polly, sous-titres, musique, effets sonores) avec des rendus interchangeables.

Qu'est-ce que explainer-video-pipeline ?

Cette compétence permet de générer automatiquement une vidéo explicative de 1 à 3 minutes en français, combinant voix off, sous-titres, musique et effets sonores. L'utilisateur fournit simplement un sujet, et le pipeline orchestre la rédaction d'un script via un modèle de langage (par défaut Claude Opus 5.5), la création d'un storyboard structuré en scènes, la génération d'images animées par du code (via Remotion, HTML/Canvas ou Manim), la synthèse vocale avec Amazon Polly ou gTTS, le sous-titrage mot à mot avec Whisper, et le mixage audio final. La sortie est un fichier MP4 prêt à être partagé. Le pipeline prend en charge plusieurs moteurs de rendu (Remotion, HTML, Manim, Seedance) et permet de remplacer chaque composant (modèle de langage, TTS, etc.) sans modifier le flux global. Il inclut des étapes de vérification intermédiaire (planche contact, contrôle des durées) pour garantir la qualité du résultat.

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/liangruibupt/explainer_video_platform/tree/HEAD/skills/explainer-video-pipeline

Demander à votre IA préférée

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

Documentation

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ètreValeur par défautAutres valeurs
topicobligatoire—
storyboard_modelclaude-opus-5.5 écrit le script, la narration et le storyboardtout ID de modèle de kiro-cli chat --list-models
video_engineopus-5.5 : claude-opus-5.5 écrit chaque scène sous forme de code qui dessine chaque imageun 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)
rendererremotion (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_modelseedance-1-5-pro-251215tout modèle Seedance activé dans le compte ModelArk de l'utilisateur
ttspolly, voix neurale Zhiyu, cmn-CN, us-east-1gtts (gratuit, sans clé, voix plus plate) ; toute autre voix/langue Polly
captionsactivé : horodatage Whisper par mot, incrusté sous forme de sous-titres mot par mot surlignésdésactivé
whisper_modelsmall (CPU, int8 ; environ 5 s pour 10 s de parole)base (plus rapide), medium (horodatage plus précis)
musicsynth (fond sonore libre de droits généré avec ffmpeg)none ; chemin vers un fichier musical possédé par l'utilisateur
sfxactivé : les événements listés dans scenes.json sont synthétisés et placés sur leurs imagesdésactivé : omettre sfx de chaque scène
languagenarration en chinois mandarintoute langue prise en charge par Polly et Whisper
size, fps1920×1080, 30 ips1080×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, sidechaincompress et ass/libass. Le ffmpeg fourni par Remotion ne les possède pas. Pointer FFMPEG / FFPROBE vers cette version.
  • Environnement Python venv (boto3 gTTS playwright faster-whisper pillow numpy), puis python -m playwright install chromium-headless-shell depuis ce venv. faster-whisper 1.2.x se casse avec PyAV 19 (unexpected keyword argument 'metadata_errors') : épingler av==16.1.0. Définir HF_HOME vers 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/Tex nécessitent une distribution LaTeX plus dvisvgm ; texlive-core de conda-forge sur aarch64 n'a pas latex.fmt, donc les formules échouent là. Écrire les formules avec Text() (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.

  1. 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érer package.json, tsconfig.json (resolveJsonModule: true), src/index.ts, src/Root.tsx à la main et npm i remotion @remotion/cli react react-dom.
  2. Script et storyboard (par storyboard_model). Écrire scenes.json : un objet par scène avec id, narration (la phrase parlée), visual (ce qui est à l'écran), optionnel manim (nom de la classe Scene) et optionnel sfx : [{"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.
  3. 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.
  4. La narration pilote le timing. Exécuter narrate.py scenes.json . --tts polly. Cela écrit durations.json (images par scène, à partir de la longueur réelle de la voix plus une marge), narration.wav et audio/sNN.mp3. Le code de chaque scène lit durations.json, donc chaque scène dure exactement aussi longtemps que sa phrase.
  5. Code de scène (par video_engine).
    • remotion : un composant React par scène, animé avec useCurrentFrame et interpolate/spring relatif au début de la scène.
    • html : un index.html avec window.seek = async (frame) => {...} qui dessine exactement cette image à partir du numéro d'image et du tableau durations.json. Pas de requestAnimationFrame, pas d'horloge réelle, pas de Math.random non ensemencé. Coller le tableau durations.json dans la page comme constante : une page ouverte en file:// ne peut pas fetch() un fichier local, et l'échec est silencieux. GSAP : timeline en pause + tl.seek(frame / fps). p5.js : noLoop() + redraw() dans seek.
    • manim : un scenes.py avec une classe Scene par scène. Lire la durée cible depuis os.environ["SCENE_SECONDS"] et terminer avec self.wait(max(0.04, secs - self.renderer.time)) ; dimensionner les animations longues avec secs aussi. Garder les 15 % inférieurs de l'image libres pour les sous-titres.
    • seedance : seedance_clips.py scenes.json . avec ARK_API_KEY définie ; télécharge clips/<id>.mp4 (les URL expirent après 24 h).
  6. 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.
  7. Son. Si une scène a sfx, exécuter sfx.py scenes.json .. Puis mix_bgm.py . --music <music> : il réduit la musique sous la voix, ajoute sfx.wav, écrit narration_bgm.wav et affiche les niveaux RMS. L'introduction uniquement musicale devrait être d'environ −20 à −30 dB ; −55 dB ou moins signifie qu'elle est inaudible.
  8. 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 écrit captions.ass (chaque caractère se surligne lorsqu'il est prononcé) et words.json (temps par caractère, utilisables pour l'accentuation à l'écran à l'étape 5).
  9. 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.
  10. 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 copy et 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.
  11. 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=1 que les fichiers sont bien présents.

Pièges

  • Ne jamais mettre de commentaires /* */ dans une chaîne d= 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. DashedVMobject n'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 strReplace en 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. html et manim l'évitent.

Skills associés