qqwjq1981 commited on
Commit
99fac43
·
verified ·
1 Parent(s): 5e880b2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +25 -41
app.py CHANGED
@@ -232,9 +232,11 @@ def process_entry(entry, i, add_voiceover, target_language):
232
  font="./NotoSansSC-Regular.ttf",
233
  method='caption',
234
  color='yellow',
235
- font_size=int(video.h // 15),
 
 
236
  size=(int(video.w * 0.8), None)
237
- ).with_start(entry["start"]).with_duration(entry["end"] - entry["start"]).with_position(('bottom')).with_opacity(0.7)
238
 
239
  audio_segment = None
240
  if add_voiceover:
@@ -248,54 +250,36 @@ def add_transcript_voiceover(video_path, translated_json, output_path, add_voice
248
  """
249
  Add transcript and voiceover to a video, segment by segment.
250
  """
251
- # Load the video file
252
  video = VideoFileClip(video_path)
 
253
 
254
- # Create text clips based on timestamps
255
  text_clips = []
256
  audio_segments = []
257
 
258
- # Define relative font size based on video height (adjust this value as necessary)
259
- subtitle_font_size = int(video.h // 15) # Ensure it's an integer
260
- max_subtitle_width = int(video.w * 0.8) # 80% of video width
261
-
262
- font_path = "./NotoSansSC-Regular.ttf"
263
-
264
- for i, entry in enumerate(translated_json):
265
- logger.debug(f"Processing entry {i}: {entry}")
266
-
267
- # Ensure `entry` is a dictionary with keys "start", "end", and "translated"
268
- if isinstance(entry, dict) and "translated" in entry:
269
- # Create text clip for subtitles
270
- txt_clip = TextClip(
271
- text=entry["translated"],
272
- font=font_path,
273
- method='caption',
274
- color='yellow',
275
- font_size=subtitle_font_size,
276
- size=(max_subtitle_width, None)
277
- ).with_start(entry["start"]).with_duration(entry["end"] - entry["start"]).with_position(('bottom')).with_opacity(0.7)
278
- text_clips.append(txt_clip)
279
-
280
- # Generate voiceover for this segment, if needed
281
- if add_voiceover:
282
- segment_audio_path = f"segment_{i}_voiceover.wav"
283
- generate_voiceover([entry], target_language, segment_audio_path)
284
- audio_segment = AudioFileClip(segment_audio_path).set_duration(entry["end"] - entry["start"])
285
- audio_segments.append(audio_segment)
286
- else:
287
- raise ValueError(f"Invalid entry format: {entry}")
288
-
289
- # Combine the text clips
290
  final_video = CompositeVideoClip([video] + text_clips)
291
 
292
- # Concatenate all audio segments if voiceover was added
293
- if add_voiceover:
294
- final_audio = sum(audio_segments, AudioFileClip("silent_audio.wav")) # Mix all audio segments
295
- final_audio = final_audio.set_duration(video.duration) # Ensure the final audio matches the video duration
296
  final_video = final_video.set_audio(final_audio)
297
 
298
- # Write the result to a file
299
  logger.info(f"Saving the final video to: {output_path}")
300
  final_video.write_videofile(output_path, codec="libx264", audio_codec="aac")
301
 
 
232
  font="./NotoSansSC-Regular.ttf",
233
  method='caption',
234
  color='yellow',
235
+ stroke_color='black', # Border color
236
+ stroke_width=2, # Border thickness
237
+ font_size=int(video.h // 20),
238
  size=(int(video.w * 0.8), None)
239
+ ).with_start(entry["start"]).with_duration(entry["end"] - entry["start"]).with_position(('bottom')).with_opacity(0.8)
240
 
241
  audio_segment = None
242
  if add_voiceover:
 
250
  """
251
  Add transcript and voiceover to a video, segment by segment.
252
  """
 
253
  video = VideoFileClip(video_path)
254
+ font_path = "./NotoSansSC-Regular.ttf"
255
 
 
256
  text_clips = []
257
  audio_segments = []
258
 
259
+ with concurrent.futures.ThreadPoolExecutor() as executor:
260
+ futures = [executor.submit(process_entry, entry, i, video.w, video.h, font_path, add_voiceover, target_language)
261
+ for i, entry in enumerate(translated_json)]
262
+
263
+ for future in concurrent.futures.as_completed(futures):
264
+ try:
265
+ txt_clip, audio_segment = future.result()
266
+ text_clips.append(txt_clip)
267
+ if add_voiceover and audio_segment:
268
+ audio_segments.append(audio_segment)
269
+ except Exception as e:
270
+ logger.error(f"Error processing entry: {e}")
271
+
272
+ # Sort text clips and audio segments based on their start times
273
+ text_clips.sort(key=lambda clip: clip.start)
274
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
275
  final_video = CompositeVideoClip([video] + text_clips)
276
 
277
+ if add_voiceover and audio_segments:
278
+ audio_segments.sort(key=lambda segment: segment.start)
279
+ final_audio = concatenate_audioclips(audio_segments)
280
+ final_audio = final_audio.set_duration(video.duration)
281
  final_video = final_video.set_audio(final_audio)
282
 
 
283
  logger.info(f"Saving the final video to: {output_path}")
284
  final_video.write_videofile(output_path, codec="libx264", audio_codec="aac")
285