Spaces:
Sleeping
Sleeping
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 |
+
|