Monday, October 24, 2011

python: subtitle_delay_adjuster

Motivation: Couldn't find the perfect subtitles (.srt) file for a relatively-obscure movie? Are the subs in your .srt file off by a few seconds - just enough to irritate you, but not enough to ditch the awesome flick you're watching, AND are you feeling too lazy to tweak the subtitle offset in vlc manually?

This little proggie might just save the day  ^_^

#!/usr/bin/python2.7

import re
from datetime import datetime, timedelta
from functools import partial
import argparse



def replace_time(matchobj, time_diff):
    if matchobj.group(1) not in [None, '']:
       x = (datetime.strptime(matchobj.group(1), "%H:%M:%S") + time_diff).strftime("%H:%M:%S")
    

    if matchobj.group(3) not in [None, '']:
       y = (datetime.strptime(matchobj.group(3), "%H:%M:%S") + time_diff).strftime("%H:%M:%S")
    
    return x + matchobj.group(2) + y



def main():
    parser = argparse.ArgumentParser(
        description = 'subtitle_delay_adjuster: delay or advance all subtitles in an srt file by a given number of seconds',
        epilog = 'example: "%(prog)s -2 Thank.You.For.Smoking.2005.srt" would make all subs in the srt file appear 2 seconds earlier'
    )
    parser.add_argument('seconds', action='store', type=int, help='number of seconds by which to delay subtitles: use a negative number to advance subs instead of delaying them')
    parser.add_argument('srt_file', action='store', help='name of the srt_file to process')    
    args = parser.parse_args()

    time_diff = timedelta(seconds = args.seconds)


    infile = file(args.srt_file, 'r')
    outfile = file('out.srt', 'w')

    inlines = infile.readlines()

    for line in inlines:
        #print "line before sub: " + line
        newline = re.sub('(\d\d:\d\d:\d\d)(.*-->.*)(\d\d:\d\d:\d\d)', partial(replace_time, time_diff=time_diff), line)
        #print " line after sub: " + newline
        outfile.write(newline)

    infile.close()
    outfile.close()

    print "\n\n\nNew subs are ready! File: out.srt"




if __name__ == '__main__':
    main()

It certainly did save my day when I was trying to get the right subs for one of my favorite movies, "Thank You for Smoking" :-)