SPACERUNNER99 commited on
Commit
230dec4
·
verified ·
1 Parent(s): 5c9f156

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +140 -50
app.py CHANGED
@@ -1,65 +1,155 @@
1
- from moviepy import *
2
  import pysrt
3
  import gradio as gr
4
-
5
-
 
6
 
7
  def time_to_seconds(time_obj):
8
- return time_obj.hours * 3600 + time_obj.minutes * 60 + time_obj.seconds + time_obj.milliseconds / 1000
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
  def create_subtitle_clips(subtitles, videosize, fontsize, font, color, debug):
11
  subtitle_clips = []
12
- color_clips=[]
13
- for subtitle in subtitles:
14
- start_time = time_to_seconds(subtitle.start) # Add 2 seconds offset
15
- end_time = time_to_seconds(subtitle.end)
16
- duration = end_time - start_time
17
- video_width, video_height = videosize
18
- max_width = video_width * 0.8
19
- max_height = video_height * 0.2
20
- #reshaped_text = arabic_reshaper.reshape(subtitle.text)
21
- #bidi_text = get_display(reshaped_text)
22
- text_clip = TextClip(font, subtitle.text, font_size=fontsize, size=(int(video_width * 0.8), int(video_height * 0.2)) ,text_align="center" ,color=color, method='caption').with_start(start_time).with_duration(duration)
23
- #myclip = ColorClip(size=(int(video_width * 0.8), int(video_height * 0.2)) , color=(225, 0, 0)).with_opacity(0.2).with_start(start_time).with_duration(duration)
24
- subtitle_x_position = 'center'
25
- subtitle_y_position = video_height * 0.68
26
- text_position = (subtitle_x_position, subtitle_y_position)
27
- subtitle_clips.append(text_clip.with_position(text_position))
28
- #color_clips.append(myclip.with_position(text_position))
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  return subtitle_clips
30
 
31
  def video_edit(srt, input_video, color, font, font_size, input_audio):
32
- print(input_video)
33
- input_video_name = input_video.split(".mp4")[0]
34
- video = VideoFileClip(input_video)
35
- audio = AudioFileClip(input_audio)
36
- video = video.with_audio(audio)
37
- print(video)
38
- output_video_file = input_video_name + '_subtitled' + ".mp4"
39
- subtitles = pysrt.open(srt, encoding="utf-8")
40
- subtitle_clips = create_subtitle_clips(subtitles, video.size, int(font_size), f'{font}.ttf', color, False)
41
- final_video = CompositeVideoClip([video]+ subtitle_clips)
42
- final_video.write_videofile(output_video_file, codec="libx264", audio_codec="aac", logger=None, preset = "faster", fps=24)
43
- print('final')
44
- video.close()
45
- audio.close()
46
- return output_video_file
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
 
48
  with gr.Blocks() as demo:
49
- gr.Markdown("Start typing below and then click **Run** to see the progress and final output.")
50
  with gr.Column():
51
- srt_file = gr.File()
52
- video_in = gr.Video()
53
- color = gr.Text()
54
- font = gr.Text()
55
- font_size = gr.Number()
56
- audio_in = gr.Audio(type = "filepath")
57
- btn = gr.Button("Create")
58
- output_video = gr.Video()
59
- btn.click(
60
- fn=video_edit,
61
- inputs=[srt_file, video_in, color, font, font_size, audio_in],
62
- outputs=output_video
63
- )
 
 
 
 
 
 
 
64
 
65
  demo.launch(debug=True)
 
1
+ from moviepy.editor import *
2
  import pysrt
3
  import gradio as gr
4
+ import traceback
5
+ import os
6
+ from pathlib import Path
7
 
8
  def time_to_seconds(time_obj):
9
+ try:
10
+ return time_obj.hours * 3600 + time_obj.minutes * 60 + time_obj.seconds + time_obj.milliseconds / 1000
11
+ except Exception as e:
12
+ raise ValueError(f"Invalid time format: {e}")
13
+
14
+ def validate_subtitle_time(subtitles, video_duration):
15
+ for i, subtitle in enumerate(subtitles):
16
+ start = time_to_seconds(subtitle.start)
17
+ end = time_to_seconds(subtitle.end)
18
+ if start > end:
19
+ raise ValueError(f"Subtitle {i+1}: Start time ({start}s) exceeds end time ({end}s)")
20
+ if end > video_duration + 2:
21
+ raise ValueError(f"Subtitle {i+1}: End time ({end}s) exceeds video duration ({video_duration}s)")
22
 
23
  def create_subtitle_clips(subtitles, videosize, fontsize, font, color, debug):
24
  subtitle_clips = []
