omarbajouk commited on
Commit
4ecdcb7
·
verified ·
1 Parent(s): 5a68a09

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +23 -13
app.py CHANGED
@@ -333,14 +333,14 @@ def _write_video_with_fallback(final_clip, out_path_base, fps=25):
333
  raise RuntimeError(last_err or "FFmpeg a échoué")
334
 
335
  # ============================================================
336
- # BUILD CAPSULE — Pipeline complet
337
  # ============================================================
338
  def build_capsule(titre, sous_titre, texte_voix, texte_ecran, theme,
339
  image_fond=None, logo_path=None, logo_pos="haut-gauche",
340
  fond_mode="plein écran",
341
  image_presentateur=None, voix_type="Féminine",
342
  position_presentateur="bottom-right", plein=False,
343
- moteur_voix="Kokoro (HuggingFace, offline)", langue="fr",speaker=None):
344
 
345
  # 1) TTS (Parler-TTS multivoix ou fallback)
346
  try:
@@ -349,9 +349,17 @@ def build_capsule(titre, sous_titre, texte_voix, texte_ecran, theme,
349
  print(f"[Capsule] Erreur TTS Parler ({e}), fallback gTTS.")
350
  audio_mp = tts_gtts(texte_voix, lang=langue)
351
 
 
 
 
 
 
 
 
352
 
353
  # 2) Fond (PIL)
354
- fond_path = make_background(titre, sous_titre, texte_ecran, theme, logo_path, logo_pos, image_fond, fond_mode)
 
355
 
356
  # 3) MoviePy (imports lents ici seulement)
357
  from moviepy.editor import ImageClip, AudioFileClip, CompositeVideoClip, VideoFileClip
@@ -369,8 +377,7 @@ def build_capsule(titre, sous_titre, texte_voix, texte_ecran, theme,
369
  if vpath and os.path.exists(vpath):
370
  v = VideoFileClip(vpath).without_audio().fx(vfx.loop, duration=dur)
371
  if plein:
372
- v = v.resize((W, H))
373
- v = v.set_position(("center", "center"))
374
  else:
375
  v = v.resize(width=520)
376
  pos_map = {
@@ -389,28 +396,31 @@ def build_capsule(titre, sous_titre, texte_voix, texte_ecran, theme,
389
  out_base = os.path.join(OUT_DIR, name)
390
  out = _write_video_with_fallback(final, out_base, fps=target_fps)
391
 
392
- # 6) SRT + manifest
393
  srt_path = write_srt(texte_voix, dur)
394
  capsules.append({
395
  "file": out,
396
  "title": titre,
397
  "langue": langue,
398
- "voice": voix_type,
399
  "theme": theme,
400
  "duration": round(dur, 1)
401
  })
402
  _save_manifest()
403
 
404
- # Nettoyage
405
  try:
406
- audio.close(); final.close(); bg.close()
 
 
407
  if os.path.exists(audio_mp): os.remove(audio_mp)
408
- if os.path.exists(audio_wav): os.remove(audio_wav)
409
- except Exception:
410
- pass
411
  gc.collect()
412
 
413
- return out, f"✅ Capsule {langue.upper()} créée ({dur:.1f}s, voix {voix_type})", srt_path
 
414
 
415
  # ============================================================
416
  # GESTION / ASSEMBLAGE
 
333
  raise RuntimeError(last_err or "FFmpeg a échoué")
334
 
335
  # ============================================================
336
+ # BUILD CAPSULE — Pipeline complet (corrigé)
337
  # ============================================================
338
  def build_capsule(titre, sous_titre, texte_voix, texte_ecran, theme,
339
  image_fond=None, logo_path=None, logo_pos="haut-gauche",
340
  fond_mode="plein écran",
341
  image_presentateur=None, voix_type="Féminine",
342
  position_presentateur="bottom-right", plein=False,
343
+ moteur_voix="Parler-TTS (offline)", langue="fr", speaker=None):
344
 
345
  # 1) TTS (Parler-TTS multivoix ou fallback)
346
  try:
 
349
  print(f"[Capsule] Erreur TTS Parler ({e}), fallback gTTS.")
350
  audio_mp = tts_gtts(texte_voix, lang=langue)
351
 
352
+ # 🔧 S'assurer qu'on a un WAV standard
353
+ audio_wav = audio_mp
354
+ if not audio_mp.lower().endswith(".wav"):
355
+ try:
356
+ audio_wav = _normalize_audio_to_wav(audio_mp)
357
+ except Exception as e:
358
+ print(f"[Audio] Normalisation échouée ({e}), on garde {audio_mp}")
359
 
360
  # 2) Fond (PIL)
361
+ fond_path = make_background(titre, sous_titre, texte_ecran, theme,
362
+ logo_path, logo_pos, image_fond, fond_mode)
363
 
364
  # 3) MoviePy (imports lents ici seulement)
365
  from moviepy.editor import ImageClip, AudioFileClip, CompositeVideoClip, VideoFileClip
 
377
  if vpath and os.path.exists(vpath):
378
  v = VideoFileClip(vpath).without_audio().fx(vfx.loop, duration=dur)
379
  if plein:
380
+ v = v.resize((W, H)).set_position(("center", "center"))
 
381
  else:
382
  v = v.resize(width=520)
383
  pos_map = {
 
396
  out_base = os.path.join(OUT_DIR, name)
397
  out = _write_video_with_fallback(final, out_base, fps=target_fps)
398
 
399
+ # 6) Sous-titres + manifest
400
  srt_path = write_srt(texte_voix, dur)
401
  capsules.append({
402
  "file": out,
403
  "title": titre,
404
  "langue": langue,
405
+ "voice": speaker or voix_type,
406
  "theme": theme,
407
  "duration": round(dur, 1)
408
  })
409
  _save_manifest()
410
 
411
+ # 7) Nettoyage
412
  try:
413
+ audio.close()
414
+ final.close()
415
+ bg.close()
416
  if os.path.exists(audio_mp): os.remove(audio_mp)
417
+ if audio_wav != audio_mp and os.path.exists(audio_wav): os.remove(audio_wav)
418
+ except Exception as e:
419
+ print(f"[Clean] Erreur nettoyage : {e}")
420
  gc.collect()
421
 
422
+ return out, f"✅ Capsule {langue.upper()} créée ({dur:.1f}s, voix {speaker or voix_type})", srt_path
423
+
424
 
425
  # ============================================================
426
  # GESTION / ASSEMBLAGE