Spaces:
Running
Running
Added Moviepy ImageMagic Path
Browse files- subtitles.py +70 -67
subtitles.py
CHANGED
@@ -1,67 +1,70 @@
|
|
1 |
-
from moviepy.editor import VideoFileClip, TextClip, CompositeVideoClip
|
2 |
-
import json
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
#
|
16 |
-
|
17 |
-
|
18 |
-
#
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
#
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
#
|
36 |
-
txt_clip = txt_clip.
|
37 |
-
|
38 |
-
#
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
#
|
47 |
-
final_clip
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
# #
|
56 |
-
# for
|
57 |
-
|
58 |
-
#
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
|
|
|
|
|
|
|
1 |
+
from moviepy.editor import VideoFileClip, TextClip, CompositeVideoClip
|
2 |
+
import json
|
3 |
+
|
4 |
+
from moviepy.config import change_settings
|
5 |
+
|
6 |
+
change_settings({"IMAGEMAGICK_BINARY": "/usr/bin/convert"}) # Adjust the path as necessary
|
7 |
+
|
8 |
+
class SubtitlesRenderer(object):
|
9 |
+
|
10 |
+
def add_subtitles(self,video_file, subtitle_file, output_file):
|
11 |
+
# Load subtitle data from JSON
|
12 |
+
with open(subtitle_file, 'r', encoding='utf-8') as f:
|
13 |
+
subtitles = json.load(f)
|
14 |
+
|
15 |
+
# Load the video
|
16 |
+
video = VideoFileClip(video_file)
|
17 |
+
|
18 |
+
# Initialize an array to store TextClips
|
19 |
+
text_clips_list = []
|
20 |
+
|
21 |
+
# Define the maximum width for the subtitles
|
22 |
+
max_width = video.size[0] - 40 # Adjust as needed, leaving some padding on the sides
|
23 |
+
|
24 |
+
|
25 |
+
# Create TextClips for each subtitle
|
26 |
+
for subtitle in subtitles:
|
27 |
+
text = subtitle['text']
|
28 |
+
start_time = subtitle['start']
|
29 |
+
end_time = subtitle['end']
|
30 |
+
|
31 |
+
# Create TextClip with subtitle text
|
32 |
+
txt_clip = TextClip(text, fontsize=28, color='white', font='Arial', method='caption',size=(max_width, None),stroke_color='black',
|
33 |
+
stroke_width= 0.5, bg_color='black',)
|
34 |
+
|
35 |
+
# Set the duration of the subtitle
|
36 |
+
txt_clip = txt_clip.set_duration(end_time - start_time)
|
37 |
+
|
38 |
+
# Position the subtitle at the bottom
|
39 |
+
txt_clip = txt_clip.set_position(('center', 'bottom'))
|
40 |
+
|
41 |
+
# Add TextClip to the array
|
42 |
+
text_clips_list.append(txt_clip.set_start(start_time))
|
43 |
+
|
44 |
+
# Composite all TextClips onto the video
|
45 |
+
#final_clip = video.fl(compose_text, text_clips_list)
|
46 |
+
# Composite all TextClips onto the video
|
47 |
+
final_clip = CompositeVideoClip([video] + text_clips_list)
|
48 |
+
|
49 |
+
# Write the result to a file
|
50 |
+
final_clip.write_videofile(output_file, codec='libx264', fps=video.fps, audio_codec='aac',
|
51 |
+
ffmpeg_params=["-vf", "format=yuv420p"]) # Add this for compatibility
|
52 |
+
|
53 |
+
return output_file
|
54 |
+
# def compose_text(self,frame, t, text_clips):
|
55 |
+
# # Select the appropriate TextClips for the current time t
|
56 |
+
# current_clips = [text_clip for text_clip in text_clips if text_clip.start < t < text_clip.end]
|
57 |
+
|
58 |
+
# # Composite the selected TextClips onto the frame
|
59 |
+
# for clip in current_clips:
|
60 |
+
# frame = frame.blit(clip.get_frame(t - clip.start), clip.pos)
|
61 |
+
# return frame
|
62 |
+
|
63 |
+
if __name__ == '__main__':
|
64 |
+
video_file = 'video.mp4'
|
65 |
+
subtitle_file = 'segments.json'
|
66 |
+
output_file = 'output_video_with_subtitles.mp4'
|
67 |
+
|
68 |
+
renderer = SubtitlesRenderer()
|
69 |
+
renderer.add_subtitles(video_file, subtitle_file, output_file)
|
70 |
+
|