25
+ try:
26
+ font_path = f"{font}.ttf"
27
+ if not Path(font_path).is_file():
28
+ raise FileNotFoundError(f"Font file '{font_path}' not found")
29
+
30
+ for subtitle in subtitles:
31
+ start_time = time_to_seconds(subtitle.start)
32
+ end_time = time_to_seconds(subtitle.end)
33
+ duration = end_time - start_time
34
+
35
+ if duration <= 0:
36
+ raise ValueError(f"Invalid subtitle duration at position {subtitle.position}")
37
+
38
+ video_width, video_height = videosize
39
+ text_clip = TextClip(
40
+ subtitle.text,
41
+ fontsize=fontsize,
42
+ font=font,
43
+ color=color,
44
+ size=(int(video_width * 0.8), int(video_height * 0.2)),
45
+ method='caption',
46
+ print_cmd=debug
47
+ ).set_start(start_time).set_duration(duration)
48
+
49
+ subtitle_y_position = video_height * 0.68
50
+ subtitle_clips.append(text_clip.set_position(('center', subtitle_y_position)))
51
+
52
+ except Exception as e:
53
+ raise RuntimeError(f"Error creating subtitle clips: {str(e)}") from e
54
+
55
  return subtitle_clips
56
 
57
  def video_edit(srt, input_video, color, font, font_size, input_audio):
58
+ try:
59
+ # Input validation
60
+ if not all([srt, input_video, input_audio]):
61
+ raise ValueError("All input files are required")
62
+
63
+ if not os.path.exists(input_video):
64
+ raise FileNotFoundError(f"Video file {input_video} not found")
65
+
66
+ if not os.path.exists(input_audio):
67
+ raise FileNotFoundError(f"Audio file {input_audio} not found")
68
+
69
+ # Process files
70
+ input_video_name = os.path.splitext(input_video)[0]
71
+ output_video_file = f"{input_video_name}_subtitled.mp4"
72
+
73
+ with VideoFileClip(input_video) as video:
74
+ video_duration = video.duration
75
+
76
+ # Load subtitles
77
+ try:
78
+ subtitles = pysrt.open(srt.name, encoding='utf-8')
79
+ except Exception as e:
80
+ raise ValueError(f"Error loading SRT file: {str(e)}")
81
+
82
+ validate_subtitle_time(subtitles, video_duration)
83
+
84
+ # Process audio
85
+ with AudioFileClip(input_audio) as audio:
86
+ if audio.duration < video_duration:
87
+ raise ValueError("Audio duration is shorter than video duration")
88
+
89
+ video = video.set_audio(audio)
90
+
91
+ # Create subtitles
92
+ subtitle_clips = create_subtitle_clips(
93
+ subtitles,
94
+ video.size,
95
+ int(font_size),
96
+ font,
97
+ color,
98
+ debug=False
99
+ )
100
+
101
+ # Compose final video
102
+ final_video = CompositeVideoClip([video] + subtitle_clips)
103
+
104
+ # Write output
105
+ try:
106
+ final_video.write_videofile(
107
+ output_video_file,
108
+ codec="libx264",
109
+ audio_codec="aac",
110
+ preset="fast",
111
+ threads=4,
112
+ logger=None
113
+ )
114
+ except Exception as e:
115
+ raise RuntimeError(f"Error writing video file: {str(e)}")
116
+
117
+ return output_video_file
118
+
119
+ except Exception as e:
120
+ error_trace = traceback.format_exc()
121
+ raise gr.Error(f"Processing failed: {str(e)}\n\nDebug Info:\n{error_trace}")
122
+
123
+ finally:
124
+ # Cleanup resources
125
+ if 'final_video' in locals():
126
+ final_video.close()
127
+ if 'subtitle_clips' in locals():
128
+ for clip in subtitle_clips:
129
+ clip.close()
130
 
131
  with gr.Blocks() as demo:
132
+ gr.Markdown("## Video Subtitle Generator")
133
  with gr.Column():
134
+ with gr.Row():
135
+ srt_file = gr.File(label="SRT Subtitle File", type="file")
136
+ video_in = gr.Video(label="Input Video", format="mp4")
137
+ audio_in = gr.Audio(label="Input Audio", type="filepath")
138
+ with gr.Row():
139
+ color = gr.ColorPicker(label="Text Color", value="#ffffff")
140
+ font = gr.Dropdown(
141
+ label="Font",
142
+ choices=["Arial", "Helvetica", "Times-New-Roman", "Courier-New"],
143
+ value="Arial"
144
+ )
145
+ font_size = gr.Slider(12, 72, value=32, label="Font Size")
146
+ btn = gr.Button("Generate Subtitled Video", variant="primary")
147
+ output_video = gr.Video(label="Output Video")
148
+
149
+ btn.click(
150
+ fn=video_edit,
151
+ inputs=[srt_file, video_in, color, font, font_size, audio_in],
152
+ outputs=output_video
153
+ )
154
 
155
  demo.launch(debug=True)