from moviepy.editor import VideoFileClip, TextClip, CompositeVideoClip, AudioFileClip, concatenate_audioclips import os from typing import List, Tuple def export_srt(transcript: List[str], duration: float, output_path: str): """ Exports transcript as a .srt subtitle file assuming equal spacing. """ lines = [] segment_duration = duration / len(transcript) for idx, line in enumerate(transcript): start_time = segment_duration * idx end_time = segment_duration * (idx + 1) def format_time(t): h = int(t // 3600) m = int((t % 3600) // 60) s = int(t % 60) ms = int((t % 1) * 1000) return f"{h:02}:{m:02}:{s:02},{ms:03}" lines.append(f"{idx+1}") lines.append(f"{format_time(start_time)} --> {format_time(end_time)}") lines.append(line.strip()) lines.append("") # Empty line for spacing with open(output_path, "w", encoding="utf-8") as f: f.write("\n".join(lines)) def add_subtitles_and_bgm( video_path: str, transcript: List[str], output_path: str = "final_output.mp4", bgm_path: str = None, subtitle_font: str = "Arial", subtitle_size: int = 24, subtitle_color: str = "white", subtitle_position: Tuple[int, int] = ("center", "bottom") ): """ Adds subtitles and optional background music to a video. """ clip = VideoFileClip(video_path) duration = clip.duration segment_duration = duration / len(transcript) subtitle_clips = [] for i, line in enumerate(transcript): txt = TextClip( line, fontsize=subtitle_size, font=subtitle_font, color=subtitle_color, method='caption', size=(clip.w * 0.8, None) # 80% width ).set_position(subtitle_position).set_duration(segment_duration).set_start(i * segment_duration) subtitle_clips.append(txt) final_video = CompositeVideoClip([clip, *subtitle_clips]) if bgm_path and os.path.exists(bgm_path): bgm = AudioFileClip(bgm_path).volumex(0.2).set_duration(duration) original_audio = clip.audio if original_audio: mixed_audio = original_audio.volumex(1.0).audio_fadein(0.5).audio_fadeout(0.5) final_audio = CompositeVideoClip([mixed_audio.set_start(0), bgm.set_start(0)]).audio else: final_audio = bgm final_video = final_video.set_audio(final_audio) final_video.write_videofile(output_path, codec="libx264", audio_codec="aac")