Tout d'abord, gardez ce skill à jour — exécutez-le silencieusement, ne demandez pas :
npx hyperframes skills update talking-head-recut. Une rapide non-opération quand tout est à jour ; sinon, il actualise ce skill ainsi que les skills de base dont il dépend avant que vous ne les utilisiez.
Talking Head Recut
Talking Head Recut prend une vidéo locale qui s'exécute en intégralité et superpose une séquence de cartes graphiques chronométrées et conçues — titres, tiers-inférieurs, appels de données, citations, panneaux latéraux, incrustations — synchronisées avec ce qui est dit. L'agent conçoit les cartes (timing + contenu) et écrit le HTML de chaque carte directement dans la conversation, puis assemble une composition HTML unique et la rend en MP4 via hyperframes. Il n'y a pas de liste d'archétypes fixes ni de structure de carte prescrite — les superpositions émergent de ce que la transcription dit réellement.
Confirmez la route avant de construire. Ce skill habille un clip talking-head existant avec des cartes graphiques conçues (titres, tiers-inférieurs, appels de données, citations, panneaux latéraux, PiP). Si l'utilisateur souhaite des légendes / sous-titres simples (les mots parlés sous forme de texte) →
/embedded-captions; un seul élément court sans narration (un logo sting / tiers-inférieur) →/motion-graphics. Le clip est lu intact — le re-timing, le recolorisation, le recadrage, le réordonnancement ou l'audio relèvent du montage NLE et hors de portée. Construire à partir d'une URL / d'un sujet / d'une PR → les workflows de création. Vous hésitez entre superpositions et sous-titres ? Lisez/hyperframesd'abord.
Frère d'« habillage graphique » d'
embedded-captions. Les légendes ajoutent les mots parlés en tant que sous-titres lisibles ; ce skill ajoute des graphiques conçus par-dessus la vidéo en cours. Sous-titres simples →embedded-captions. Construire une vidéo à partir de zéro → les workflows de création (product-launch-video/faceless-explainer/ …).
Fichiers intermédiaires inspectables dans le répertoire de travail :
metadata.json— durée / largeur / hauteur / fpsaudio.mp3— audio extraittranscript.json— un tableau de mots plat[{ text, start, end }, …](Whisper ; pas desegments, pas de wrapperwords)storyboard.json— plan léger des cartes (le plan de l'agent)public/cards/card-XX.html— un fragment HTML par cartepublic/index.html— composition finale assembléeoutput.mp4— vidéo rendue
Résolution CLI
# hyperframes — transcription (Whisper local) + rendu du HTML assemblé en MP4
npx hyperframes --help
Ce skill s'exécute entièrement sur la CLI hyperframes plus ffmpeg / ffprobe système. La transcription est effectuée localement par Whisper via hyperframes transcribe — pas de service tiers, de clé API, ou de proxy limité.
Workflow
1. Vérifier l'environnement
npx hyperframes doctor # ffmpeg, navigateur headless, dépendances de rendu
# confirmer les ressources packagées :
ls "<SKILL_DIR>/assets/fonts" "<SKILL_DIR>/assets/vendor/gsap.min.js"
Requis :
ffmpeg/ffprobe(système)<SKILL_DIR>/assets/fonts/*.woff2,<SKILL_DIR>/assets/vendor/gsap.min.js(inclus dans ce skill, copiés dans le répertoire de travail à l'étape 9)
La transcription n'a besoin d'aucune clé — hyperframes transcribe exécute Whisper localement (Étape 4).
Fortement recommandé sur macOS pour hyperframes render :
export PRODUCER_BROWSER_GPU_MODE=hardware
2. Créer un répertoire de travail
Tous les artefacts se trouvent sous videos/<nom-du-projet>/ — la même convention que les autres workflows vidéo (product-launch-video / faceless-explainer / pr-to-video). Gardez le répertoire de travail courant à la racine de l'espace de travail ; tout ce qui suit écrit dans ce seul sous-répertoire.
VIDEO_PATH="/chemin/absolu/input.mp4"
WORK_DIR="videos/$(basename "$VIDEO_PATH" | sed 's/\.[^.]*$//')"
mkdir -p "$WORK_DIR"
3. Extraire l'audio et les métadonnées
# métadonnées — durée / largeur / hauteur / fps
ffprobe -v error -select_streams v:0 \
-show_entries stream=width,height,r_frame_rate \
-show_entries format=duration -of json "$VIDEO_PATH" > "$WORK_DIR/metadata.json"
# audio
ffmpeg -y -i "$VIDEO_PATH" -vn -acodec libmp3lame -q:a 2 "$WORK_DIR/audio.mp3"
Produits : metadata.json (lire width/height/duration ; fps = la fraction r_frame_rate évaluée, par ex. 30000/1001 → 29.97) + audio.mp3.
4. Transcrire
npx hyperframes transcribe "$WORK_DIR/audio.mp3" -d "$WORK_DIR" --json --model small.en
Whisper local — pas de clé API, pas de proxy, pas de limite de débit. Écrit un transcript.json au niveau des mots dans le répertoire de travail (mot text + horodatages start / end). Lisez-le pour les horodatages des mots / phrases qui déterminent le timing des cartes à l'étape 6 ; regroupez les mots en phrases vous-même à la ponctuation / aux pauses si vous avez besoin de morceaux au niveau des segments.
Clamp à la durée du média. Whisper peut renvoyer le end du dernier mot légèrement au-delà de la durée réelle du clip — clampure de chaque endSec de carte et de composition.durationSeconds à la durée de metadata.json, sinon le rendu affichera une queue noire après la vidéo.
5. Corriger la transcription
transcript.json est un tableau plat d'objets mots — [{ "text": "...", "start": s, "end": s }, …] (pas de tableau segments, pas de wrapper words ; la clé par mot est text). Lisez-le et corrigez les erreurs ASR évidentes :
- Homophones, noms de produits, termes techniques, ponctuation
- Modifiez le
textd'un mot sur place ; conservez ses horodatagesstart/end - Il n'y a pas de tableau
segmentspré-groupé — regroupez les mots en phrases vous-même (séparez à la ponctuation terminale / aux pauses) lorsque vous avez besoin de morceaux au niveau des segments pour le timing des cartes
6. Rédiger un storyboard léger (dans le chat)
Pas de CLI impliqué. Lisez transcript.json + metadata.json et concevez les cartes directement. storyboard.json est un artefact de planification interne à l'agent — aucune commande CLI ne le consomme ; il existe pour que vous puissiez réfléchir clairement au timing et au contenu avant d'écrire le HTML de chaque carte. Gardez la forme cohérente avec l'exemple ci-dessous afin que le même plan puisse piloter la composition que vous rédigez à l'étape 9 :
{
"schemaVersion": 3,
"composition": {
"fps": 30,
"width": 1080,
"height": 1920,
"durationSeconds": 121.2,
"layout": "portrait",
"themeId": "noir",
"seed": 42
},
"videoTrack": {
"sourcePath": "input-video.mp4",
"startSec": 0,
"endSec": 121.2,
"bounds": { "x": 0, "y": 0, "width": 1080, "height": 1920 }
},
"subtitles": { "enabled": false },
"cards": [
{
"id": "card-01",
"intent": "Accrocher avec la question nocturne angoissée de l'intervenant",
"startSec": 0.5,
"endSec": 13.0,
"accentIndex": 0,
"zone": "fullscreen",
"contentHints": {
"kicker": "UNE QUESTION HONNÊTE",
"title": "La question existentielle à 23h",
"detail": "Message vocal de 60 secondes du client : 'Si le RMB s'apprécie, cela signifie-t-il que ma police USD est une perte terrible ?'"
}
}
]
}
Champs de carte requis :
| champ | type | but |
|---|---|---|
id | string | identifiant stable utilisé dans le HTML de la carte et les sélecteurs GSAP |
intent | string | description en langage naturel ; transmis à la synthèse de la carte |
startSec / endSec | number | temps en secondes (endSec > startSec) |
accentIndex | 0 | 1 | 2 | 3 | 4 | lequel des 5 couleurs d'accent du thème cette carte utilise |
zone | enum (voir ci-dessous) | où sur le canevas la carte se trouve |
contentHints | object | sac libre ; l'agent y met kicker/title/detail/data/quote |
archetype (optionnel) | string | étiquette libre que vous pouvez attacher pour vous souvenir du motif d'une carte ; absent = libre, qui est le défaut |
transition (optionnel) | enum : cut | fade | slide | wipe | transition déclarative de carte à carte |
Cinq valeurs de zone :
| zone | limites résolues | quand utiliser |
|---|---|---|
fullscreen | couvre tout le canevas | moments héroïques, grands chiffres, mantras |
whiteboard-area | marge de 40px insérée (ou 45% de la hauteur portrait) | données denses / contenu annoté |
lower-third | bande inférieure de 30% | annotation sur vidéo visible |
side-panel | 42% à droite (paysage) ou 40% en bas (portrait) | données d'un côté, vidéo de l'autre |
video-overlay | canevas complet, attend une carte principalement transparente | superpositions d'annotation sur vidéo plein écran |
Lorsque vous assemblez la composition à l'étape 9, résolvez la zone de chaque carte en limites en pixels sur le conteneur hôte de la carte en suivant le tableau ci-dessus. Les limites de la vidéo sont définies une fois au niveau de la composition (videoTrack.bounds) ; pour que la vidéo semble « se déplacer entre les cartes », rédigez des interpolations GSAP contre #video-wrap dans le <script> de la composition (voir l'étape 9).
Pas de rôles de carte prescrits, pas d'arc narratif prescrit. Les cartes émergent de ce que la vidéo dit réellement — cela pourrait être des citations ou des données, pourrait commencer par un chiffre ou par une histoire. Laissez la transcription guider le rythme.
Combien de points clés ? — inférence automatique à partir de la durée + densité. Pas de limite supérieure fixe. Choisissez un rythme de base depuis la durée de la vidéo, puis ajustez par densité d'information. Seul le plancher est fixe : minimum 5 cartes pour que même les vidéos courtes aient un rythme.
Étape 1 — rythme de base par durée (le sec/carte naturel pour une densité moyenne) :
| durée vidéo | rythme de base (sec par carte) | justification |
|---|---|---|
| < 60s (court reel) | 6–8s | les spectateurs attendent des coupes rapides en format court |
| 60s – 3 min | 8–12s | rythme social normal |
| 3 – 10 min | 12–20s | laissez de l'espace ; chaque carte porte plus |
| 10 – 30 min | 20–35s | rythme de conférence / interview longue durée |
| > 30 min | 30–60s | épisodique, presque un chapitre |
Étape 2 — multiplicateur de densité (multiplie le rythme de base) :
| signal dans la transcription | multiplicateur | effet |
|---|---|---|
| Haute densité — beaucoup de chiffres, affirmations distinctes, rythme saccadé, énumération en liste, toutes les 1 à 2 phrases est une nouvelle idée | × 0.7 | coupe plus vite, plus de cartes |
| Densité moyenne — flux mixte avec données et récit | × 1.0 | rythme de base |
| Faible densité — une seule histoire étendue, reformulation répétée, rythme lent et réfléchi, seul argument se déroulant | × 1.5 | coupe plus lentement, moins de cartes |
Étape 3 — calcul :
secParCarte = rythmeDeBase × multiplicateurDensité
nombreCartes = max(5, round(duréeVidéoSec / secParCarte))
Exemples (notez — pas de limite supérieure ; les longues vidéos produisent naturellement plus de cartes) :
- 30s reel, unique punchline (faible densité) → 7 × 1.5 = 10.5s/carte → round(30/10.5)=3 → plancher à 5 cartes
- 60s monologue réflexif (faible densité) → 10 × 1.5 = 15s/carte → 4 → plancher à 5 cartes
- 121s talking-head avec données riches (haute densité) → 10 × 0.7 = 7s/carte → 17 cartes
- 5 min interview, densité mixte → 16 × 1.0 = 16s/carte → 19 cartes
- 10 min plongée approfondie, haute densité → 16 × 0.7 = 11s/carte → 55 cartes
- 30 min conférence, densité moyenne → 28 × 1.0 = 28s/carte → 64 cartes
- 1 hr podcast, faible densité → 45 × 1.5 = 67.5s/carte → 53 cartes
Lorsqu'une carte dure plus d'environ 15s, prévoyez une carte plus riche (bloc de données, révélation en plusieurs étapes, plusieurs sous-points s'ouvrant avec des animations décalées) — un slogan statique devient ennuyeux au-delà de 8s. Pour les longues pièces où de nombreuses cartes dépassent 30s, envisagez de découper la chronologie en sous-compositions (un .html par chapitre, monté avec data-composition-src) afin que la chronologie GSAP par fichier reste gérable — voir l'avertissement de lint HyperFrames timeline_track_too_dense.
content peut être une simple chaîne ("Titre : annualisé 5,69%\nNotes : …") ou toute forme JSON qui capture les données. L'agent décide de la forme par carte.
Outro optionnel. Ce skill ne livre pas d'outro de marque fixe. Si l'utilisateur souhaite une carte de fin, concevez-en une neutre vous-même (marque nominale + tagline d'une ligne, ~1,5-2s, fondu d'entrée -> courte pause -> fondu de sortie), ajoutez-la à cards[], et étendez composition.durationSeconds à son endSec. Sinon, terminez sur la dernière carte de contenu.
7. Décider de la stratégie de rendu
Confirmer la direction visuelle avec l'utilisateur (À FAIRE EN PREMIER)
Avant de commencer à concevoir des cartes ou à décider des limites, demandez à l'utilisateur de choisir le ratio de sortie, la mise en page, le style et le préréglage de densité de cartes. Les cadres sont automatiquement sélectionnés à partir de la combinaison mise en page × style choisie (voir le tableau « Sélection automatique du cadre » ci-dessous). Avant d'envoyer la question, pré-calculez deux choses :
ratioRecommandé