marquesafonso's picture
add height ratio for better caption mode. pydantic v2 field validation. add archiver to main.
d0c0836
raw
history blame
2.54 kB
from moviepy.editor import VideoFileClip, CompositeVideoClip, TextClip
import os
def parse_srt(srt_file):
"""Parse the SRT file and return a list of (start, end, text) for each subtitle."""
with open(srt_file, "r", encoding='utf-8') as file:
lines = file.readlines()
i = 0
subtitles = []
while i < len(lines):
if lines[i].strip().isdigit():
timing_str = lines[i+1].strip().split(" --> ")
start = timing_str[0]
end = timing_str[1]
text = lines[i+2].strip()
subtitles.append((start, end, text))
i += 4
else:
i += 1
return subtitles
def filter_caption_width(caption_mode:str):
if caption_mode == 'desktop':
caption_width_ratio = 0.5
caption_height_ratio = 0.8
elif caption_mode == 'mobile':
caption_width_ratio = 0.2
caption_height_ratio = 0.7
return caption_width_ratio, caption_height_ratio
def subtitler(video_file:str,
srt_path:str,
output_file:str,
fontsize:int,
font: str,
bg_color:str,
text_color:str,
caption_mode:str
):
"""Add subtitles from an SRT file to a video."""
video_file = os.path.abspath(video_file)
srt_path = os.path.abspath(srt_path)
output_file = os.path.abspath(output_file)
clip = VideoFileClip(filename=video_file, target_resolution=None)
subtitles = parse_srt(srt_path)
subtitle_clips = []
caption_width_ratio, caption_height_ratio = filter_caption_width(caption_mode)
for start, end, text in subtitles:
# Create TextClip with specified styling
# To get a list of possible color and font values run: print(TextClip.list("font"), '\n\n', TextClip.list("color"))
txt_clip = TextClip(text, fontsize=fontsize, color=text_color, font=font, method='caption',
bg_color=bg_color, align='center', size=(clip.w*caption_width_ratio, None))
txt_clip = txt_clip.set_position(('center', 'bottom')).set_duration(clip.duration).set_start(start).set_end(end)
subtitle_x_position = 'center'
subtitle_y_position = clip.h * caption_height_ratio
text_position = (subtitle_x_position, subtitle_y_position)
subtitle_clips.append(txt_clip.set_position(text_position))
video = CompositeVideoClip(size=None, clips=[clip] + subtitle_clips)
video.write_videofile(output_file, codec='libx264', audio_codec='aac')