13

Please see this question.

I have just merged two avi files cd1.avi and cd1.avi into movie.avi using:

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

Problem is that I had to subtitle files linked to the first avi files:

cd1.srt
cd2.srt

At first I tried simply to concatenate the files together:

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

But that caused havoc with the subtitles... any suggestions?

3 Answers 3

20

This is pretty trivially done, since .srt files are just text files that contain time stamps -- all you need to do is add the length of cd1.avi to the times of all the subtitles in cd2.srt. You can find the length of cd1.avi with ffmpeg:

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

And then add that to cd2.srt using srttool

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

or:

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

Then you should just be able to concatenate the files together and renumber:

srttool -r -i cd.srt

I picked srttool because in Arch it comes with transcode, which you installed for this question; there are lots of other tools that can shift and merge .srt files too, and at least one website, submerge

3
  • +1 thanks micheal, really appreciate your efforts with my questions
    – Stefan
    Sep 20, 2010 at 22:15
  • 1
    Thanks! This worked great. Only problem I found is that srttool puts output to the command line. I actually doesn't modify the file you want. A little redirection (>) and WHAMMO, it works perfectly. This has been a huge help and thank you very much.
    – user11667
    Oct 19, 2011 at 4:38
  • 1
    How do you install srttool on MacOS? Jul 21, 2020 at 12:36
0

I needed the subs from the second SRT file to be appended to the nearest EXISTING timing in the first SRT file, so came up with the script below.

For example, in this way you can join subtitles in different languages into a single file. You might also want to modify the script and append content from the other file with a different color. The only supported syntax for doing this in a SRT file is using something like <font color="#00ffff">text here</font>.

The script requires a recent python3 and the srt module which can be installed with pip3 install srt.

Usage:

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())))
0

I liked the accepted answer. Unfortunately, it depended on (a) an invocation of ffmpeg that exited with a non-zero exit code and (b) on srttool, which is not obviously available in homebrew.

Additionally, I was wanting something that would perform a bit more automation over several files (since I'm using a DJI drone and it splits files every 4GB).

I ended up writing srt-concat as part of the jaraco.media project. It does require a Python environment (and the expertise that requires), but it's readily installable and runnable. Just pip install jaraco.media into your Python environment, then run python -m jaraco.media.srt-concat ... according to the directions in that readme. It will attempt to detect the media file associated with each matching SRT file, calculate the durations of those files, and add the aggregated duration as it concatenates the SRT entries.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.