Montage motion graphics + interface d'édition
Parle à l'utilisateur dans sa langue. Écris les sous-titres dans les mots exacts de l'orateur (ne paraphrase jamais).
Chemins : ME = dossier de cette compétence, W = un dossier projet par vidéo. Tous les scripts sont en bash/python/node ; scripts/env.sh trouve ffmpeg, node, python, Chrome et le moteur embarqué (engine/). Première fois : voir README.md → Installation (npm install dans le dossier de la compétence, pip install -r requirements.txt).
Règles (non négociables)
- Logos officiels uniquement pour toute marque mentionnée — jamais d'icône redessinée « inspirée ». Récupère-le depuis le site web de la marque (
capture_site.js) ou demande à l'utilisateur. - Charte graphique : pour un client, lis les couleurs, polices et logo depuis son site web (
captures/info.json) et écris la palette en haut departs/top.js. Pour les propres vidéos de l'utilisateur, demande sa charte une fois et conserve-la danstheme.json+top.js. - Captures du site web : capture le site du client (pages complètes, desktop + mobile) et utilise-les dans les panneaux (navigateur défilant, illustrations officielles recadrées). Les bannières de cookies sont cachées, jamais acceptées. Les écrans de produits connectés ne sont pas accessibles : dis-le et propose d'intégrer des captures d'écran fournies par l'utilisateur.
- Rythme : plein écran ↔ panneaux (zoom ARRIÈRE dedans, zoom AVANT dehors), punch-ins sur les mots forts (~1 toutes les 2-3 s), exactement un moment signature (logo / nom reveal), musique de fond atténuée sous la voix, effets sonores (whoosh à chaque zoom, pops, clics, frappes, impact sur le reveal), flash lumineux sur les coupures.
- Annonces publicitaires : rien d'important dans les 14 % supérieurs (y < 270) ni en dessous de y ≈ 1250 (UI Reels/TikTok) ; sous-titres relevés (
CAPDY) ; pas de sous-titres dans les panneaux (le panneau affiche les mots comme titres) ; carte de fin = logo de la marque + URL + les mots de l'orateur ; aucune affirmation ou chiffre inventé. - Sous-titres jamais sur le visage. Langues LTR →
"sens": "ltr"dansprojet.json(la construction corrige l'ordre des mots) ; RTL (arabe) →"rtl". Nom de la marque sous forme de pilule (fx: "pill", couleurs dansprojet.json → pill). - Mixage : l'utilisateur règle la voix / musique / effets dans l'éditeur. Valeurs par défaut : voix 100 %, musique 46 %, effets 36 %. Normalise toujours le volume à -14 LUFS.
- Chaque animation est un ÉLÉMENT du registre (voir ci-dessous) pour que l'utilisateur puisse la sélectionner, décaler, masquer et commenter. Aucune animation en dehors du registre.
- Ancres : chaque
wS(card, word)doit pointer sur le mot que l'animation illustre — exécutescripts/ancres.pyet lis le tableau ; ne devine jamais d'indice.
Workflow
- Préparer :
bash $ME/scripts/preparer.sh <video> <W> <lang> "<Whisper prompt: noms propres>"→ source copiée, recadrage plein écran, images clés, coupes probables, transcription mot à mot. Ensuite le détourage de la personne sur fond (~1 s/image ; ne lance pas Whisper en même temps — RAM) :python $ME/engine/mask.py u2net_human_seg <W> && python $ME/engine/make_head.py <W>. - Client (le cas échéant) :
node $ME/scripts/capture_site.js <url> <W>→captures/,assets/logo-*.png, couleurs/polices. Regarde les captures ; recadre les visuels utiles dansW/assets/(illustrations, une longue page pour un navigateur défilant). - Sous-titres : écris
W/cartes.json(mots exacts + timings Whisper ; cartes de 2 à 5 mots ;hot,fx) →python $ME/scripts/cartes.py <W>. Modèle :templates/cartes.EXAMPLE.json. - Plan de montage : divise le script en beats (accroche, problème, produit, preuve, CTA…), choisis pour chacun : plein écran ou panneau, quel objet concret montrer, un moment signature, des sons. Écris
W/plan-montage.md(modèletemplates/plan.EXAMPLE.md) et montre-le brièvement à l'utilisateur avant d'animer. - projet.json (modèle
templates/projet.EXAMPLE.json) :nom,titre,langue,sens,outro,vol,musique_gain,pill,coupes,cadrage(plans qui vont dans un panneau → fenêtre de mesure),cadrage_forcesi le masque attrape l'arrière-plan. Ensuitepython $ME/scripts/framing.py <W>. - Scènes dans
W/parts/:top.js←templates/top.EXAMPLE.js(palette,CUTS/SEGB,PANELS, zoomsZP,CAPDY) ;primitives.js←templates/primitives.js;gfx.js←templates/gfx.EXAMPLE.js(SCENES_ED, unEL(...)par animation, calques, carte de fin, polices). - Sons :
W/sons.json(modèletemplates/sons.EXAMPLE.json) :musique{bpm, intro_filtree, coupure = silence avant un reveal, accords} etevents=[element|null, time|"fin+x", "sound[:param]", gain, [repeat, step]]. Sons : pop, bulle, clic, shutter, succes, buzz, tick, touche, impact, tape, whoosh_in:dur, whoosh_out:dur, ding:freq:dur, shimmer:dur, riser:dur, souffle:dur. Lie chaque son à son élément pour qu'il suive lorsque l'élément est décalé ou masqué. - Ancres :
python $ME/scripts/ancres.py <W>. - Prévisualisations :
python $ME/scripts/build.py <W>puisnode $ME/engine/04_render_frames.js <W> preview t1 t2 …→ planche contact → révise comme un moniteur exigeant (lisible ? visage clair ? zones de sécurité pub ?) et corrige avant le rendu. - Rendu :
bash $ME/scripts/rendu.sh <W>(arrière-plan, 3-6 min) →<nom>.mp4(+.srt/.txt), pistes dansmixage/pistes/, médias de l'éditeur. Vérifie 6-8 images du MP4, -14 LUFS, taille. - Éditeur : lance
python $ME/scripts/editor_server.py <W> <port>(dans Claude Code desktop : ajoute-le à.claude/launch.jsonet utilise l'outil de prévisualisation), ouvrehttp://localhost:<port>/editeur/. Vérifie que la prévisualisation, la sélection par clic et la lecture fonctionnent. - Surveiller les commentaires : surveille
W/comments.jsonet émet une ligne par nouveau commentaire avecstatus == "à faire"(commande dansreferences/editor.md).
Traitement d'un commentaire
- Lis-le (
target=el:<id>|scene:<id>|cap:<n>|audio:<track>,t, clicx,y). - Mets le statut "en cours" :
POST /api/comments/status {"id":…, "status":"en cours"}. - Modifie l'élément dans
parts/gfx.js(outop.jspour les zooms/panneaux,cartes.jsonpour les sous-titres,sons.jsonpour les sons), dans le respect de la charte et du registre. Si la demande est vague, applique la meilleure option et mentionne une alternative dans la réponse. python $ME/scripts/build.py <W>(+sons.pysi les sons changent) → l'éditeur recharge sa prévisualisation tout seul. Vérifie 1-2 images de prévisualisation.- Statut "fait" + un court
reply(ce qui a changé) — affiché dans l'éditeur. Rappelle à l'utilisateur qu'il peut cliquer sur "Rendre la vidéo". - Une préférence générale ("Je ne veux jamais X") → ajoute-la aux Règles de ce fichier.
Registre des éléments (contrat avec l'éditeur)
EL(id, name, scene, layer, [x,y,w,h], ()=>[start,end], t=>{…draw…})
layer:'panel'(dessiné à l'intérieur du panneau, derrière la tête qui sort) ·'full'(plein écran, devant) ·'none'(global : flashs, carte de fin).treçu = temps décalé par l'éditeur (EDITS.off) ; ne dessine qu'à l'intérieur de ta fenêtre ; caché siEDITS.hide[id].- La boîte
[x,y,w,h]est utilisée pour le clic dans la prévisualisation : maintiens-la précise. SCENES_ED= scènes listées à gauche de l'éditeur (id,label,a,b,kind).- Zooms : chaque entrée
ZPest un élémentzoom<i>(peut être supprimé dans l'éditeur).
Fichiers du projet
projet.json · cartes.json → caps.json (caps.orig.json = base de l'éditeur) · sons.json · parts/{top,primitives,gfx}.js · framing.js · edits.json (paramètres de l'éditeur : off, hide, caps, vol) · comments.json · captures/, assets/ · mixage/pistes/ · editeur/ · <nom>.mp4/.srt/.txt.