tester1hf commited on
Commit
2f74b6f
·
verified ·
1 Parent(s): 4750060

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +95 -24
app.py CHANGED
@@ -17,7 +17,6 @@ from concurrent.futures import ThreadPoolExecutor, as_completed
17
  import threading
18
  from moviepy.editor import AudioFileClip, VideoFileClip, concatenate_videoclips
19
 
20
-
21
  # Streamlit UI
22
  st.set_page_config(
23
  page_title="Прямая линия с Путиным",
@@ -27,7 +26,7 @@ st.set_page_config(
27
  )
28
 
29
  # Configure logging
30
- logging.basicConfig(level=logging.INFO)
31
  logger = logging.getLogger(__name__)
32
  logger.setLevel(logging.INFO)
33
 
@@ -144,7 +143,7 @@ def generate_text(prompt):
144
  logger.error(f"API call failed: {str(e)}")
145
  return '[{"Киселёв":"К сожалению, не удалось расслышать вопрос. Пожалуйста, попробуйте еще раз."}, {"Путин":"Мы работаем над улучшением системы. Спасибо за понимание."}]'
146
 
147
- def split_text(text, max_length=300):
148
  chunks = []
149
  while len(text) > max_length:
150
  split_at = text.rfind(' ', 0, max_length)
@@ -178,41 +177,113 @@ def generate_audio(text, speaker_name):
178
  sf.write(temp_filename, full_audio, sample_rate)
179
  return temp_filename
180
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
  def process_line(args):
182
  idx, speaker, text = args
183
  final_filename = f"t{idx+1}-{speaker}.wav"
184
  base_audio = None
185
- output_filename = None
186
-
187
  try:
188
  logger.info(f"Processing line {idx+1} for {speaker}")
189
  base_audio = generate_audio(text, speaker)
190
-
191
  if not os.path.exists(base_audio):
192
  return None
193
 
194
- output_filename = f"output_{uuid.uuid4().hex[:6]}.wav"
195
-
196
- # Extract source SE and convert
197
- source_se, _ = se_extractor.get_se(base_audio, tone_color_converter, vad=True)
198
- tone_color_converter.convert(
199
- audio_src_path=base_audio,
200
- src_se=source_se,
201
- tgt_se=ref_se[speaker],
202
- output_path=output_filename,
203
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
 
205
- if os.path.exists(output_filename):
206
- os.rename(output_filename, final_filename)
207
- return final_filename
208
-
209
  except Exception as e:
210
  logger.error(f"Error processing line {idx+1}: {str(e)}")
 
211
  finally:
212
- for f in [base_audio, output_filename]:
213
- if f and os.path.exists(f):
214
- os.remove(f)
215
- return None
216
 
217
  def create_video(audio_files):
218
  try:
 
17
  import threading
18
  from moviepy.editor import AudioFileClip, VideoFileClip, concatenate_videoclips
19
 
 
20
  # Streamlit UI
21
  st.set_page_config(
22
  page_title="Прямая линия с Путиным",
 
26
  )
27
 
28
  # Configure logging
29
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
30
  logger = logging.getLogger(__name__)
31
  logger.setLevel(logging.INFO)
32
 
 
143
  logger.error(f"API call failed: {str(e)}")
144
  return '[{"Киселёв":"К сожалению, не удалось расслышать вопрос. Пожалуйста, попробуйте еще раз."}, {"Путин":"Мы работаем над улучшением системы. Спасибо за понимание."}]'
145
 
146
+ def split_text(text, max_length=800):
147
  chunks = []
148
  while len(text) > max_length:
149
  split_at = text.rfind(' ', 0, max_length)
 
177
  sf.write(temp_filename, full_audio, sample_rate)
178
  return temp_filename
179
 
180
+ def process_single_chunk(chunk_file, speaker):
181
+ output_filename = f"temp_output_{uuid.uuid4().hex}.wav"
182
+ try:
183
+ source_se, _ = se_extractor.get_se(chunk_file, tone_color_converter, vad=True)
184
+ tone_color_converter.convert(
185
+ audio_src_path=chunk_file,
186
+ src_se=source_se,
187
+ tgt_se=ref_se[speaker],
188
+ output_path=output_filename,
189
+ )
190
+ return output_filename
191
+ except Exception as e:
192
+ logger.error(f"Error processing chunk: {str(e)}")
193
+ return None
194
+
195
+ def merge_audio_files(files, sample_rate):
196
+ merged = np.array([])
197
+ for f in files:
198
+ audio, _ = sf.read(f)
199
+ merged = np.concatenate([merged, audio])
200
+ return merged
201
+
202
  def process_line(args):
203
  idx, speaker, text = args
204
  final_filename = f"t{idx+1}-{speaker}.wav"
205
  base_audio = None
206
+
 
207
  try:
208
  logger.info(f"Processing line {idx+1} for {speaker}")
209
  base_audio = generate_audio(text, speaker)
210
+
211
  if not os.path.exists(base_audio):
212
  return None
213
 
214
+ audio_array, sr = sf.read(base_audio)
215
+ duration = len(audio_array) / sr
216
+
217
+ chunks = []
218
+ if duration > 15:
219
+ chunk_samples = 15 * sr
220
+ num_full_chunks = len(audio_array) // chunk_samples
221
+ remainder_samples = len(audio_array) % chunk_samples
222
+ remainder_duration = remainder_samples / sr
223
+
224
+ chunks = []
225
+ for i in range(num_full_chunks):
226
+ start = i * chunk_samples
227
+ end = start + chunk_samples
228
+ chunks.append(audio_array[start:end])
229
+
230
+ # Handle remainder
231
+ if remainder_samples > 0:
232
+ if remainder_duration < 10:
233
+ if chunks:
234
+ last_chunk = chunks.pop()
235
+ merged = np.concatenate([last_chunk, audio_array[num_full_chunks*chunk_samples:]])
236
+ chunks.append(merged)
237
+ else:
238
+ chunks.append(audio_array)
239
+ else:
240
+ chunks.append(audio_array[num_full_chunks*chunk_samples:])
241
+
242
+ # Validate chunks durations
243
+ valid_chunks = []
244
+ for chunk in chunks:
245
+ chunk_duration = len(chunk)/sr
246
+ if chunk_duration >= 10:
247
+ valid_chunks.append(chunk)
248
+ else:
249
+ if valid_chunks:
250
+ prev = valid_chunks.pop()
251
+ merged = np.concatenate([prev, chunk])
252
+ valid_chunks.append(merged)
253
+ else:
254
+ valid_chunks.append(chunk)
255
+ chunks = valid_chunks
256
+ else:
257
+ chunks = [audio_array]
258
+
259
+ # Process each chunk
260
+ converted_files = []
261
+ for i, chunk in enumerate(chunks):
262
+ chunk_file = f"temp_chunk_{uuid.uuid4().hex}.wav"
263
+ sf.write(chunk_file, chunk, sr)
264
+ chunk_output = process_single_chunk(chunk_file, speaker)
265
+ if chunk_output:
266
+ converted_files.append(chunk_output)
267
+ os.remove(chunk_file)
268
+
269
+ if not converted_files:
270
+ return None
271
+
272
+ merged_audio = merge_audio_files(converted_files, sr)
273
+ sf.write(final_filename, merged_audio, sr)
274
+
275
+ # Cleanup converted files
276
+ for f in converted_files:
277
+ os.remove(f)
278
+
279
+ return final_filename
280
 
 
 
 
 
281
  except Exception as e:
282
  logger.error(f"Error processing line {idx+1}: {str(e)}")
283
+ return None
284
  finally:
285
+ if base_audio and os.path.exists(base_audio):
286
+ os.remove(base_audio)
 
 
287
 
288
  def create_video(audio_files):
289
  try: