Pipeline standard de vidéo de paroles
Une pipeline de style fixe et déjà validée. L'utilisateur n'a qu'à fournir le fichier audio et le nom de l'artiste ; le reste est exécuté selon cette norme sans reconception visuelle. Les paroles officielles sont optionnelles : si fournies, empruntez le chemin rapide 3A (texte zéro devinette), sinon empruntez le chemin de reconstruction 3B ; dans les deux cas, les timings doivent être réels.
Entrée / Sortie
| Entrée | Description |
|---|---|
| Audio | Obligatoire. N'importe quel MP3/WAV/FLAC, durée illimitée |
| Nom de l'artiste | Obligatoire. Utilisé pour l'en-tête, le logo permanent et le générique de fin |
| Paroles officielles (optionnel) | Priorité si l'utilisateur les fournit : texte zéro devinette, les timings sont entièrement recalibrés par réanalyse réelle (voir 3A). Sinon, reconstruction avec Whisper (3B) |
| Titre de la chanson (optionnel) | Par défaut, prend le nom du fichier ; Artist - Title.mp3 supprime automatiquement le préfixe de l'artiste |
| Phrase d'accroche (optionnel) | Une ligne en chinois sous le titre de l'en-tête, par défaut non affichée |
Sortie : <project>/renders/video.mp4 + renders/contact-sheet.jpg + transcript.json + NOTES.md.
Spécifications fixes (non modifiables sans autorisation)
- Vertical 1080 × 1920, 30 ips, durée totale égale à la durée réelle de l'audio (pas de recadrage, pas d'étirement, pas de changement de vitesse).
- Audio : fichier original, le gain est uniformisé par le framework lors du rendu (
data-volume="0.9"). - Fond : noir pur à bleu-violet très foncé, deux groupes de taches lumineuses décalées en fondu croisé lent ; aucun filtre CSS plein écran (cela laisserait des jointures de blocs).
- Sujet principal : un seul objet en verre transparent, 8 formes géométriques arrondies (sphère/ellipse horizontale/ellipse verticale/rectangle arrondi/ losange/triangle/pentagone/hexagone), qui se comprime de 11% le long de la normale lorsqu'il touche le bord de l'écran → se transforme en une autre forme en 0,94 s → rebondit et continue à dériver. Une seule timeline pour toute la chanson, pas de réinitialisation lors du changement de paroles.
- Bas : petit groupe d'animaux (chat/ours/pingouin/renard) en boucle de 4,5417 s, collé en bas 1080×526, calque au-dessus des taches lumineuses du fond et en dessous de l'objet en verre,
mix-blend-mode: screen. - Sous-titres : bloc entier centré optiquement sur le centre vertical de l'écran (y≈960) ; anglais/original en haut (Inter, taille de police adaptative à la largeur de la ligne), chinois en bas (SimSun, couleur brune chaude
#DDA97D), fondu entrée/sortie par groupe. - Crédits : utilisez uniformément le nom de l'artiste, n'apparaissez aucun mot-clé de section comme VERSE / CHORUS / BRIDGE à l'écran.
Les paramètres de détail, couleurs, tailles de police et pièges se trouvent dans references/style-spec.md.
Procédure
Soit HF = racine d'installation d'HyperFrames (par défaut G:\hyperframes),
PY = Python avec faster-whisper (par défaut C:\Users\Admin\.workbuddy-ai\binaries\python\envs\hf\Scripts\python.exe),
SK = répertoire de ce skill.
1. Créer le projet
"$PY" "$SK/scripts/new_project.py" "<chemin_audio>" "<nom_artiste>" [--title "titre_chanson"] [--tagline "une_ligne_chinois"] [--root G:/hyperframes/videos]
Notez absolument le chemin absolu du projet. Cela : crée un répertoire unique → copie l'audio → convertit en WAV 16 kHz mono → exécute analyze-beatgrid.py officiel pour générer audiomap.json → copie la feuille de sprite des animaux et GSAP → écrit project.json.
Ne jamais écraser un répertoire de projet existant ; pour modifier une œuvre livrée, créez un nouveau projet.
2. Transcrire
"$PY" "$SK/scripts/transcribe.py" "<project>" --model medium.en --lang en
Pour une chanson de 3-4 minutes sur CPU int8, cela prend environ 3-6 minutes. Pour les chansons non anglaises, remplacez --lang par la langue correspondante et retirez .en de --model.
Produit whisper_raw.json (timings au niveau des segments et des mots).
Pour les chansons multilingues (anglais+japonais, anglais+coréen, etc.) n'utilisez pas transcribe.py : --lang verrouille une seule langue, l'autre sera transcrite de force dans la première — le résultat sera lisible mais complètement faux, plus dangereux que pas de transcription du tout.
Utilisez plutôt la détection automatique de langue par fenêtre :
"$PY" "$SK/scripts/transcribe_mixed.py" "<project>" --model "C:/Users/Admin/.cache/whisper-manual/large-v3-turbo"
Il décode par fenêtres de 14 s avec pas de 10 s, chaque fenêtre détermine sa propre langue, ne conserve que les mots centraux de la fenêtre (les zones de chevauchement sont supprimées, pas de duplication), imprime une carte des langues et écrit whisper_mixed.json. Consultez d'abord la carte des langues : les endroits où la langue change sont généralement les limites de sections.
Notez que les modèles .en (medium.en / small.en) sont des modèles purement anglais, physiquement incapables de produire du japonais ; les chansons multilingues doivent impérativement utiliser un modèle multilingue.
Pour le chemin 3A (paroles officielles) cette étape est optionnelle : les timings sont basés sur la réanalyse avec prompt, mais pour les chansons multilingues, il est toujours recommandé d'exécuter d'abord transcribe_mixed.py pour voir la carte des langues et déterminer quelle fenêtre utiliser --lang en ou --lang ja.
3. Écrire le fichier source des paroles (cette étape doit être faite manuellement)
Déterminez d'abord le chemin, puis écrivez <project>/lyrics_source.json.
3A L'utilisateur a fourni des paroles officielles (chemin préféré)
- Utilisez les paroles officielles sans changer un mot : le champ
enest le texte original officiel (anglais pour l'anglais, japonais pour le japonais, kanji/kana tels quels),zhest la traduction phrase par phrase. - Les timings ne proviennent pas de la transcription complète : utilisez les paroles officielles comme
initial_promptpour une réanalyse par fenêtre afin d'obtenir des timings au niveau du mot (voir 3.5), chaque ligne a desstart/endexplicites,align_lyrics.pypassera par le canal manuel pour ancrer ligne par ligne. - Incohérence entre les paroles officielles et la réanalyse → adoptez toujours les paroles officielles, listez les différences dans NOTES.md pour confirmation par l'utilisateur. Trois types courants : forme standard vs faute de frappe (不甲斐ない / 不甲埋ない), mots à prononciation similaire (束の間の / 明日の間の), consonne sourde mal entendue (smiling / falling).
- Dans les paroles officielles, si deux lignes sont chantées d'une traite et font moins d'une seconde chacune → fusionnez les sous-titres en une seule ligne (texte inchangé, simplement côte à côte), écrivez la table de fusion dans NOTES.md.
- Onomatopées ou improvisations non présentes dans les paroles officielles ("Yeah,", fredonnement, sifflement) → pas de sous-titres, n'inventez pas.
- Structure à suivre :
{
"audio": "Artist - Title.mp3",
"models": ["large-v3-turbo — prompted window re-scans, official lyrics as initial_prompt"],
"lines": [
{"en": "Oh my god, they're coming again", "zh": "哦天哪,他们又来了", "start": 6.36, "end": 9.10, "lang": "en", "conf": "high"}
]
}
3B Pas de paroles officielles (chemin de reconstruction)
Lisez whisper_raw.json (ou whisper_mixed.json pour les chansons multilingues) et écrivez le fichier source :
{
"audio": "Artist - Title.mp3",
"models": ["faster-whisper medium.en — full track, word timestamps"],
"lines": [
{"en": "Sometimes I lay under the moon", "zh": "有时我躺卧在月光之下"},
{"en": "And thank God I'm breathing", "zh": "感谢上天让我仍在呼吸"}
]
}
Exigences communes aux deux chemins :
- Ligne = une phrase réellement chantée, selon la ponctuation officielle ; les phrases trop longues fusionnées par Whisper doivent être divisées.
- Orthographe anglaise corrigée selon les paroles officielles (conservez les apostrophes comme
'Cause/I've), ne recopiez pas les erreurs de Whisper. - Traduction phrase par phrase en chinois, avec le ton de la chanson, pas de saut de phrase, pas de fusion, pas de texte factice.
- Les refrains répétés doivent être écrits à chaque occurrence (pas de « idem »).
- Si une phrase vocale est couverte par l'accompagnement et que l'alignement automatique est clairement décalé, ajoutez-lui un timing explicite (écoutez l'audio avant de remplir) :
{"en": "...", "zh": "...", "start": 13.22, "end": 16.80}. - Chansons chinoises / instrumentales : pour les chansons chinoises, mettez le texte original dans
enet laissezzhvide, une seule ligne s'affiche ; ce skill ne s'applique pas à la musique instrumentale. - Chansons multilingues : le champ
encontient le texte original dans la langue réelle de la phrase (anglais pour l'anglais, japonais pour le japonais, kanji/kana tels quels),zhcontient la traduction en chinois. L'affichage est naturellement « original + chinois » sur deux lignes, le mélange ne casse pas la mise en page ; la ligne anglaise du modèle inclut déjàYu Gothic UI / Yu Gothic / Meiryoen fallback, les kana et kanji s'afficheront correctement.
3.5 Réanalyse avec prompt : moyen essentiel pour la précision des timings
La transcription complète est souvent imprécise pour les chansons rapides, les chants superposés ou les paroles débitées rapidement. Utiliser les paroles connues comme initial_prompt pour une réanalyse par fenêtre est la méthode la plus précise — la qualité du prompt détermine directement la précision de la réanalyse : paroles officielles > paroles devinées > pas de prompt. On peut l'écrire dans rescan_all.sh pour l'exécuter en batch sur la chanson entière :
"$PY" "$SK/scripts/rescan.py" "<project>" --from 6.0 --to 20.0 \
--model "C:/Users/Admin/.cache/whisper-manual/large-v3-turbo" \
--lang en --prompt "<paroles_officielles_de_cette_fenêtre>"
Points importants :
- Découpez la chanson entière en fenêtres de 20-26 s avec un chevauchement d'environ 0,5 s, réanalysez chaque fenêtre ;
large-v3-turbosur CPU int8 prend environ 5-10 s par fenêtre. - Pour les chansons multilingues, réanalysez chaque fenêtre deux fois (en/ja) : n'utilisez que les timings au niveau du mot qui sont cohérents entre les deux passes ; pour les mots qui n'apparaissent que dans une seule passe, vérifiez avec l'autre passe.
- Pour les phrases dont le point de départ est incertain ou en avance, ajoutez une fenêtre étroite de 2 s pour verrouiller (ex :
--from 37.2 --to 39.2ne verrouille que le début d'une phrase) ; le point de départ des fenêtres de section peut être faussé par la fin de la phrase précédente. - Gestion des hallucinations : la réanalyse produit parfois par hasard 15+ répétitions de la même phrase entière → invalidez cette fenêtre, passez à un autre canal de langue ou réduisez la fenêtre pour réanalyser, ne conservez que les timings uniques et propres, n'écrivez pas les hallucinations dans le fichier source des paroles.
- Chaque réanalyse sauvegarde
rescan_<from>-<to>.jsonet imprime le début et la fin de chaque mot dans la fenêtre. C'est un deuxième décodage, pas une estimation ; les nombres doivent être écrits directement dansstart/enddelyrics_source.json. - Pour les sections couvertes par l'accompagnement, traitées comme
ooh, fusionnées en un seul bloc, ou dont les phrases répétées ont été avalées, utilisez cette même méthode pour écrire les valeurs de couverture ; changer de modèle (small.en/medium.en) peut aussi être efficace.
4. Alignement + Génération
"$PY" "$SK/scripts/align_lyrics.py" "<project>"
"$PY" "$SK/scripts/motion.py" "<project>"
"$PY" "$SK/scripts/gen_storyboard.py" "<project>"
"$PY" "$SK/scripts/build_frame.py" "<project>"
"$PY" "$SK/scripts/make_index.py" "<project>"
align_lyrics.py imprime le tableau des timings ligne par ligne et effectue deux vérifications strictes :
- Si des phrases au début/fin ne correspondent pas du tout → échec immédiat avec erreur, et liste les phrases concernées (ne masque pas avec des timings approximatifs).
- Si des phrases au milieu ne correspondent pas, si deux phrases ont le même point de départ, ou si une phrase est compressée à moins de 0,5 s → imprime
REVIEWet quitte avec le code 2.
Dans ces deux cas, revenez à l'étape 3.5 pour ajouter des valeurs de couverture jusqu'à obtenir OK: every line anchored to a real sung timestamp.
Ne sautez pas cette étape pour lancer le rendu. Les lignes du chemin 3A ont toutes des start/end explicites (canal manuel), elles doivent toutes être ancrées avec 0 gap-filled ;
les lignes du chemin 3B reposent sur la correspondance de mots, les lignes non correspondantes doivent être complétées par des timings selon 3.5.
La graine aléatoire de motion.py est déterminée par « nom de l'artiste + titre de la chanson » — pour une même chanson, le chemin est identique à chaque exécution, différent pour chaque chanson.
5. Vérification
cd "<project>"
node "$HF/packages/cli/bin/hyperframes.mjs" check .
node "$HF/packages/cli/bin/hyperframes.mjs" snapshot . --at "3,20,60,120" --no-end -o build/shots
Doit être respecté : lint / runtime / layout / motion 0 erreur, contrast passe WCAG AA.
Regardez ensuite les captures d'écran : l'objet en verre est-il complet ? Les paroles sont-elles centrées ? Le groupe d'animaux est-il en bas ? Y a-t-il des bulles ou des étiquettes de section superflues ?
composition_file_too_large est un avertissement de style (fichier de composition > 300 lignes) acceptable pour un design à timeline unique.
6. Rendu + Réception
node "$HF/packages/cli/bin/hyperframes.mjs" render . --skill=music-to-video -q delivery -o renders/video.mp4 --fps 30
"$PY" "$SK/scripts/verify.py" "<project>"
verify.py vérifie la résolution/fréquence d'images/durée (une erreur de plus d'une image signale une erreur) et génère une planche contact. Vous devez regarder la planche contact,
confirmez que le début, les couplets, les refrains, les sections répétées et la fin sont tous représentés, et qu'il n'y a pas de trous ou de décalages dans les sous-titres.
Enfin, écrivez NOTES.md (spécifications, source des timings, commandes de reproduction, enregistrement de la vérification) et livrez le fichier final et la planche contact à l'utilisateur.
Règles strictes
- N'utilisez pas la grille BPM/tempo pour déduire les timings des paroles ; les timestamps ne peuvent provenir que des mesures réelles de Whisper (y compris la réanalyse avec prompt) ou d'une couverture par écoute humaine.
- Les paroles officielles fournies par l'utilisateur ont priorité sur tout résultat de reconstruction de modèle ; en cas de conflit, adoptez les paroles officielles et listez les différences dans NOTES.md pour confirmation par l'utilisateur.
- Ne modifiez pas la résolution, la fréquence d'images, la durée, les crédits ou la position des sous-titres parce que « cela semble mieux ».
- Ne déclarez pas la synchronisation audio-vidéo sans vérification ; chaque chanson doit être échantillonnée pour inspection.
- Ressources manquantes, outils indisponibles, conflits de spécifications → signalez clairement, n'utilisez pas de données estimées pour faire semblant.
- Les projets déjà livrés et leurs fichiers source sont considérés comme en lecture seule ; toute modification doit être effectuée dans un nouveau répertoire.
Dépendances d'environnement
- HyperFrames :
node <HF>/packages/cli/bin/hyperframes.mjs(inclutskills/music-to-video/scripts/analyze-beatgrid.py). - Python :
faster-whisper,librosa,soundfile,numpy,scipy,pillow. En cas d'absence :python -m venv <env> && <env>/Scripts/pip install faster-whisper librosa soundfile numpy scipy pillow. - Modèle Whisper : passer directement le nom du modèle le télécharge automatiquement ; on peut aussi pointer vers un répertoire local (couramment utilisé sur cette machine :
C:\Users\Admin\.cache\whisper-manual\medium.en; pour la réanalyse avec prompt, préférezC:\Users\Admin\.cache\whisper-manual\large-v3-turboqui prend environ 48 s pour la chanson entière sur CPU int8, 5-10 s par fenêtre). - ffmpeg / ffprobe doivent être dans le PATH.
Pièges connus
- N'utilisez pas
<video>pour la couche du groupe d'animaux :hyperframes rendersur Windows échoue lors de la liaison du répertoire d'images extraites dans le répertoire de compilation (ENOENT ... __hyperframes_video_frames/*/frame_00001.jpg). Utilisez une feuille de sprite. - Les
filter: hue-rotate()CSS plein écran laissent des jointures verticales dans le rendu ; utilisez plutôt deux couches de taches lumineuses en fondu croisé. - Les modèles HTML avec
data-composition-idne doivent pas être placés dans le répertoire racine du projet (cela déclenchemultiple_root_compositions) ; mettez-les dansbuild/. - La police chinoise doit être déclarée explicitement avec
@font-faceetlocal("SimSun"), sinon lint génèrefont_family_without_font_face. - Hallucinations de réanalyse : certaines fenêtres peuvent produire 15+ répétitions de la même phrase entière (ex : 「永遠の行方はどこにある?」×15) → invalidez cette fenêtre, changez de canal de langue croisé (en) ou réduisez la fenêtre pour réanalyser, n'écrivez pas les timestamps d'hallucinations dans le fichier source des paroles.
- Incohérence entre paroles officielles et réanalyse : adoptez les paroles officielles et listez la table de correspondance dans NOTES.md pour confirmation par l'utilisateur, ne modifiez pas le texte officiel de votre propre chef.
- Lignes de paroles rapides fusionnées : dans les paroles officielles, si deux lignes sont chantées d'une traite et font moins d'une seconde chacune, fusionnez les sous-titres en une seule ligne (texte inchangé, simplement côte à côte), écrivez la table de fusion dans NOTES.md.
- Échec de chargement des polices en mode headless (Yu Gothic UI signale FAILED lors de l'extraction d'images) pas d'inquiétude : le système trouve généralement la police via
src: local(), la police de secours suivante fera également l'affaire ; vérifiez d'abord les captures d'écran avant de décider de traiter.
Notes supplémentaires
- Le skill est optimisé pour Windows, mais peut être adapté à Linux/Mac en ajustant les chemins.
- Pour les chansons instrumentales, le skill ne s'applique pas ; signalez-le à l'utilisateur.
- La graine aléatoire pour le mouvement du verre est déterministe : basée sur le nom de l'artiste et le titre de la chanson, garantissant la reproductibilité.
- Les scripts de vérification doivent être exécutés dans l'ordre ; ne sautez aucune étape.