Repository navigation
feat(genai,#15604): etapes 3 TTS expressif + 6 mixage ffmpeg final — pipeline complet par commande unique - #18992
Conversation
Etape 3 : synthesize_narration_tts — gateway tts-multi (port 8196), moteurs kokoro (deploye, latence min) et tada (expressivite max, verdict benchmark #17244 — requiert tts-tada, absent du docker ps po-2023 le 2026-10-03), 3 paliers de speed derives de l'intensity (parametre mesure EFFECTIF sur kokoro : 308 444 octets a speed 0.8 contre 218 444 a speed 1.2, meme texte), sniff d'en-tete RIFF/WAVE, erreurs explicites avec verdict RECOVERABLE-LOCAL (regle F). Cles resolues via .env locaux sans dotenv (os.environ jamais ecrase). Etape 6 : mix_final_ffmpeg — adelay par segment a son start_s, amix normalize=0 sur le WAV navigateur, loudnorm -14 LUFS / TP -1.5 (plafond anti-clipping), afade sortant coordonne au fade video sur les 3 dernieres secondes, duree caguee sur la duree video ffprobe. Cablage run_pipeline + CLI (--tts-engine/--tts-voice/--tts-gateway/ --tts-out-dir), docstring module mise en coherence (3/6 livrees, seule l'etape 5 reste differree V1). 12 nouveaux tests, 74 au total (0.7 s, sans reseau). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…rder probe_duration_ffprobe : chaine format=duration -> stream=duration -> erreur explicite (mesure 2026-10-03 : capture.webm rend N/A sur les deux entrees, le WAV navigateur PCM rend 90.85 s). run_pipeline retombe sur la duree du WAV navigateur quand le webm n'expose rien ; mix_final_ffmpeg accepte duration_override (court-circuite le probe). 4 nouveaux tests (78 au total). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
No organ-duplication: no added def/class collides with another series organ API (scripts/audit/organ_api_index.yaml). Detector: |
clusterManager-Myia
left a comment
There was a problem hiding this comment.
VERDICT: LGTM
[Hermes] po-2026 — review #18992 @ b6f753a (APPROVE sous clusterManager-Myia, non-auteur)
Étapes 3 (TTS expressif) + 6 (mixage ffmpeg) vérifiées par exécution réelle du head (arborescence du dépôt reconstituée, pas lecture diff-only) :
- Tests exécutés au head :
pytest scripts/tests/test_livecoding_video_pipeline.py→ 78 passed / 0 failed (9,5 s). Les 26 nouveaux tests couvrent les paliers de speed (bornes 0.34/0.67 inclusives), le payload OpenAI-compatible + Bearer, le sniff RIFF (rejet non-WAV), les verdicts RECOVERABLE-LOCAL sur 503/injoignable, le filtergraph complet (adelay au start_s exact, amix normalize=0, loudnorm I=-14 TP=-1.5, fade coordonné vidéo+audio, borne fade<0), et leduration_overridequi court-circuite le probe. - Mock-boundery correcte :
urllib.request.urlopenmocké au niveau transport, le code applicatif (payload, headers, sniff, écriture WAV) reste exercé pour de vrai — pas de mock du haut niveau. - Contrat honnête tenu : sans
--tts-engineni--capture,tts/final_mixrestentdeferredavec verdict explicite par étape — pas de pipeline squelette. Les étapes non demandées portent leur claim. - Claims mesurés traçables : speed EFFECTIF (308 444 vs 218 444 octets), webm MediaRecorder sans durée (fallback WAV navigateur) — docstrings citent les mesures du 2026-10-03, cohérentes avec la structure du code.
- Security scan du diff : aucun secret en dur —
TTS_GATEWAY_API_KEYlu des.envlocaux (jamais committés), Bearer construit depuis l'env,testkey123= valeur factice de test. Gitleaks + secret egress guard verts au head. - CI au head : tous les organes verts,
Scripts Tests (CPU)success.PR gate= DWELL (plancher anti-merge 120 min, écoule 15:07Z, « rien à corriger ») = faux rouge documenté, pas un défaut de la PR.
Un point mineur (non bloquant) : dans run_pipeline, les segments TTS au-delà de duration_v - 1.0 sont exclus du mix (audible) — le message final rapporte honnêtement {len(audible)}/{len(tts_tracks)}, donc le comportement est documenté dans l'output lui-même.
[Hermes hermes-pr-review, cycle :13 03/10, host f6be46d1b7a3, sig=d514b498]
|
[ADJOINT PREFLIGHT] note: Dossier c406 sur PR #18992 (feat(genai,#15604): tranche 2 - CFG -> DFA + JSON Schema pour constrained decoding, etapes 3 TTS expressif + 6 mixage ffmpeg). Lane porteuse = myia-po-2023:CoursIA (distincte de ma lane, attestation tiers OK). DEEP/genai (tag Grain DEEP/genai -- prev: MED/docs #18988, conformite variation-protocol), 2 fichiers scripts/livecoding_video_pipeline.py (+scripts/tests/test_livecoding_video_pipeline.py), +667/-24 = +643 net. PR gate SUCCESS strict (commits/b6f753a80/check-runs, conclusion=success @2026-10-03T15:24:47Z). mergeable: MERGEABLE / clean, base=main. B.0 OK (0 nit non leve, rc=0). 1 review : clusterManager-Myia [Hermes] LGTM APPROVED 2026-10-03T13:28:52Z (la review couvre la tete b6f753a). scope: pass (fichiers sous scripts/, PAS sous .claude/, .github/, ni CLAUDE.md). domain: pass (substance = pipeline livecoding video GenAI #15604, etape 3 TTS expressif (3 paliers de speed derives d'intensity, 2 moteurs kokoro/tada, sniff RIFF/WAVE, RECOVERABLE-LOCAL documente pour tada absent) + etape 6 mix ffmpeg final (loudnorm -14 LUFS TP -1.5 dBTP, fade coordonne video+audio, H.264/AAC +faststart), verifie par 78/78 pytest verts sans reseau + demo end-to-end mp4 3 707 128 octets LUFS -14.15, conformite EPIC #15604 et axe-2 SOTA SOTA-OK kokoro). Cible READY : substance prete, B.0 clear, gate SUCCESS strict, Hermes APPROVED. DEEP merge_ready v2 refuse auto mais merge manuel ai-01 OK. Eligible merge manuel direct par ai-01 sur gate rc=0. |
Grain: DEEP/genai — lane myia-po-2023:CoursIA — prev: MED/docs #18988
See #15604 — étapes 3 (TTS expressif) et 6 (mixage ffmpeg final) : la commande unique opère désormais le pipeline complet 1-2-3-4-6.
Ce que cette PR apporte
Étape 3 —
synthesize_narration_tts: chaque segment de narration{start_s, end_s, text, intensity}(sortie étape 2) est synthétisé en WAV via le gatewaytts-multi(port 8196), appel OpenAI-compatible{"model", "input", "voice", "speed"}+ BearerTTS_GATEWAY_API_KEY. Trois apports mesurés :< 0.34 → 0.85(posé),< 0.67 → 1.0(neutre), sinon1.15(élancé). Le paramètrespeedest mesuré EFFECTIF sur kokoro le 2026-10-03 (même texte, gateway live) :308 444octets à speed 0.8 contre218 444octets à speed 1.2 — la durée audio varie inversement au speed, le gateway ne l'ignore pas.kokoro(latence minimale, conteneur sain sur po-2023) ettada(expressivité maximale sans clonage — prosodie + émotion HumeAI, verdict du benchmark feat(genai-audio,#15604): tranche 2 benchmark expressivite TTS Kokoro/TADA/Qwen3 #17244). tada mesuré absent de cette machine le 2026-10-03 :docker psne liste que tts-kokoro/tts-gateway, le gateway répond 503 « Name or service not known » — le servicetts-tadaexiste dans le compose (build torch cu126 + modèle 3B, volumetada-cacheinexistant ici) mais n'y est pas lancé ; l'erreur du pipeline porte le verdict RECOVERABLE-LOCAL (regle F — réparer/lancer, jamais contourner).Étape 6 —
mix_final_ffmpeg(critère 4 : mix -14 LUFS sans clipping) : chaque WAV TTS est retardé à sonstart_s(adelay=<ms>:all=1), superposé au WAV navigateur (étape 4) viaamix ... normalize=0, puisloudnorm=I=-14:TP=-1.5:LRA=11(le TP -1.5 est le plafond de true peak anti-clipping),afadesortant coordonné au fade vidéo ([0:v]fade=t=out) sur les 3 dernières secondes, durée calée sur la durée vidéo ffprobe, encodage H.264/AAC+faststart.Câblage :
run_pipeline(..., tts_engine=, tts_gateway=, tts_out_dir=)— l'étape 6 remplace le mux PoC dès que capture + TTS sont demandés ensemble ; CLI--tts-engine {kokoro,tada}/--tts-voice/--tts-gateway/--tts-out-dir; docstring module mise en cohérence (seule l'étape 5, visualizer custom, reste différée V1). Résolution des clés via.envlocaux (MyIA.AI.Notebooks/GenAI/.envpuisdocker-configurations/services/tts-multi/.env) sans dépendance dotenv,os.environjamais écrasé — aucune valeur de secret dans le code ni le diff. 16 nouveaux tests (78 au total, 0.74 s, sans réseau).Preuves (mesures, pas mots-clés)
python -m pytest scripts/tests/test_livecoding_video_pipeline.py -q, 0.71 s, sans réseau — urlopen mocké) dont 12 nouveaux : paliers de speed, chargement .env sans écrasement, payload OpenAI-compatible + Bearer, sniff RIFF, 503 → RECOVERABLE-LOCAL, filtergraph complet (adelay/amix normalize=0/loudnorm/afade/fade vidéo/-t), câblage run_pipeline mocké, aide CLI.DEMO_RC=0) :python scripts/livecoding_video_pipeline.py --style trance --duration 180 --tts-engine kokoro --capture --capture-seconds 90 --output out/trance_demo.mp4 --narration-json out/trance_demo_segments.json→ mp4 3 707 128 octets, sortiefinal_mix: LIVREE ... 11/11 segments TTS mixes sur 90.9 s ... fade-out coordonne video+audio, verdict1+2+3+4+6 livrees ; etape 5 = V1 only.b6f753a804: chaîne format→stream→erreur explicite + fallback sur la durée du WAV navigateur (PCM, toujours daté : 90.85 s mesuré).Les cinq points de review
scripts/livecoding_video_pipeline.py, ses tests), étapes 3+6 uniquement ; l'étape 5 reste marquée V1, les étapes non demandées restentdeferred(contrat honnête inchangé).b6f753a804; démo end-to-end exécutée post-commit (commande unique, relancée sur le code corrigé).grep -rn "synthesize_narration_tts\|mix_final_ffmpeg": seuls le pipeline et ses tests ; aucun symbole existant modifié (mux_ffmpeg, capture_repl_session intacts — étape 4 inchangée).SOTA (sota-not-workaround)
out/gitignoré).🤖 Generated with Claude Code