File size: 2,579 Bytes
fe21d8b
 
 
f5d12b4
 
fe21d8b
 
 
 
 
 
 
 
 
 
f5d12b4
fe21d8b
 
 
 
 
 
f5d12b4
fe21d8b
 
 
 
f5d12b4
fe21d8b
 
f5d12b4
 
fe21d8b
 
 
 
 
 
 
 
 
 
 
 
 
f5d12b4
fe21d8b
 
 
 
f5d12b4
fe21d8b
 
 
 
 
 
 
 
 
f5d12b4
fe21d8b
f5d12b4
fe21d8b
f5d12b4
fe21d8b
 
 
 
 
 
 
 
 
f5d12b4
fe21d8b
f5d12b4
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
72
73
74
75
76
77
78
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")