MMD 舞蹈视频字幕:端到端流程 (Vidéos de danse MMD : processus de bout en bout)
0. Principe en une phrase
Après chaque écriture/rendu, il faut absolument extraire une image pour vérifier : la durée indiquée par ffprobe ne garantit pas que les sous-titres apparaissent ; une erreur de timestamp ASS ou de format de couleur de style peut entraîner un « rendu réussi mais aucun texte visible ».
Ce projet a déjà connu plusieurs mésaventures où l'on pensait avoir corrigé, mais l'incrustation n'avait pas eu lieu. La validation se fait toujours par l'extraction d'images clés.
1. Actifs et chemins (cet espace de travail)
| Élément | Chemin |
|---|---|
| Projet de sous-titres | D:\yingyong2\论项目\字幕\ |
| Paroles LRC | 字幕\[by维尔日记].txt — KISS OF LIFE《Who is she (Japanese Ver.)》, 36 couplets |
| Ancienne vidéo MMD | 字幕\0001-4956 - 副本.mkv (2560×1080 / 30fps ; fichier incomplet, 165s annoncés, seulement ~137s décodables) |
| Nouvelle vidéo MMD | D:\mmd.mp4\0002-4956.mkv (2560×1080 / 30fps / 165.166s, complète) |
| Polices | 字幕\build\fonts\ (Anton, ArchivoBlack, BebasNeue, Bungee, Monoton, PermanentMarker, RubikGlitch, Silkscreen, PirataOne, UnifrakturCook) + système Georgia / Microsoft YaHei |
| Scripts de génération | 字幕\build\*.py |
| Sortie vidéo | 字幕\输出\<nom_de_tâche>\ (un dossier par tâche, nom de livraison lisible en chinois) |
| ffmpeg | C:\Users\35530\AppData\Local\Microsoft\WinGet\Packages\Gyan.FFmpeg_Microsoft.Winget.Source_8wekyb3d8bbwe\ffmpeg-9.0-full_build\bin\ffmpeg.exe |
| python | C:\Users\35530\.dsh\dsh-runtimes\dsh-primary-runtime\dependencies\python\python.exe (PIL 12.3 / numpy 2.3, pas de cv2) |
2. Processus principal en sept étapes
① Sonder la source ffprobe résolution/fréquence d'images/durée/couleurs ; test de décodage pour vérifier l'intégrité du fichier
② Choisir un segment Couplet musical vs chorégraphie ; échantillon 5s / 30s / vidéo complète
③ Synchroniser les paroles Temps absolu LRC → temps relatif ASS en soustrayant le début du segment
④ Définir le style Se référer à S1–S6 (voir style-frames-compare) ; d'abord image fixe, puis animation
⑤ Écrire l'ASS Généré par Python ; respecter les règles strictes de format de ass-render-playbook
⑥ Rendre ffmpeg incrustation (ou calque transparent) ; d'abord une validation 5–10s, puis tout le segment
⑦ Valider Extraire des images (au moins 1 par couplet) + assembler une table d'images clés ; vérifier la composition, l'absence de chinois, le cadrage, le fondu de fin
① Sonder la source
$ff='...\ffmpeg.exe'; $fp='...\ffprobe.exe'
& $fp -v error -select_streams v:0 -show_entries stream=width,height,r_frame_rate,nb_frames,pix_fmt,color_space -show_entries format=duration -of default=nw=1 $v
& $ff -v error -i $v -map 0:v:0 -c copy -f null NUL # « File ended prematurely » = fichier tronqué
- Les sources de ce projet sont toutes en 2560×1080 / 30fps / h264 yuv420p / bt709, ultra-large 64:27.
- Une vidéo de 165s ≈ 4956 frames ; une vidéo de 30s = 900 frames.
② Choisir un segment
- Premier couplet LRC :
36.892 / 40.366 / 44.003 / 47.577 / 51.179 / 54.698 / 58.309 / 61.926, se termine vers ~66s. - Échantillon 5s souvent utilisé :
0:58.2–1:03.2; échantillon 30s :0:36.5–1:06.5; vidéo complète : 0–154.6s (l'ancien fichier ne va que jusqu'à 137s). - Découpage :
-ss 36.5 -t 30 -i src -vf "eq=brightness=-0.05:contrast=1.04:saturation=1.02" -c:v libx264 -crf 16 -pix_fmt yuv420p(légère réduction de la luminosité pour faire ressortir les textes blancs/crème ; l'étalonnage complet est traité séparément dans subject-color-grade)
③ Synchroniser les paroles
Les LRC sont des temps absolus ; l'ASS utilise les temps relatifs au début du segment. Par exemple, si le segment commence à 36.5s, alors 36.892 → 0.392s.
Un repère par couplet ; à l'intérieur d'un couplet, diviser en plusieurs événements par mot (voir ci-dessous). L'événement de fin doit être coupé 0.14–0.4s avant pour éviter le chevauchement entre lignes.
④ Définir le style
- Lire d'abord la compétence
style-frames-compare, choisir S1–S6 selon l'ambiance souhaitée, produire d'abord une image fixe à montrer à l'utilisateur. - Contrainte importante : quand l'utilisateur dit explicitement « pas de chinois », ne garder que les paroles originales en anglais/japonais ; le personnage au centre, les gros caractères dans les zones de sécurité latérales et les coins.
- Générateurs réutilisables existants :
styles_anim.py(animation 5s de S2/S4/S6),flare_wide.py(explosion),neon_wide.py(néon),avoid_side2.py(évitement total),kpop_styles.py(images fixes),art_frames.py(images fixes artistiques).
⑤ Écrire l'ASS
- Utiliser Python (plus fiable que l'écriture manuelle) : définir une classe
Ass+ assistantsword()/rect(), puiswrite(). - Règles strictes, modèles et pièges voir
ass-render-playbook(format de tempsH:MM:SS.cc, valeurs de couleur de style sans&final, chemins de polices relatifs, etc.).
⑥ Rendre
- Répertoire de travail = répertoire de sortie ; nom de fichier ASS en ASCII ; répertoire des polices relatif :
cd "字幕\输出\S4S6_30s"
& $ff -v error -y -i _base_30s.mp4 -vf "ass=_s4.ass:fontsdir=fonts" `
-c:v libx264 -preset medium -crf 16 -pix_fmt yuv420p -movflags +faststart S4_30s.mp4
- Calque transparent (pour post-production) :
-f lavfi -i "[email protected]:s=2560x1080:r=30,format=rgba" -vf "ass=x.ass:alpha=1"+ VP9yuva420p(détails dans ass-render-playbook).
⑦ Liste de contrôle de validation
- La durée
ffprobecorrespond à celle prévue (5.000 / 30.000 / 154.6) - Extraire des images : au moins 1 par couplet, confirmer que le texte apparaît réellement, qu'il est bien positionné, sans caractères illisibles
- Si l'utilisateur demande « pas de chinois » extraire 2–3 images pour confirmer qu'il n'y a que de l'anglais/japonais
- Le visage/corps du personnage n'est pas obstrué (vérifier particulièrement les plans rapprochés et gros plans)
- La dernière ligne s'estompe avant la fin (par exemple avant 29.86s), ne laisse aucun résidu de texte
- Assembler une
关键帧.jpg(2×2 ou 2×3, chaque case 1280×540, avec étiquettes) pour faciliter la consultation par l'utilisateur - Nom de fichier lisible + fichier md d'explication livré ensemble
3. Types de tâches → Livrables
| Tâche | Livrable |
|---|---|
| Proposition d'image fixe | N images 2560×1080 jpg + 总览.jpg + md d'explication |
| Échantillon 5s | 1–3 vidéos 5s mp4 + vidéo comparative + table d'images clés |
| Échantillon 30s | 1–2 vidéos 30s mp4 (900 frames) + version comparative + table d'images clés + md d'explication |
| Livraison en paire (courant) | Pour chaque style, 2 vidéos : X_有背景_30s.mp4 (incrustation H.264) + X_纯字幕_透明_30s.webm (VP9 alpha) ; N styles × 2 vidéos, avec 纯字幕_透明预览.jpg (aperçu de synthèse avec damier) |
| Vidéo complète | Sous-titres ASS + mp4 incrusté / webm transparent + explication |
| Étalonnage | mp4 étalonné + images comparatives + description des paramètres / LUT |
Rendu de la version transparente (même ASS que la version avec fond, parfaitement synchrone image par image) :
& $ff -v error -y -f lavfi -i "[email protected]:s=2560x1080:r=30,format=rgba" ` -vf "ass=_s4.ass:alpha=1:fontsdir=fonts" -t 30 -c:v libvpx-vp9 -pix_fmt yuva420p ` -b:v 0 -crf 30 -row-mt 1 -auto-alt-ref 0 -metadata:s:v:0 alpha_mode=1 OUT.webmVérifier l'alpha :
ffmpeg -c:v libvpx-vp9 -ss 12.4 -i OUT.webm -frames:v 1 -pix_fmt rgba f.png, PIL vérifie alpha min=0 / max=255, couverture>0 ; l'extraction d'image doit explicitement utiliser-c:v libvpx-vp9, sinon l'alpha est perdue et tout devient 255.
4. Parallélisation (sous-agents) — Convention
Méthode standard lorsque l'utilisateur dit « faites-le en parallèle avec des sous-agents » :
- L'agent principal prépare d'abord le média de base partagé (découpé, assombri uniformément) ainsi qu'une copie de
fonts/et la feuille de repères (tableau des temps relatifs) ; - Chaque sous-agent de style reçoit dans le prompt : le chemin d'entrée, le nom de fichier de sortie (ex.
S4_30s.mp4), les règles strictes ASS, le tableau de la timeline, les exigences de validation ; - Chaque sous-agent écrit seulement ses propres fichiers de préfixe, sans se chevaucher ;
- L'agent principal, une fois tout récolté, produit la vidéo comparative, la table d'images clés, l'explication, et procède à la validation unifiée par extraction d'images. Testé : Un style unique de 30s (2560×1080, 8 couplets, environ 40–60 dialogues) prend environ 10–20 minutes de la conception au produit fini ; deux sous-agents en parallèle ≈ le temps du plus lent.