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)