#!/usr/bin/env python # subconvert -- Converts between MicroDVD (sub) and SubRip (srt) # subtitle formats # Copyright (C) 2006 Adrian C. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; see the file COPYING. If not, write to # the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, # Boston, MA 02110-1301 USA. # Even though I have a large collection of movies and often I've to # fix subtitles or adjust timing, it was because of VDR that I wrote # this script. There is a fine plugin for VDR called "txtsubs" which # lets you insert subtitles in your recordings, unfortunately it only # recogniznes MicroDVD format. So, because of commercials and other # reasons, in my recordings there is always a second or two that has to # be adjusted in the subtitles. # I edit subtitles with application called Ksubtile which unfortunately # only recognizes SubRip format. So I needed something to quickly switch # between formats, and odd enough I wasn't able to find it on the net. # I did find "sub2srt", but since I lack any Perl skills I wasn't able # to modify the script to reverse the process. So I wrote my own. # # Script does check for some things, but mainly expects that you are using # it properly, try --help option for start. # Converted subtitles are printed to the terminal, you can redirect it # to a file using "> outfile" or "| tee outfile" or whatever... # # Guided by subtitle tutorial at: http://www.doom9.org/sub.htm # and a program written by Roland Obermayer: "sub2srt" import sys import string import fileinput import optparse VERSION = '0.1' # insert more RATES = { 'PAL' : 25, 'NTSC' : 29.97, 'FILM' : 23.976 } def frame_to_time(frame, frate): seconds = int(frame / float(frate)) ms = int((float(frame) / float(frate)) * 1000) ms = str(ms)[-3:] s = seconds % 60 mn = seconds // 60 m = mn % 60 h = mn // 60 h = '%02d' % h m = '%02d' % m s = '%02d' % s return '%s:%s:%s,%s' % (h, m, s, ms) def time_to_frame(time, frate): time = time.split(':') h = int(time[0]) * 3600 m = int(time[1]) * 60 s = float(time[2].replace(',','.')) ctime = float(h+m+s) * frate return int(ctime) class Converter: def __init__(self, frate): self.frate = frate def sub_to_srt(self, subfile): converted = 0 for line in fileinput.input(subfile): try: sframe = line.split('}{')[0].split('{')[1] eframe = line.split('}{')[1].split('}')[0] text = line.split('}{')[1].split('}')[1] stime = frame_to_time(int(sframe), self.frate) etime = frame_to_time(int(eframe), self.frate) if '|' in text: text = text.split('|')[0]+'\n'+text.split('|')[1].strip() else: text = text.strip() converted += 1 print '%d\n%s --> %s\n%s\n' % (converted, stime, etime, text) except IndexError: pass def srt_to_sub(self, subfile): srtfile = open(subfile).read().replace('\r','') clean = string.split(srtfile, '\n\n') clean = filter(None, map(string.strip, clean)) for sub in clean: sub = sub.split('\n') stime = sub[1].split(' --> ')[0] etime = sub[1].split(' --> ')[1] try: text = sub[2]+'|'+sub[3] except IndexError: text = sub[2] sframe = time_to_frame(stime, self.frate) eframe = time_to_frame(etime, self.frate) print '{%s}{%s}%s' % (sframe, eframe, text) def main(): usage = "%prog [-b | -t FILE] [--fps=FRATE] > OUTFILE" parser = optparse.OptionParser(usage=usage) parser.add_option('-t', '--sub2srt', dest='subfile', help='convert sub to srt') parser.add_option('-b', '--srt2sub', dest='srtfile', help='convert srt to sub') parser.add_option('--fps', dest='frate', help='frame rate, one of: NTSC, FILM, or \ the program defaults to PAL (25fps)') (option, args) = parser.parse_args() if option.frate: if RATES.has_key(option.frate): frate = RATES[option.frate] else: raise SystemExit("%s: Unknown frame rate, why don\'t you try --help" % parser.get_prog_name()) try: c = Converter(frate) except: c = Converter(RATES['PAL']) try: if option.subfile: c.sub_to_srt(option.subfile) elif option.srtfile: c.srt_to_sub(option.srtfile) except IOError: raise SystemExit("%s: Unable to read subtitle file, why don\'t you try --help" % parser.get_prog_name()) if __name__ == '__main__': if len(sys.argv) == 1: raise SystemExit("%s: Why don\'t you try --help" % sys.argv[0]) main()