#!/usr/bin/env python# subconvert -- Converts between MicroDVD (sub) and SubRip (srt)# subtitle formats# Copyright (C) 2006 Adrian C. <anrxc@hi.t-com.hr># 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 sysimport stringimport fileinputimport optparseVERSION = '0.1'# insert moreRATES = { 'PAL' : 25, 'NTSC' : 29.97, 'FILM' : 23.976 }def frame_to_time(frame, frate): def evalnum(num): if len(str(num)) == 1: return '0%d' % num else: return num 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 = evalnum(h) m = evalnum(m) s = evalnum(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]) else: main()