如何合并两个 *.srt 文件

如何合并两个 *.srt 文件

请参见问题。

我刚刚合并了两个 avi 文件cd1.avicd1.avi使用movie.avi

avimerge -o movie.avi -i cd{1,2}.avi

问题是我必须字幕链接到第一个avi文件的文件:

cd1.srt
cd2.srt

起初我尝试简单地将文件连接在一起:

cat cd{1,2}.srt > movie.srt

但这对字幕造成了严重破坏......有什么建议吗?

答案1

这非常简单,因为.srt文件只是包含时间戳的文本文件 - 您需要做的就是cd1.avi将 的长度添加到cd2.srt.你可以找到cd1.avi的长度ffmpeg

ffmpeg -i cd1.avi  # Look for the Duration: line

然后将其添加到cd2.srtusingsrttool

srttool -d 12345 -i cd2.srt  # 12345 is the amount to add in seconds

或者:

srttool -a hh:mm:ss -i cd2.srt  # The first subtitle will now start at hh:mm:ss

然后您应该能够将文件连接在一起并重新编号:

srttool -r -i cd.srt

我选择它是srttool因为在 Arch 中它附带了transcode,您安装它是为了这个问题;还有很多其他工具.srt也可以移动和合并文件,并且至少有一个网站,淹没

答案2

我需要将第二个 SRT 文件中的 subs 附加到第一个 SRT 文件中最接近的现有计时,因此提出了下面的脚本。

例如,通过这种方式,您可以将不同语言的字幕合并到一个文件中。您可能还想修改脚本并使用不同的颜色附加其他文件中的内容。在 SRT 文件中执行此操作的唯一支持的语法是使用类似<font color="#00ffff">text here</font>.

该脚本需要最新的 python3 和srt可以安装的模块pip3 install srt

用法:

python3 merge_srt.py first.srt second.srt
#!/usr/bin/env python3

import argparse
import sys
from datetime import timedelta
from pathlib import Path

# pip3 install srt
import srt


def nearest(items, pivot):
    return min(items, key=lambda x: abs(x.start - pivot))


if __name__ == '__main__':

    parser = argparse.ArgumentParser(description='merge SRT subtitles',
                                     usage="""
    Merge SRT subtitles:                                     
    \t{0} first.srt second.srt -o merged.srt
 """.format(Path(sys.argv[0]).name))

    parser.add_argument('srt1',
                        metavar='srt1',
                        help='SRT-file-1')
    parser.add_argument('srt2',
                        metavar='srt2',
                        help='SRT-file-2')
    parser.add_argument('--output-file', '-o',
                        default=None,
                        help='Output filename')
    parser.add_argument('--encoding', '-e',
                        default=None,
                        help='Input file encoding')
    args = parser.parse_args(sys.argv[1:])

    srt1_path = Path(args.srt1)
    srt2_path = Path(args.srt2)

    with srt1_path.open(encoding=args.encoding or 'utf-8') as fi1:
        subs1 = {s.index: s for s in srt.parse(fi1)}

    with srt2_path.open(encoding=args.encoding or 'utf-8') as fi2:
        subs2 = {s.index: s for s in srt.parse(fi2)}

    # iterate all subs in srt2 and find the closest EXISTING slots in srt1
    for idx, sub in subs2.items():

        start: timedelta = sub.start
        sub_nearest_slot: srt.Subtitle = nearest(subs1.values(), start)
        sub_nearest_slot.content = f'{sub_nearest_slot.content}<br>{sub.content}'
        subs1[sub_nearest_slot.index] = sub_nearest_slot

    if not args.output_file:
        generated_srt = srt1_path.parent / (f'{srt1_path.stem}_MERGED_{srt1_path.suffix}')
    else:
        generated_srt = Path(args.output_file)

    with generated_srt.open(mode='w', encoding='utf-8') as fout:
        fout.write(srt.compose(list(subs1.values())))

答案3

我喜欢接受的答案。不幸的是,它依赖于(a)以非零退出代码退出的 ffmpeg 调用和(b)srttool,这在自制软件中显然不可用。

此外,我想要一些能够对多个文件执行更多自动化的东西(因为我使用的是 DJI 无人机,它每 4GB 分割一次文件)。

我最终写了srt-连接作为项目的一部分jaraco.media。它确实需要 Python 环境(以及所需的专业知识),但它很容易安装和运行。只需pip install jaraco.media进入您的 Python 环境,然后python -m jaraco.media.srt-concat ...按照该自述文件中的说明运行即可。它将尝试检测与每个匹配的 SRT 文件关联的媒体文件,计算这些文件的持续时间,并在连接 SRT 条目时添加聚合的持续时间。

答案4

接受的答案使用ffmpeg然后srttool。如果你已经ffmpeg安装了,你可以直接使用连接解复用器并且不需要其他任何东西:

$ cat mylist.txt
file '/path/to/file1.srt'
file '/path/to/file2.srt'
file '/path/to/file3.srt'
    
$ ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.srt

相关内容