binaryMao commited on
Commit
e4a7c99
·
verified ·
1 Parent(s): 14776cb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +26 -16
app.py CHANGED
@@ -1,6 +1,9 @@
1
  # -*- coding: utf-8 -*-
2
  """
3
- ROBOTSMALI — Sous-titrage Bambara (VERSION COMPLÈTE V6.5 - INTERFACE ÉPURÉE)
 
 
 
4
  """
5
  import os
6
  import shlex
@@ -41,12 +44,12 @@ VIDEO_EXAMPLES = [
41
 
42
  _cache = {}
43
 
44
- # ---------------------------- # FONCTIONS IA & FFmpeg # ----------------------------
45
 
46
  def run_cmd(cmd):
47
  res = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
48
  if res.returncode != 0:
49
- raise RuntimeError(f"FFmpeg: {res.stdout}")
50
  return res.stdout
51
 
52
  def load_model(name):
@@ -71,8 +74,7 @@ def load_model(name):
71
  return model
72
 
73
  def burn_subtitles(video_path, words, duration):
74
- # Sauvegarde dans le dossier de travail pour la stabilité
75
- out_name = f"resultat_robotsmali.mp4"
76
  out_path = os.path.abspath(out_name)
77
 
78
  chunk_size = 7
@@ -102,9 +104,12 @@ def burn_subtitles(video_path, words, duration):
102
 
103
  def pipeline(video_input, model_name):
104
  try:
105
- if not video_input: return "❌ Vidéo introuvable", None
 
 
106
 
107
- yield "⏳ Phase 1/3 : Analyse Audio...", None
 
108
  wav_path = os.path.abspath("temp_audio.wav")
109
  run_cmd(f'ffmpeg -hide_banner -loglevel error -y -i {shlex.quote(video_input)} -vn -ac 1 -ar 16000 -f wav {shlex.quote(wav_path)}')
110
 
@@ -112,26 +117,30 @@ def pipeline(video_input, model_name):
112
  shell=True, stdout=subprocess.PIPE, text=True).stdout
113
  duration = float(dur_out.strip()) if dur_out.strip() else 10.0
114
 
115
- yield f"⏳ Phase 2/3 : Transcription {model_name}...", None
 
116
  model = load_model(model_name)
117
  res = model.transcribe([wav_path])[0]
118
  text = res.text if hasattr(res, 'text') else str(res)
119
  words = [w for w in text.split() if len(w) > 1]
120
 
121
- if not words: return "⚠️ Pas de parole détectée", None
 
 
122
 
123
- yield "⏳ Phase 3/3 : Encodage de la vidéo...", None
 
124
  final_v = burn_subtitles(video_input, words, duration)
125
 
126
  if os.path.exists(wav_path): os.remove(wav_path)
127
 
128
- yield "✅ Sous-titrage terminé !", final_v
129
 
130
  except Exception as e:
131
  traceback.print_exc()
132
- yield f"❌ Erreur: {str(e)}", None
133
 
134
- # ---------------------------- # INTERFACE # ----------------------------
135
 
136
  custom_css = """
137
  body { background-color: #0b0e14; }
@@ -150,11 +159,12 @@ with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
150
  v_in = gr.Video(label=None, mirror_webcam=False)
151
  m_sel = gr.Dropdown(list(MODELS.keys()), value="Soloba V1 (CTC)", label="Modèle IA")
152
  btn = gr.Button("🚀 GÉNÉRER", variant="primary")
 
153
  with gr.Column():
154
  gr.Markdown("### 📤 Résultat")
155
- status = gr.Markdown("*Prêt*")
156
- # Une seule case vidéo pour le résultat
157
- v_out = gr.Video(label="Vidéo finale (lecture et téléchargement)")
158
 
159
  gr.Examples(examples=VIDEO_EXAMPLES, inputs=[v_in, m_sel], cache_examples=False)
160
 
 
1
  # -*- coding: utf-8 -*-
2
  """
3
+ ROBOTSMALI — Sous-titrage Bambara (VERSION COMPLÈTE V6.6)
4
+ - Interface à deux colonnes (Entrée / Résultat unique)
5
+ - Conservation du Statut détaillé (Phases de traitement)
6
+ - Tous les modèles RobotsMali inclus
7
  """
8
  import os
9
  import shlex
 
44
 
45
  _cache = {}
46
 
47
+ # ---------------------------- # FONCTIONS TECHNIQUES # ----------------------------
48
 
49
  def run_cmd(cmd):
50
  res = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
51
  if res.returncode != 0:
52
+ raise RuntimeError(f"FFmpeg Error: {res.stdout}")
53
  return res.stdout
54
 
55
  def load_model(name):
 
74
  return model
75
 
76
  def burn_subtitles(video_path, words, duration):
77
+ out_name = f"robotsmali_output_{int(time.time())}.mp4"
 
78
  out_path = os.path.abspath(out_name)
79
 
80
  chunk_size = 7
 
104
 
105
  def pipeline(video_input, model_name):
106
  try:
107
+ if not video_input:
108
+ yield "❌ Erreur : Aucune vidéo chargée.", None
109
+ return
110
 
111
+ # Phase 1 : Audio
112
+ yield "⏳ Phase 1/3 : Analyse et extraction de l'audio...", None
113
  wav_path = os.path.abspath("temp_audio.wav")
114
  run_cmd(f'ffmpeg -hide_banner -loglevel error -y -i {shlex.quote(video_input)} -vn -ac 1 -ar 16000 -f wav {shlex.quote(wav_path)}')
115
 
 
117
  shell=True, stdout=subprocess.PIPE, text=True).stdout
118
  duration = float(dur_out.strip()) if dur_out.strip() else 10.0
119
 
120
+ # Phase 2 : Transcription
121
+ yield f"⏳ Phase 2/3 : Transcription IA ({model_name})...", None
122
  model = load_model(model_name)
123
  res = model.transcribe([wav_path])[0]
124
  text = res.text if hasattr(res, 'text') else str(res)
125
  words = [w for w in text.split() if len(w) > 1]
126
 
127
+ if not words:
128
+ yield "⚠️ Phase 2 : Aucune parole détectée dans l'audio.", None
129
+ return
130
 
131
+ # Phase 3 : Encodage
132
+ yield "⏳ Phase 3/3 : Génération de la vidéo sous-titrée...", None
133
  final_v = burn_subtitles(video_input, words, duration)
134
 
135
  if os.path.exists(wav_path): os.remove(wav_path)
136
 
137
+ yield "✅ Traitement terminé avec succès !", final_v
138
 
139
  except Exception as e:
140
  traceback.print_exc()
141
+ yield f"❌ Erreur critique : {str(e)}", None
142
 
143
+ # ---------------------------- # INTERFACE GRADIO # ----------------------------
144
 
145
  custom_css = """
146
  body { background-color: #0b0e14; }
 
159
  v_in = gr.Video(label=None, mirror_webcam=False)
160
  m_sel = gr.Dropdown(list(MODELS.keys()), value="Soloba V1 (CTC)", label="Modèle IA")
161
  btn = gr.Button("🚀 GÉNÉRER", variant="primary")
162
+
163
  with gr.Column():
164
  gr.Markdown("### 📤 Résultat")
165
+ # Le Statut est conservé ici pour informer sur l'état des fichiers audio/vidéo
166
+ status = gr.Markdown("### État\n*En attente de démarrage...*")
167
+ v_out = gr.Video(label="Vidéo finale")
168
 
169
  gr.Examples(examples=VIDEO_EXAMPLES, inputs=[v_in, m_sel], cache_examples=False)
170