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