Communitygithub.com

animated-voiceover-ad

Annonce vidéo verticale (9:16, Reel/Story pour publicité Meta) entièrement codée en Remotion sur la narration du propriétaire : texte cinétique mot par mot, téléphone avec notifications, compteur de résultats, tampons, carte d’offre et CTA, avec musique et effets. À lancer sur demande comme « annonce animée », « vidéo animée pour pub », « annonce avec ma voix », « annonce sans me filmer », ou en envoyant un enregistrement vocal. Idéal pour les retouches : « la musique est trop forte », « cette seconde est ennuyeuse », « le texte n’est pas synchronisé », « fais une autre version ».

Qu'est-ce que animated-voiceover-ad ?

Cette compétence permet de créer des publicités vidéo verticales animées (9:16, format Reel/Story Meta) entièrement générées par code en utilisant Remotion, synchronisées sur la narration enregistrée du propriétaire. Elle fonctionne en analysant l’audio avec Whisper pour récupérer les timings de chaque mot, puis en assemblant des éléments visuels comme du texte cinétique, des notifications téléphoniques, des compteurs de résultats, des tampons et des cartes d’offre avec CTA, le tout accompagné de musique et d’effets sonores. La compétence est conçue pour les utilisateurs qui souhaitent une annonce professionnelle sans se filmer, simplement en fournissant un enregistrement vocal. Elle prend en charge les ajustements précis (volume, timing, variations) et génère automatiquement plusieurs versions avec différentes musiques pour les tests A/B. Idéale pour les agents IA comme Claude Code, Cursor ou Codex, elle offre un pipeline complet : nettoyage audio, transcription, montage scène par scène, rendu et correction.

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/chenmorr/animated-voiceover-ad/tree/main

Demander à votre IA préférée

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

Documentation

Annonce animée sur narration

Le principe

Ce qu’on entend = ce qu’on voit. La narration dicte les timings. On enregistre d’abord, Whisper donne le temps de chaque mot, puis tout texte, scène, notification et effet se cale sur un mot. Dans le code, pas de numéros de frames : on écrit at: 'clients' et le temps est extrait de public/words.json. Nouvel enregistrement = npm run vo, et la vidéo se synchronise toute seule.

Aucune seconde à l’écran ne reste statique. Une seconde sans mouvement = le spectateur défile.

Règles d’or

  1. Tu n’entends pas. Le propriétaire est la seule oreille. Toute vérification audio de ta part est numérique (silencedetect, ffprobe, retranscription). Il est interdit d’écrire « l’audio est correct » sans citer la sortie.
  2. D’abord nettoyer les silences, ensuite retranscrire. Whisper se trompe sur les timings près des silences. prep-vo.sh fait les deux dans le bon ordre.
  3. Après un changement audio, relancer npm run vo. Sans ça, toute la synchronisation se décale.
  4. La vidéo se termine quand la narration se termine + 8 frames (DURATION dans time.ts). render-all.sh imprime la durée de chaque fichier par rapport à la narration. S’ils diffèrent, quelque chose a été coupé.
  5. Texte uniquement entre y=260 et y=1570. Au-dessus et en dessous, Instagram couvre. validate() stoppe le rendu avec une explication si un texte sort de cette zone ou dépasse 1000px de large.
  6. Les effets sont en dessous de la voix. Fixés dans Ad.tsx : narration 1.15, musique 0.22, chaque effet multiplié par SFX = 0.38. « Les effets sont trop forts » = changer un seul nombre.
  7. stills avant mp4. npm run check rend 10 frames dans out/stills. Les examiner toutes (lire les PNG) avant le rendu complet.
  8. Contenu authentique uniquement. Chiffres, paiements et messages de clients : ce qui s’est vraiment passé. On peut masquer les noms, mais il est interdit d’inventer des résultats. À la fois à cause de la politique Meta et parce que les gens sentent le faux.
  9. Hébreu : Les polices (Rubik, Heebo, variables, OFL) sont déjà dans le template et chargées avec delayRender. La racine est en direction: rtl. Les chiffres dans une étiquette reçoivent direction: ltr.

Première installation du projet

cp -R ~/.claude/skills/animated-voiceover-ad/template ~/ads/<nom-de-lannonce>
cd ~/ads/<nom-de-lannonce>
npm install
npm run setup          # Effets et musique depuis Mixkit

Il faut : Node 18+, ffmpeg, whisper-cli (brew install ffmpeg whisper-cpp) et le modèle whisper dans ~/.whisper/models/ggml-large-v3-turbo.bin (s’il manque, words.mjs affiche une commande de téléchargement).

Le pipeline

ÉtapeCe qu’on fait
1. ScriptSelon references/script-formula.md. Chaque phrase est pré-mappée à une scène. On montre au propriétaire avant qu’il enregistre.
2. EnregistrementSur téléphone ou QuickTime, un seul fichier. Erreur ? On s’arrête une seconde et on recommence la phrase. Ensuite on supprime la mauvaise prise (voir references/audio.md).
3. Nettoyage et transcriptionnpm run vo -- recording.m4a. Affiche tous les mots avec leurs timings. On montre la transcription au propriétaire et on corrige les mots mal retranscrits par Whisper directement dans public/words.json (uniquement le champ w).
4. Mise en scèneOn modifie uniquement src/Ad.tsx : KTS (texte cinétique), notifications, SCENES. Chaque temps = un mot, ['encore', 2] pour la deuxième occurrence. Détail des composants dans references/scenes.md.
5. Vérificationnpm run check (tsc + stills). On examine chaque still.
6. Rendunpm run render. Chaque musique dans MUSICS (Root.tsx) = fichier séparé dans out/, pour test A/B.
7. CorrectionsChaque remarque du propriétaire = une modification unique : un mot différent dans at, volume, until. On ne réécrit pas une scène entièrement.

Versions pour la pub

  • Musique : Déjà intégrée, 3 compositions.
  • Accroches différentes : Les 3 premières secondes sont cruciales. On enregistre 2-3 accroches différentes en fichiers séparés, on concatène chacune avec le corps via ffmpeg concat, on lance npm run vo sur chaque concaténation et on rend dans un dossier séparé. Tout Ad.tsx reste identique tant que les mots du corps sont les mêmes.
  • Sous-titres complets : CAPTIONS = true dans Ad.tsx. Une seule ligne, coupée selon la ponctuation. Utile car la plupart des vues sur pub se font sans son.

Problèmes connus

ProblèmeSolution
Le mot "X" n’a pas été trouvé dans la narrationLe message suggère des mots proches. En hébreu, Whisper colle ou sépare les préfixes (ו/ה/ל/ב). On utilise le mot tel qu’il apparaît dans words.json.
Le rendu montre du code ancienAncien bundle dans $TMPDIR/remotion-webpack-bundle-*. render-all.sh le supprime.
TypeScript 7 installéRemotion nécessite [email protected].
delayRender se bloque--timeout=180000 (déjà dans render-all).
Le tampon rétrécit avant d’atterrirovershootClamping: true sur son spring (déjà présent).
Mots collés après nettoyage des silencesAugmenter stop_duration dans prep-vo.sh à 0.35.
Seconde « ennuyeuse »Ajouter une ligne de KT, une notification ou un effet sur ce mot. Aucune seconde sans événement.

La démo dans le template

Le template est livré avec une narration de démonstration (voix TTS, public/vo.wav + public/words.json) et un Ad.tsx synchronisé, pour voir tout fonctionner avant d’enregistrer : npm install && npm run setup && npm run check. Pour une vraie annonce : npm run vo -- recording.m4a écrase les deux, puis on réécrit Ad.tsx selon le script.

Skills associés