AlserFurma commited on
Commit
80564a8
·
verified ·
1 Parent(s): 194447e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +61 -25
app.py CHANGED
@@ -8,6 +8,7 @@ from transformers import VitsModel, AutoTokenizer, pipeline
8
  import scipy.io.wavfile as wavfile
9
  import traceback
10
  import random
 
11
 
12
  # =========================
13
  # Параметры
@@ -88,7 +89,6 @@ def generate_quiz(text: str):
88
  raise ValueError(f"Ошибка генерации вопроса:\n{str(e)}\nМодель вернула: {out}")
89
 
90
 
91
-
92
  def synthesize_audio(text_ru: str):
93
  """Переводит русскую строку на казахский, синтезирует аудио и возвращает путь к файлу .wav"""
94
  translation = translator(text_ru, src_lang="rus_Cyrl", tgt_lang="kaz_Cyrl")
@@ -108,23 +108,50 @@ def synthesize_audio(text_ru: str):
108
  return tmpf.name
109
 
110
 
111
- def make_talking_head(image_path: str, audio_path: str):
112
  """Вызывает SkyReels/Talking Head space и возвращает путь или URL видео."""
113
- client = Client(TALKING_HEAD_SPACE)
114
- result = client.predict(
115
- image_path=handle_file(image_path),
116
- audio_path=handle_file(audio_path),
117
- guidance_scale=3.0,
118
- steps=10,
119
- api_name="/process_image_audio"
120
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
 
122
- if isinstance(result, dict) and "video" in result:
123
- return result["video"]
124
- elif isinstance(result, str):
125
- return result
126
- else:
127
- raise ValueError(f"Unexpected talking head result: {type(result)}")
128
 
129
 
130
  # =========================
@@ -152,14 +179,16 @@ def start_lesson(image: Image.Image, text: str, state):
152
  state_data = {'image_path': image_path, 'correct': correct, 'options': options}
153
 
154
  # удаляем временный аудио файл
155
- try: os.remove(audio_path)
156
- except: pass
 
 
157
 
158
- return video_path, question, options, state_data, state_data
159
 
160
  except Exception as e:
161
  traceback.print_exc()
162
- return None, f"Ошибка: {e}", [], [], state
163
 
164
 
165
  def answer_selected(selected_option: str, state):
@@ -181,8 +210,10 @@ def answer_selected(selected_option: str, state):
181
  audio_path = synthesize_audio(reaction_ru)
182
  reaction_video = make_talking_head(image_path, audio_path)
183
 
184
- try: os.remove(audio_path)
185
- except: pass
 
 
186
 
187
  return reaction_video, display_message
188
 
@@ -227,10 +258,15 @@ with gr.Blocks() as demo:
227
  outputs=[out_video, out_question, btn_opt1, btn_opt2, lesson_state]
228
  )
229
 
230
- btn_opt1.click(fn=answer_selected, inputs=[btn_opt1, lesson_state], outputs=[out_reaction_video, out_status])
231
- btn_opt2.click(fn=answer_selected, inputs=[btn_opt2, lesson_state], outputs=[out_reaction_video, out_status])
 
 
 
 
 
232
 
233
  demo.load(lambda: "Готово", outputs=out_status)
234
 
235
  if __name__ == '__main__':
236
- demo.launch()
 
8
  import scipy.io.wavfile as wavfile
9
  import traceback
10
  import random
11
+ import time
12
 
13
  # =========================
14
  # Параметры
 
89
  raise ValueError(f"Ошибка генерации вопроса:\n{str(e)}\nМодель вернула: {out}")
90
 
91
 
 
92
  def synthesize_audio(text_ru: str):
93
  """Переводит русскую строку на казахский, синтезирует аудио и возвращает путь к файлу .wav"""
94
  translation = translator(text_ru, src_lang="rus_Cyrl", tgt_lang="kaz_Cyrl")
 
108
  return tmpf.name
109
 
110
 
111
+ def make_talking_head(image_path: str, audio_path: str, max_retries=3):
112
  """Вызывает SkyReels/Talking Head space и возвращает путь или URL видео."""
113
+ for attempt in range(max_retries):
114
+ try:
115
+ client = Client(TALKING_HEAD_SPACE)
116
+ result = client.predict(
117
+ image_path=handle_file(image_path),
118
+ audio_path=handle_file(audio_path),
119
+ guidance_scale=3.0,
120
+ steps=10,
121
+ api_name="/process_image_audio"
122
+ )
123
+
124
+ # Отладочный вывод
125
+ print(f"Result type: {type(result)}")
126
+ print(f"Result content: {result}")
127
+
128
+ # Обработка различных форматов результата
129
+ if isinstance(result, tuple):
130
+ # Если результат - кортеж, берем первый элемент
131
+ video_path = result[0]
132
+ if isinstance(video_path, dict) and "video" in video_path:
133
+ return video_path["video"]
134
+ elif isinstance(video_path, str):
135
+ return video_path
136
+ else:
137
+ # Если первый элемент не подходит, пробуем найти путь к видео в кортеже
138
+ for item in result:
139
+ if isinstance(item, str) and (item.endswith('.mp4') or item.endswith('.webm') or os.path.exists(str(item))):
140
+ return item
141
+ raise ValueError(f"Не удалось найти видео в результате: {result}")
142
+ elif isinstance(result, dict) and "video" in result:
143
+ return result["video"]
144
+ elif isinstance(result, str):
145
+ return result
146
+ else:
147
+ raise ValueError(f"Unexpected talking head result: {type(result)}, value: {result}")
148
 
149
+ except Exception as e:
150
+ if attempt < max_retries - 1:
151
+ print(f"Попытка {attempt + 1} не удалась: {e}. Повторяю через 2 секунды...")
152
+ time.sleep(2)
153
+ else:
154
+ raise Exception(f"Ошибка после {max_retries} попыток: {str(e)}")
155
 
156
 
157
  # =========================
 
179
  state_data = {'image_path': image_path, 'correct': correct, 'options': options}
180
 
181
  # удаляем временный аудио файл
182
+ try:
183
+ os.remove(audio_path)
184
+ except:
185
+ pass
186
 
187
+ return video_path, question, gr.Button(options[0], visible=True), gr.Button(options[1], visible=True), state_data
188
 
189
  except Exception as e:
190
  traceback.print_exc()
191
+ return None, f"Ошибка: {e}", gr.Button("Вариант 1", visible=True), gr.Button("Вариант 2", visible=True), state
192
 
193
 
194
  def answer_selected(selected_option: str, state):
 
210
  audio_path = synthesize_audio(reaction_ru)
211
  reaction_video = make_talking_head(image_path, audio_path)
212
 
213
+ try:
214
+ os.remove(audio_path)
215
+ except:
216
+ pass
217
 
218
  return reaction_video, display_message
219
 
 
258
  outputs=[out_video, out_question, btn_opt1, btn_opt2, lesson_state]
259
  )
260
 
261
+ btn_opt1.click(fn=lambda state: answer_selected(state.get('options', [''])[0] if state else '', state),
262
+ inputs=[lesson_state],
263
+ outputs=[out_reaction_video, out_status])
264
+
265
+ btn_opt2.click(fn=lambda state: answer_selected(state.get('options', [''])[1] if state and len(state.get('options', [])) > 1 else '', state),
266
+ inputs=[lesson_state],
267
+ outputs=[out_reaction_video, out_status])
268
 
269
  demo.load(lambda: "Готово", outputs=out_status)
270
 
271
  if __name__ == '__main__':
272
+ demo.launch(server_name="0.0.0.0", server_port=7860)