File size: 3,458 Bytes
3b13b0e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
"""
合并视频和字幕文件
"""
import os
import pysrt
from moviepy import VideoFileClip, concatenate_videoclips


def get_video_duration(video_path):
    """获取视频时长(秒)"""
    video = VideoFileClip(video_path)
    duration = video.duration
    video.close()
    return duration


def adjust_subtitle_timing(subtitle_path, time_offset):
    """调整字幕时间戳"""
    subs = pysrt.open(subtitle_path)

    # 为每个字幕项添加时间偏移
    for sub in subs:
        sub.start.hours += int(time_offset / 3600)
        sub.start.minutes += int((time_offset % 3600) / 60)
        sub.start.seconds += int(time_offset % 60)
        sub.start.milliseconds += int((time_offset * 1000) % 1000)

        sub.end.hours += int(time_offset / 3600)
        sub.end.minutes += int((time_offset % 3600) / 60)
        sub.end.seconds += int(time_offset % 60)
        sub.end.milliseconds += int((time_offset * 1000) % 1000)

    return subs


def merge_videos_and_subtitles(video_paths, subtitle_paths, output_video_path, output_subtitle_path):
    """合并视频和字幕文件"""
    if len(video_paths) != len(subtitle_paths):
        raise ValueError("视频文件数量与字幕文件数量不匹配")

    # 1. 合并视频
    video_clips = []
    accumulated_duration = 0
    merged_subs = pysrt.SubRipFile()

    try:
        # 处理所有视频和字幕
        for i, (video_path, subtitle_path) in enumerate(zip(video_paths, subtitle_paths)):
            # 添加视频
            print(f"处理视频 {i + 1}/{len(video_paths)}: {video_path}")
            video_clip = VideoFileClip(video_path)
            video_clips.append(video_clip)

            # 处理字幕
            print(f"处理字幕 {i + 1}/{len(subtitle_paths)}: {subtitle_path}")
            if i == 0:
                # 第一个字幕文件直接读取
                current_subs = pysrt.open(subtitle_path)
            else:
                # 后续字幕文件需要调整时间戳
                current_subs = adjust_subtitle_timing(subtitle_path, accumulated_duration)

            # 合并字幕
            merged_subs.extend(current_subs)

            # 更新累计时长
            accumulated_duration += video_clip.duration

        # 判断视频是否存在,若已经存在不重复合并
        if not os.path.exists(output_video_path):
            print("合并视频中...")
            final_video = concatenate_videoclips(video_clips)

            # 保存合并后的视频
            print("保存合并后的视频...")
            final_video.write_videofile(output_video_path, audio_codec='aac')

        # 保存合并后的字幕
        print("保存合并后的字幕...")
        merged_subs.save(output_subtitle_path, encoding='utf-8')

        print("合并完成")

    finally:
        # 清理资源
        for clip in video_clips:
            clip.close()


def main():
    # 示例用法
    video_paths = [
        "temp/1.mp4",
        "temp/2.mp4",
        "temp/3.mp4",
        "temp/4.mp4",
        "temp/5.mp4",
    ]

    subtitle_paths = [
        "temp/1.srt",
        "temp/2.srt",
        "temp/3.srt",
        "temp/4.srt",
        "temp/5.srt",
    ]

    output_video_path = "temp/merged_video.mp4"
    output_subtitle_path = "temp/merged_subtitle.srt"

    merge_videos_and_subtitles(video_paths, subtitle_paths, output_video_path, output_subtitle_path)


if __name__ == "__main__":
    main()