De bout en bout : (première exécution : demander à l'utilisateur ses handles/watermark/CTA/voix) → sujet → recherche → brouillon → approbation → voix off → timing → scènes Remotion → rendu → export Reels → QA → couvertures + légendes → livraison.
C'est la version plus complète de vertical-reels-video-studio (de base). La configuration de marque se trouve dans brand.config.json (lu par src/brand.ts et passé aux compositions via la prop brand).
0a. Première exécution : demander à l'utilisateur SES paramètres (ne jamais utiliser les valeurs par défaut)
Avant la première vidéo, si brand.config.json est manquant, contient "configured": false, ou contient encore @votrehandle,
demandez à l'utilisateur (une question à la fois) et enregistrez les réponses dans brand.config.json :
- Handles sociaux : Instagram, Threads, TikTok, X (ceux qu'il utilise).
- Texte du watermark (exactement tel qu'il doit apparaître, ex.
@votrehandleou@ig / @x) et position (bottom-center,bottom-left,top-left,top-right). - CTA texte et le handle qu'il mentionne.
- Voix : son identifiant de voix ElevenLabs + modèle + langue, ou "J'enregistrerai ma propre voix". La clé API n'est demandée que comme secret
ELEVENLABS_API_KEY. - Langue et ton ; comment la voix doit prononcer son nom/handle.
Puis définissez "configured": true. N'inventez jamais un handle, ne réutilisez jamais celui de quelqu'un d'autre (y compris l'auteur de ce kit), et ne rendez jamais un watermark qui dit encore @votrehandle.
0b. Configuration de marque (brand.config.json, rempli à partir des réponses de l'utilisateur)
| Clé | Espace réservé | Remarques |
|---|---|---|
| Handles | {{IG_HANDLE}}, {{THREADS_HANDLE}}, {{TIKTOK_HANDLE}}, {{X_HANDLE}} | handles.*, ceux de l'utilisateur |
| Watermark | {{WATERMARK}} + position | watermark.text / watermark.position, texte exact donné par l'utilisateur ; jamais codé en dur dans les scènes |
| Langue / ton | {{LANGUAGE}}, {{TONE}} | ex. indonésien décontracté gua/lu, emoji épars |
| Nom prononcé | {{SPOKEN_NAME}} | Comment la voix dit votre handle (ex. "Jane Doe" pour @janedoe_). Les légendes affichent toujours le vrai handle |
| Avertissement | {{DISCLAIMER}} | Pour les sujets financiers, ex. "Éducation, pas un conseil financier" |
| Voix | {{VOICE_ID}}, {{TTS_MODEL}}, {{LANGUAGE_CODE}} | voice.*, le choix de l'utilisateur (ou son propre enregistrement) |
| Clé API | env ELEVENLABS_API_KEY | Ne jamais l'imprimer, la journaliser ou la commiter |
| CTA | {{CTA}}, {{CTA_HANDLE}} | cta.text / cta.handle, demandé à l'utilisateur (ex. "Suivez {{CTA_HANDLE}} pour plus", "Commentez TUTORIEL") |
| Règles strictes | {{HARD_RULES}} | Marques à ne jamais moquer, noms à flouter, mots à ne jamais dire |
| Périphérique de rendu | {{RENDER_DEVICE}} | Machine GPU ou CPU. Toujours indiquer lequel a été réellement utilisé |
1. Recherche et brouillon (pas d'audio, pas de rendu)
- Vérifiez chaque affirmation par des sources primaires : documents officiels/PR, propre article de l'auteur, registres, captures d'écran datées. Les posts de dirigeants comptent comme déclarations officielles. Étiquetez les estimations (
ESTIMATION · pas officielle) et les allégations (ALLÉGUÉ). Abandonnez ce que vous ne pouvez pas vérifier plutôt que de l'adoucir. - Une histoire par vidéo, mots du quotidien, rythme lent. Les noms de produits durs vont à l'écran, pas dans la voix off.
- Proposez 2 à 4 options d'accroche (H1, H2,…) : une question pourquoi/comment ou un contraste audacieux. Laissez l'utilisateur choisir.
- Tableau minuté :
temps | à l'écran | VO. Visez 45–65 s, max dur 90 s (visez ≤ 88 s pour qu'une révision tienne encore). - Écrivez
factcheck.md(affirmation → source → statut) etsources.md. - Envoyez le brouillon et attendez l'approbation. "Ne pas rendre" de l'utilisateur est définitif jusqu'à ce qu'il dise allez-y.
2. Voix off (ElevenLabs)
- Deux scripts :
script-display.txt(ce que les légendes affichent) etscript-tts.txt(épelé pour la voix). Conservez une correspondance display↔TTS. - Prononciation (voir
docs/VOICEOVER.md) :A.I.avec des points pour que cela sonne anglais ; tickers lettre par lettre dans une VO non anglaise (ETH →E, T, H) ; nombres en toutes lettres ; termes anglais en orthographe anglaise simple (pas de ré-orthographe avec traits d'union) ; une virgule après un /t/ final avant une voyelle ; noms de marques ré-orthographiés seulement si les tests prouvent que cela aide. - Post-traitement
atempo1.05 (1.1 pour un contenu rapide). Loudness −14 LUFS intégré, ≤ −1 dBTP. - Pas de lignes en double. Si une ligne répète l'accroche ou un élément antérieur, coupez-la ou reformulez-la.
- Vérifiez d'abord le quota de caractères. Re-voix uniquement les lignes défaillantes (passez
previous_textpour la continuité).
3. Timing
- Horodatages des mots à partir de l'alignement TTS (diviser par le facteur de tempo) ou faster-whisper →
timing.json{duration, phrases:[{s,e,words:[{w,s,e}]}], scenes:[{id,start}]}(scripts/build-timing.py). - Fusionnez les tokens ré-orthographiés vers les mots d'affichage (
A.I.→AI,E, T, H→ETH) ou les légendes commencent en retard. - Les scènes se basent sur les mots parlés :
wt(scene, word)→ image où ce mot commence.
4. Style de mouvement (Remotion, 1080×1920, 30 fps)
Aspect : fond #0A1016, crème #EFE6D2, ambre #FFB000, rouge #E2553F, vert #7BD88F. Polices via @remotion/google-fonts : Big Shoulders 800 (titres), Plus Jakarta Sans (corps/légendes), JetBrains Mono (pastilles/code).
Disposition : contenu important y 200–1500. Groupe de pied de page : légendes karaoké ~y 1310–1353, watermark (si l'utilisateur a choisi bas) ~y 1427–1446, progression ~y 1474, tout à gauche de x 960 (Reels dessine ses boutons à droite).
Pas d'images vides : l'accroche est lisible à l'image 0 ; l'ouverture et la fin sont aussi pleines que le milieu (une image hero, le présentateur, une pastille), jamais une seule ligne sur un fond vierge.
Aides d'assouplissement (src/motion/ease.ts) :
const clamp01=(x:number)=>Math.max(0,Math.min(1,x));
const P=(t:number,a:number,b:number)=>clamp01((t-a)/(b-a));
const eOut=(x:number)=>1-Math.pow(1-x,3);
const eIn=(x:number)=>x*x*x;
const backOut=(x:number,s=1.70158)=>1+(s+1)*Math.pow(x-1,3)+s*Math.pow(x-1,2);
const sec=(f:number,at:number)=>(f-at)/30;
const ap=(f:number,at:number,d=0.3)=>eOut(P(sec(f,at),0,d));
const pop=(f:number,at:number)=>Math.max(0,backOut(P(sec(f,at),0,0.35),2.2));
const punch=(f:number,at:number)=>{const t=sec(f,at);if(t<0)return 1;return 1+0.12*eOut(P(t,0,0.2))-0.06*eOut(P(t,0.2,2.5));};
const shake=(f:number,at:number)=>{const t=sec(f,at);return t<0||t>0.4?0:14*Math.exp(-t*10)*Math.sin(t*70);};
Mouvements : type cinétique (le mot atterrit sur son temps VO, scale(0.6+0.4*pop), ±4° se stabilisant sur 0,25 s, mots accentués plus gros + ambre/rouge), coup de zoom sur les images clés, révélateur en cercle, transitions zoom-through (échelle 1→4,2 sur ~9 images, scène suivante 1,3→1), tampons pivotés et pastilles mono, boîtes de surbrillance rouges sur les captures d'écran, compteur d'étapes, légendes karaoké (mot actuel ambre + 1,08×), pop CTA avec secousse, SFX whoosh/pop sous la VO. Environ un temps fort toutes les 1,5 à 3 s.
Clips vidéo : enveloppez chaque <OffthreadVideo> dans une <Sequence from={at}> et définissez startFrom par rapport à celui-ci ; sinon le clip se bloque sur sa dernière image et semble figé. Bouclez les clips courts pour les longs temps. Les clips commencent sur la première image utilisable.
Transitions audio : lorsqu'une ouverture utilise de l'audio en direct (une chanson, un clip) avant la narration, fondez-la en silence et laissez ~0,3–0,5 s (une transition flash/whoosh) avant le premier mot de VO pour qu'il ne soit jamais masqué.
Présentateur optionnel (mascotte) avec synchronisation labiale
- Une identité de personnage cohérente dans chaque vidéo. Calques séparés : corps (bouche fermée repeinte), bras sur un pivot d'épaule sous le bord du manteau, une cape d'épaule statique, sprites de bouche
fermée/à moitié/ouverte/large/ronde. - Pilotez la bouche à partir du wav de la VO, pas d'une boucle :
scripts/build-mouth-track.py→ états par image (fermé en silence et en tenue finale, maintien minimum de 2 images). Limitez le bras à la plage du rig ; un simple balancement de l'image entière ne suffit pas. - Montez le présentateur seulement lorsqu'il est à l'écran ; les couvertures utilisent le corps statique bouche fermée.
5. Rendu
- Préférez une machine GPU si vous en avez une (Remotion
--hardware-acceleration, une configuration sansencodingBufferSize/encodingMaxRate, qui cassent le NVENC requis) ; reculez vers CPU seulement si autorisé. Dites toujours quel périphérique a rendu. - Rendu brut :
yuv420p+bt709dansremotion.config.ts, puis la passe Reels.
6. Export compatible Reels (scripts/reels-export.sh, détails dans docs/REELS_SAFE_EXPORT.md)
1080×1920 SAR 1, H.264 High level 4.1, yuv420p gamme TV, balises BT.709, CFR 30, GOP 60 fermé, 10 Mbps (min 8, max 12), deux passes loudnorm −14 LUFS / −1.5 dBTP, AAC 192k 48 kHz stéréo, +faststart, < 90 s. Aussi un petit aperçu < 40 Mo (scripts/make-preview.sh).
7. QA (obligatoire, avant livraison)
- Chuchotez le MP4 final (
scripts/whisper-check.py) : mauvaises prononciations, bégaiements, sons parasites, lignes en double, premier mot de chaque scène audible. - Planche contact à chaque limite de scène (
scripts/contact-sheet.sh) : problèmes, chevauchements, texte coupé, zone de sécurité, clips figés, ouverture/fin vide, watermark présent, correspondant àbrand.config.jsonet épelé exactement. scripts/qa-check.sh: codec/profil/niveau, pix_fmt, gamme, balises couleur, CFR, AAC 48k, moov avant mdat, durée < 90 s, −14 LUFS.- Corrigez et re-rendez. Gardez la version précédente lorsque vous révisez.
8. Toujours livrer avec la vidéo
- Légendes pour IG (accroche, corps, CTA, hashtags légers), Threads (plus court, pas de hashtags), TikTok, plus un
.srt. - Quatre couvertures A–D : 1080×1920 + grille 1080×1350, texte clé dans le centre 1080×1080 ; une accroche, une photo principale, max 2–3 cartes numérotées ; planche contact + laissez l'utilisateur choisir.
- Crédits des sources et le fichier de vérification des faits.
- Une ligne dans
videos-log.md: titre, fichiers, durée, loudness, périphérique, sources, statut "non posté".
Règles
- Ne postez jamais, envoyez jamais en DM, téléchargez jamais ou n'achetez jamais. Livrez des fichiers.
- Aucun fait, star, prix ou résultat fabriqué. Créditez les auteurs open source à l'écran.
- Photos, logos et clips réels uniquement ; pas de visages générés par IA de vraies personnes. Marquez les maquettes
illustration. - Utilisez des médias pour lesquels vous avez les droits ; dites à l'utilisateur quand la musique ou les clips sont protégés par le droit d'auteur (risque de mutisme/réclamation).
- Pas de secrets dans les fichiers. Posez toute question en dernier, dans son propre message.