mirror of
https://github.com/R0m1k3/Socialflow.git
synced 2026-10-19 21:18:18 +02:00
feat(reels): voix Gemini complète, sous-titres mot à mot et rendu de qualité
Service ffmpeg-api réécrit (ffmpeg-service/app/) : - Appels FFmpeg asynchrones : le service ne se fige plus pendant un rendu - Vidéo récupérée par téléchargement (GET /files/…) au lieu de base64 en JSON - Vraies erreurs HTTP ; échec explicite si la voix demandée est impossible - 30 voix Gemini + ton de lecture (dynamique, chaleureux, promo, calme), clé en en-tête, modèle configurable avec repli - Edge TTS 7 (minutage des mots restauré), secours en voix françaises - Voix traitée : filtre, compression, niveau constant ; musique bouclée et baissée automatiquement sous la voix ; mix final à -14 LUFS - Sous-titres calés mot à mot (Whisper pour Gemini et la voix d'origine, à la place de ffsubsync), style Montserrat, placés hors des boutons Reels - Vidéo : plus de retouche luminosité forcée, scaling lanczos, HDR iPhone converti, BT.709, AAC 48 kHz 192k ; la vidéo s'allonge si la voix dépasse - Grand logo de fin affiché après la voix ; FFmpeg 7.0.2 épinglé, polices et modèle Whisper intégrés à l'image ; tests pytest et ruff Application : - Sélecteur de voix partagé (4 pages) : moteur, 30 voix, ton, écoute - Reel images : minutage réel des mots, interrupteur voix respecté - sync-info ne génère plus de voix à chaque frappe (estimation locale) - Stabilisation désactivée par défaut, route /reels/preview inutilisée retirée - Log « [ReelQueue] Worker démarré » pour vérifier la version déployée Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Ze4bs7tpF1KGWUk6ZZSZ4
This commit is contained in:
47 files changed
+2206
-2285
No files matched your search
@@ -0,0 +1,60 @@
|
||||
"""Traitement de la voix : filtrage, compression et niveau sonore constant."""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from . import proc
|
||||
|
||||
# Coupe les basses inutiles, lisse la dynamique et amène la voix à -16 LUFS :
|
||||
# elle reste intelligible par-dessus la musique sans saturer.
|
||||
VOICE_CHAIN = (
|
||||
"highpass=f=80,"
|
||||
"acompressor=threshold=0.1:ratio=3:attack=5:release=120:makeup=2,"
|
||||
"loudnorm=I=-16:TP=-1.5:LRA=7,"
|
||||
"aresample=48000"
|
||||
)
|
||||
|
||||
|
||||
async def process_voice(source: Path, target: Path) -> None:
|
||||
"""Produit un WAV 48 kHz mono prêt à mixer."""
|
||||
await proc.run(
|
||||
[
|
||||
"ffmpeg",
|
||||
"-y",
|
||||
"-hide_banner",
|
||||
"-loglevel",
|
||||
"error",
|
||||
"-i",
|
||||
str(source),
|
||||
"-af",
|
||||
VOICE_CHAIN,
|
||||
"-ac",
|
||||
"1",
|
||||
"-ar",
|
||||
"48000",
|
||||
"-c:a",
|
||||
"pcm_s16le",
|
||||
str(target),
|
||||
],
|
||||
timeout=120,
|
||||
)
|
||||
|
||||
|
||||
async def encode_preview(source: Path, target: Path) -> None:
|
||||
"""MP3 de bonne qualité pour l'écoute dans le navigateur."""
|
||||
await proc.run(
|
||||
[
|
||||
"ffmpeg",
|
||||
"-y",
|
||||
"-hide_banner",
|
||||
"-loglevel",
|
||||
"error",
|
||||
"-i",
|
||||
str(source),
|
||||
"-c:a",
|
||||
"libmp3lame",
|
||||
"-b:a",
|
||||
"160k",
|
||||
str(target),
|
||||
],
|
||||
timeout=120,
|
||||
)
|
||||
Reference in new issue
Block a user