mkt-hyperframe-talking-head-video-16-9
Éditeur dédié 16:9 (1920×1080) paysage — l'entrée est un dossier de travail contenant voiceover.mp3 + source.mp4 + script.txt, la sortie est ce même dossier entièrement structuré en projet HyperFrames prêt pour prévisualisation avec npx hyperframes preview.
Il s'agit de la couche opérationnelle sous l'orchestrateur mkt-full-video-with-11-hyperframe-heygen-16-9. L'orchestrateur gère la Phase 1 (TTS) et la Phase 2 (avatar HeyGen) → remet le dossier à cette compétence pour la Phase 3 (transcription + échafaudage + lint + prévisualisation).
Ce que produit cette compétence
<dossier_de_travail>/
├── voiceover.mp3 # entrée (non modifié)
├── source.mp4 # entrée (avatar HeyGen synchro labiale, non modifié)
├── script.txt # entrée (non modifié)
├── transcript.json # généré — sortie Whisper au niveau mot
├── transcript-cleaned.json # généré — nettoyé des coquilles vietnamiennes
├── scenes-outline.json # généré — plan préalable (5 scènes)
├── scenes.json # généré — métadonnées finales par scène
├── index.html # généré — composition racine 1920×1080
├── compositions/
│ ├── scene-1.html # 1 fichier par scène, quel que soit N
│ ├── scene-2.html # rédigé par des sous-agents LLM parallèles (Phase 3d)
│ ├── scene-3.html # PAS généré par des templates Python (obsolète)
│ ├── ...
│ └── scene-N.html
├── sfx/ # 6 liens symboliques/copies SFX depuis les ressources de la compétence
│ ├── camera-flash.mp3
│ ├── Whoosh sound effect (1).mp3
│ ├── búng tay.mp3
│ ├── Laser.mp3
│ ├── ting.mp3
│ └── Discord Notification - Sound Effect.mp3
└── (optionnel) infographics/
├── 1.png 2.png 3.png # si --with-infographics
└── prompts.md # instructions éditoriales papier crème par scène
Canvas :
- Racine :
data-width="1920" data-height="1080". - Cadre avatar par défaut SPLIT :
top:100, left:1290, width:540, height:880, borderRadius:32. - Cadre avatar PIP coin :
top:600, left:1540, width:320, height:420, borderRadius:20. - Support de diapositive :
1200×1080SPLIT, animable vers1920×1080pendant PIP. - Taille intrinsèque de chaque composition :
data-width="1200" data-height="1080"(remplit 100% du support, s'étend quand celui-ci s'élargit).
Entrées requises (convention dossier de travail)
| Fichier | Requis | Note |
|---|---|---|
voiceover.mp3 | Oui | Sortie TTS ElevenLabs (voix de Hoàng). |
source.mp4 | Oui | Avatar HeyGen synchro labiale. Actuellement portrait 9:16 — le cadre paysage utilise object-fit: cover; object-position: center 25% pour un recadrage approprié. Voir references/source-mp4-cropping.md. |
script.txt | Oui | Script vietnamien qui a produit voiceover.mp3. Utilisé pour la correction des coquilles et la dérivation des titres de scène. |
scenes-outline.json | Non | Si l'utilisateur a prédéfini 5 scènes, ignorer la détection automatique. Schéma : voir Étape 3. |
Slug = nom de base du dossier de travail (aucune dérivation nécessaire). Tous les scripts lisent/écrivent dans ce dossier. Les scripts acceptent le flag --workspace <chemin> et utilisent par défaut le répertoire de travail courant.
Le pipeline (invocation séquentielle des scripts)
voiceover.mp3 + source.mp4 + script.txt
│
▼
1. transcribe_audio.py ── Whisper VN → transcript.json (niveau mot)
│
▼
2. clean_transcript.py ── supprime les artefacts Whisper, applique le dictionnaire VN
│
▼
3. detect_scenes.py ── transcript + script.txt → scenes-outline.json (5 scènes)
│
▼
4. [CHECKPOINT optionnel] ── l'utilisateur vérifie le plan / modifie kicker, titre
│
▼
5. scaffold_project.py ── écrit scenes.json (schéma complet), crée sfx/ + logos/ + avatar.jpg + yt-lower-third.html
│
▼
6. 🔥 DÉPLOIEMENT SOUS-AGENTS LLM 🔥 ── l'orchestrateur lance N agents parallèles
à usage général (1 par scène) en un seul message, chacun
rédigeant compositions/scene-{num}.html à partir de
visual-plan.json + references/composition-patterns.md.
PAS generate_compositions.py (générateur Jinja2
OBSOLÈTE — se réduit à 5 archétypes, ne peut pas adapter
les métaphores spécifiques aux scènes, échoue pour
des listicles de 6+ scènes).
│
▼
7. generate_root_index.py ── écrit index.html avec le support de diapositive (monte scene-{num}.html
pour TOUTES les scènes, sans mapping kind→fs-lesson) +
cadre avatar (bordure marque claude-orange #d97757) +
timeline GSAP (SPLIT↔PIP, respiration, punch, PIP_EVENTS,
zoom accroche hybride) + 6 SFX câblés +
couche image b-roll papier crème à la racine (plein 1920×1080)
│
▼
8. [optionnel] scaffold_infographic_slots.py
── ajoute des espaces réservés <img onerror> + écrit prompts.md
(éditorial papier crème par métaphore de scène)
│
▼
9. lint_and_preview.py ── npx hyperframes lint → 0 erreurs, puis prévisualisation
│
▼
REMISE — URL Studio affichée ; l'utilisateur vérifie ; l'orchestrateur décide du rendu.
Règle de prévisualisation d'abord (non négociable) : la compétence se termine à l'Étape 9 avec une URL Studio. Le rendu MP4 ne se produit qu'après confirmation explicite de l'utilisateur — cette étape appartient à l'orchestrateur ou à l'utilisateur manuellement.
Étape 1 : transcribe_audio.py
python3 scripts/transcribe_audio.py --workspace <dossier>
Encapsule la compétence existante mkt-ai-video-extract-srt-segment si disponible localement ; sinon, utilise directement l'interface CLI whisper :
whisper voiceover.mp3 --model medium --language vi --word_timestamps True \
--output_format json --output_dir .
NE JAMAIS utiliser --model medium.en pour l'audio vietnamien — .en traduit au lieu de transcrire. Toujours --language vi.
Sortie : transcript.json — tableau d'entrées au niveau mot {text, start, end}.
Étape 2 : clean_transcript.py
Réutilise la logique de l'éditeur 9:16 associé (mkt-hyperframe-talking-head-video/scripts/clean_transcript.py). Supprime U+FFFD, applique un dictionnaire au niveau mot et phrase VN (alphabit→Alphabet, Cod→Code, etc.), regroupe en phrases de 3-5 mots. Sortie : transcript-cleaned.json. (Pas de caption-groups.json — les légendes sont DÉSACTIVÉES en 16:9.)
Étape 3 : detect_scenes.py
Lit transcript-cleaned.json + script.txt → déduit 5 limites de scène en utilisant le squelette standard de vidéo pédagogique :
| # | Type | Indice de kicker par défaut | Variante |
|---|---|---|---|
| 1 | accroche | Première phrase du script | tier-row (aspect post-stack via kind=hook) |
| 2 | problème | Là où le script passe à "ChatGPT/AI cũ", "khó", "đứt mạch", "vấn đề"… | chats-stack |
| 3 | solution | Là où le script introduit l'outil/méthode | hero-orb |
| 4 | récapitulatif | Là où le script montre un résultat numérique ("X tiếng", "Y khách hàng") | counter-row |
| 5 | appel à l'action | Dernière phrase avec déclencheur de commentaire/like/suivi | terminal-row |
Si le script n'a pas 5 parties claires, sortie de moins (min 3) et avertit l'utilisateur. Heuristique : diviser le transcript par limites de phrases en ~5 segments avec un poids 1,5x pour la scène 3 (la solution est généralement la plus longue).
Sortie scenes-outline.json :
[
{ "num": 1, "kind": "hook", "start": 0.07, "end": 13.73, "kicker": "...", "heading": "...", "variant": "tier-row" },
{ "num": 2, "kind": "problem", "start": 13.73, "end": 27.37, "kicker": "...", "heading": "...", "variant": "chats-stack" },
{ "num": 3, "kind": "solution", "start": 27.37, "end": 47.75, "kicker": "...", "heading": "...", "variant": "hero-orb" },
{ "num": 4, "kind": "recap", "start": 47.75, "end": 53.80, "kicker": "...", "heading": "...", "variant": "counter-row" },
{ "num": 5, "kind": "cta", "start": 53.80, "end": 60.68, "kicker": "...", "heading": "...", "variant": "terminal-row" }
]
CHECKPOINT — affiche le plan pour que l'utilisateur le vérifie. L'utilisateur peut modifier kicker/titre/variante en ligne avant de continuer. Ignorer le checkpoint si la compétence est appelée avec --auto (mode orchestrateur).
Étape 4 : scaffold_project.py
Lit scenes-outline.json → enrichit chaque scène avec :
accent_words— dérivés du titre (extraire les nombres + les 2-3 derniers noms)content— schéma spécifique au modèle (voirassets/templates/)badges— 1-3 badges flottants par scènebrollEnd,hasBreath— pour la planification SPLIT↔PIPpip_events— dérivés du minutage deaccent_wordsdans la scène
Écrit scenes.json. Copie également automatiquement ces ressources autonomes du dossier assets/ de la compétence dans le dossier de travail :
| Ressource | Source | Destination | Objectif |
|---|---|---|---|
| 6 fichiers SFX | assets/sfx/ | <workspace>/sfx/ | Sons rythmiques (camera-flash, whoosh, búng-tay, Laser, ting, Discord-notification) |
| Logos de marque | assets/logos/{chatgpt,gemini,claude,claude-code}.{png,jpg} | <workspace>/assets/logos/ | Attachés automatiquement aux compositions (avatars chats-stack, hero-orb, badge d'outil tier-row) |
| Avatar | assets/avatar.jpg | <workspace>/assets/avatar.jpg | Miniature de chaîne pour la bannière d'abonnement yt-lower-third |
| YT lower-third | assets/compositions/yt-lower-third.html | <workspace>/compositions/yt-lower-third.html | Montage de bannière d'abonnement, dernières 3s de la vidéo |
Si une ressource source est manquante dans le bundle de la compétence, elle se rabat silencieusement sur le chemin du dossier de travail existant (workspace/assets/...). Si aucune n'est trouvée, cette ressource est ignorée (les compositions se dégradent gracieusement — avatars textuels au lieu de logos, pas de lower-third).
Étape 5 : 🔥 DÉPLOIEMENT SOUS-AGENTS LLM (rédaction de composition) 🔥
generate_compositions.py est OBSOLÈTE. Ne l'appelez pas. Le générateur Python Jinja2 réduit chaque scène à 1 des 5 archétypes fixes (accroche → tier-row, problème → chats-stack, solution → hero-orb, récapitulatif → counter-row, appel à l'action → terminal-row), ne peut pas s'adapter à la métaphore spécifique d'une scène (par exemple, "scroll-tape-wasted", "two-clock-comparison", "right-tool-vehicles"), et échoue pour les listicles de 6+ scènes (plusieurs tip-N se réduisent au même nom de fichier → écrasement).
Méthode canonique : l'orchestrateur (ou l'utilisateur) lance N agents general-purpose parallèles (1 par scène) en un seul message pour qu'ils s'exécutent simultanément. Chaque sous-agent :
- Lit son bloc de scène depuis
visual-plan.json(chemin :<workspace>/visual-plan.json, index de scènenum-1) - Lit les références depuis la compétence orchestrateur :
references/composition-patterns.md(8 modèles éprouvés en production),references/slide-design-tokens.md(palette + typographie) - Choisit le bon modèle pour la métaphore de sa scène — s'adapte librement (hero-orb peut devenir vault+spokes, stats-3card peut devenir two-clock-comparison)
- Rédige
compositions/scene-{num}.htmlentièrement : viewport 1200×1080, CSS limité via[data-composition-id="scene-{num}"], timeline GSAP enregistrée surwindow.__timelines["scene-{num}"], pas de!important, pas d'image-slotintégrée (l'image papier crème réside uniquement dans la couche racine)
Le résultat : chaque scène obtient un fichier de composition unique et adapté à sa métaphore. Pas de collision, pas d'enfermement dans 5 archétypes ennuyeux.
Voir l'Étape 4d de l'orchestrateur mkt-full-video-with-11-hyperframe-heygen-16-9/SKILL.md pour le modèle complet du prompt du sous-agent.
Logos de marque dans les compositions (référencés par les sous-agents)
Les sous-agents intègrent les logos de marque lorsque leur modèle en a besoin. Les logos se trouvent dans <workspace>/assets/logos/ :
| Utilisation du modèle | Élément de marque |
|---|---|
| Accroche tier-row "après" | Pilule tool-badge (en haut à droite) — logo Claude + nom. |
| Lignes d'échec problem chats-stack | Logos ChatGPT/Gemini attachés automatiquement quand name correspond à un mot-clé (chatgpt/gpt → chatgpt.png ; gemini/google → gemini.jpg). |
| Solution hero-orb / vault | Logo de marque à l'intérieur de la lueur de l'orb (par défaut Claude). |
| Appel à l'action terminal-row | Pas de logos par défaut. |
Les sous-agents se rabattent sur un avatar textuel si assets/logos/ n'existe pas (pas de scintillement).
Référence des modèles (8 archétypes, les sous-agents choisissent et adaptent)
Le fichier references/composition-patterns.md de l'orchestrateur fournit 8 modèles éprouvés en production :
| Modèle | Idéal pour | Motif interne |
|---|---|---|
tier-row before-after | Contraste d'accroche | 2 rangées de niveaux (avant rose/rouge + après lime/vert) avec lettre + éléments |
chats-stack | Problème / échec / démo Edit-Regen | Ligne utilisateur + 2-3 lignes d'échec IA + tampon de rupture |
hero-orb + spec-trio | Solution / mécanisme / coffre central | Orbe lumineuse + icônes de tâches + 3 rangées de spécifications |
counter-row | Récapitulatif / preuve numérique | Grand compteur (DE → À) + clients + balise delta |
comment-terminal | Appel à l'action / "commentez X" | Lettre de niveau + terminal macOS factice + 2 cartes cadeaux |
stats-3card | Introduction de connaissances / révélation de 3 faits | 3 colonnes style page d'accueil avec // LBL + nombre dégradé |
comparison-2col | "Quand utiliser quoi" | 2 colonnes de puces Oui/Oui |
image-slot | (OBSOLÈTE — image au niveau racine) | — |
Les sous-agents s'adaptent librement : par exemple, hero-orb → "coffre + 5 rayons de chat", stats-3card → "comparaison de deux horloges", comparison-2col → "3 cartes de véhicule à niveaux". Le document de modèle donne le squelette (HTML + CSS + GSAP), le LLM fait l'adaptation créative.
Étape 6 : generate_root_index.py
Lit scenes.json + total_duration depuis le transcript → rend assets/templates/index.html.j2 :
- Racine 1920×1080 avec
#slide-bg,#heygen-bg,#avatar-frame > .avatar-breathing > .avatar-punch > #v-source <audio id="a-source">suit l'audio original de source.mp4 (piste 1)- 6
<audio>SFX câblés avecdata-startabsolu (limites de scène) - Marque de marque en haut à gauche
- Bloc GSAP :
- Entrée initiale (fondu de l'avatar, fondu de la marque)
- Constantes SPLIT/PIP + aides
goPIP(t)/goSplit(t) - Tableau
PIP_EVENTSpiloté parpip_eventspar scène depuis scenes.json - Stratégie de zoom visuel "Hybrid Hook" sur
.avatar-breathing:- Scène ACCROCHE : rampe lente 1,0 → 1,10 sur toute la durée de la scène (construction dramatique,
power2.in) - Transition ACCROCHE→CORPS : réinitialisation brusque 1,10 → 1,0 (relâchement de tension, 0.5s
power3.in) - Scènes CORPS (2..N-1) aux événements PIP-IN : battements de punch 1,06 (rythme,
power2.out→power3.out) - Scène APPEL À L'ACTION : poussée douce 1,0 → 1,04 (fermeture,
sine.inOut)
- Scène ACCROCHE : rampe lente 1,0 → 1,10 sur toute la durée de la scène (construction dramatique,
- Petit punch de début de scène (1,06) sur
.avatar-punchpour la transition de battement
…
[abrégé pour la traduction]