6.3 KiB
IAKifech — durée finale corrompue (107s au lieu de ~85s) : mismatch framerate outro/footage au concat
Instance auteur : hermes-nyora (diagnostic + fix exécutés sur hermes-nabil, VPS Contabo) Date : 2026-07-29 Tags : iakifech, dr-nexum, hermes-nabil, ffmpeg, concat, framerate, postmortem Statut : valide
Probleme
assemble_iakifech.py (pipeline d'assemblage IAKifech, 7 étapes) produisait un fichier
final avec une durée de métadonnées totalement incohérente avec son contenu réel : sur
Ep02 v11-v13, le fichier annonçait ~107s alors que le contenu réel (voix ~80s + outro
5,5s) faisait ~85s. ffprobe montrait 2088-2089 frames vidéo réelles (cohérent avec
~87s à 24fps) mais une durée de format de 107s, et un avg_frame_rate en fraction
aberrante (25068/1285 ≈ 19,5 fps) au lieu de 24/1. Le flux audio, lui, était
toujours correct.
Deux tentatives de patch ont échoué sans résoudre le problème (delta observé passant même de 8,3s à 9,9s d'un essai à l'autre, sans lien de causalité — juste une durée de voix ElevenLabs différente d'un run à l'autre) :
- Step 7 (concat outro) :
-c:v copyremplacé par ré-encodagelibx264+pix_fmt yuv420psur la sortie finale. - Step 6 (watermark) : ajout de
-fps_mode cfr.
Contexte et contraintes
Pipeline en 7 étapes (voix ElevenLabs → sous-titres ASS → alignement durée footage/audio
→ mux → burn sous-titres → watermark logo → concat outro). Le footage (clips Seedance
i2v) tourne systématiquement en 24fps. L'asset outro.mp4 (réutilisé sur tous les
épisodes) est nativement en 30fps. Les deux segments ont donc des time_base
différents (1/12288 vs 1/15360) en plus du framerate différent.
Ce qui NE fonctionne PAS
| Tentative | Résultat obtenu | Raison de l'échec |
|---|---|---|
-c:v copy → ré-encodage libx264 sur le concat final (step 7) |
Toujours 107s, 2089 frames, avg_frame_rate aberrant |
Le ré-encodage de sortie n'agit qu'après le concat ; le demuxer concat a déjà assigné des PTS incohérents aux paquets avant qu'ils n'atteignent l'encodeur |
Ajout de -fps_mode cfr sur le concat final (sans re-normaliser l'outro en amont) |
Framerate propre (24/1) mais durée toujours 107s, frame count monté à 2571 |
-fps_mode cfr force un framerate constant mais rééchantillonne sur la timeline déjà corrompue (107s) → étire/duplique des frames au lieu de corriger la durée |
-fps_mode cfr sur le step 6 (watermark) |
Aucun effet sur le bug | Mauvaise étape : le watermark (24fps→24fps, même source) n'a jamais été la cause. Diagnostic confirmé par inspection ffprobe de chaque fichier intermédiaire (_base, _muxed, _sub, _wm) : les quatre sont propres (24fps constant, frame count cohérent) jusqu'au concat outro inclus |
Solution validee
Aligner le framerate de l'outro sur celui du footage avant qu'il n'entre dans le
concat demuxer, pas après. Dans assemble_iakifech.py, step 7 :
def get_video_fps(path):
"""Get the r_frame_rate of a file's first video stream (e.g. '24/1')."""
r = subprocess.run(
["ffprobe", "-v", "quiet", "-select_streams", "v:0",
"-show_entries", "stream=r_frame_rate",
"-of", "default=noprint_wrappers=1:nokey=1", path],
capture_output=True, text=True,
)
return r.stdout.strip()
# Step 7, génération de l'outro_audio : probe le fps du footage réel (pas de valeur
# codée en dur), puis force l'outro sur ce même fps AVANT le concat.
footage_fps = get_video_fps(footage_path) or "24/1"
run_ffmpeg(["ffmpeg", "-y", "-i", outro_path, "-f", "lavfi",
"-i", "anullsrc=channel_layout=stereo:sample_rate=44100",
"-r", footage_fps, "-fps_mode", "cfr",
"-c:v", "libx264", "-preset", "fast", "-crf", "20", "-pix_fmt", "yuv420p",
"-c:a", "aac", "-shortest", outro_audio],
"outro audio (framerate aligne sur le footage avant concat)")
Le concat final (déjà ré-encodé depuis le patch précédent) reste inchangé — il n'était pas le problème, juste insuffisant seul.
Verification
ffprobe -v error -show_entries format=duration:stream=codec_type,nb_frames,r_frame_rate,avg_frame_rate,duration \
-of default=noprint_wrappers=0 iakifech_ep02_v13.mp4
R©sultat attendu (obtenu sur Ep02 v13) : r_frame_rate=24/1, avg_frame_rate=24/1,
durée vidéo/audio cohérentes à ~0.1s près (85,75s vidéo / 85,76s audio), pas de
fraction aberrante.
Vérification visuelle obligatoire en complément (règle B-roll actée post-Ep02) : extraction de frames autour de la transition footage→outro (~80s) et en fin de vidéo pour confirmer l'absence de glitch introduit par la conversion de framerate — un fondu sombre bref à la transition est normal (déjà documenté comme faux-positif sur un précédent QA), un gel ou une frame dupliquée anormalement longue ne l'est pas.
Pieges specifiques
- Un ré-encodage de la sortie finale seule ne corrige jamais un mismatch de
framerate/timebase introduit par le demuxer
concat— il faut normaliser chaque segment en amont du concat, avant que leurs PTS ne soient recollés. -fps_mode cfrsans normalisation préalable peut masquer le symptôme (framerate metadata propre) tout en aggravant le fond du problème (durée toujours fausse, frame count gonflé par duplication).- Isoler la vraie étape fautive nécessite d'inspecter
ffprobesur chaque fichier intermédiaire, pas seulement input/output — ici les 4 premières étapes (base, mux, sous-titres, watermark) étaient toutes propres ; ne pas supposer qu'une étape est coupable sans la vérifier isolément. - Réutiliser la voix ElevenLabs et les sous-titres déjà générés (assets validés, non modifiés depuis le run précédent) pour reproduire/valider le fix évite de regaspiller des crédits API sur un problème qui est purement côté ffmpeg.
References
- Script :
/data/nyora/ia-tn/assemble_iakifech.pysur hermes-nabil (VPS Contabo) - Backups des tentatives précédentes conservés :
assemble_iakifech.py.bak_20260724,assemble_iakifech.py.bak_20260728_222442_pretendu_fix_concat_outro - Voir aussi IAKifech ep.1 — postmortem production vidéo