# sub.py # Reads subtitle files and returns a new file with # corrected timestamps if any times overlap, # and corrected subtitle indeces. # # Current correction method is: # If A ends after B begins, then change A's ending to # just before B's beginning import os import sys import re def encodeTime(mil): mil = int(mil) hours = mil / (1000 * 60 * 60) mil = mil % (1000.0 * 60 * 60) minutes = mil / (1000 * 60) mil = mil % (1000.0 * 60) seconds = mil / (1000) mil = mil % (1000.0) return "%(h)02d:%(m)02d:%(s)02d,%(i)03d" % \ {"h" : hours, "m" : minutes, "s" : seconds, "i" : mil} def decodeTime(t): p = re.compile("(\d+):(\d+):(\d+),(\d+)") m = p.match(t) h = int(m.group(1)) mi = int(m.group(2)) s = int(m.group(3)) i = int(m.group(4)) return i + (1000 * s) + (1000 * 60 * mi) + (1000 * 60 * 60 * h) def fixToNew(oldName, newName): # Read old file and close it. oldFile = file(oldName) oldContent = oldFile.read() oldFile.close # Read subtitles into list "subs". subs = [] # This code iterates through matches, and stores the subtitle index # based on its position in the file, rather than the actual number # stored in the file. This fixes incorrect index numbers. p = re.compile("(?:\A|.*?\n)(\d+)\n(.*?) --> (.*?)\n(.*?)(?:\n[\d]+\n|\n\Z)", re.DOTALL) m = 0 i = 1 pos = 0 while m != None: m = p.match(oldContent, pos) if m != None: # print m.groups() subs.append((str(i), m.group(2), m.group(3), m.group(4))) pos = m.start(2) i = i + 1 #write subs to new file: #item: (index, timestart, timestop, text) # newFile = open(newName, 'w') for num, item in enumerate(subs): index = item[0] timestart = item[1] timestop = item[2] text = item[3] if num < len(subs) - 1: nextIndex = subs[num + 1][0] nextTimestart = subs[num + 1][1] nextTimestop = subs[num + 1][2] nextText = subs[num + 1][3] # Current correction method is: # If item ends after nextItem begins, then change item's ending to # just before nextItem's beginning (by 80 milliseconds). if num == len(subs) - 1: # This is the final subtitle. just write it. newFile.write(index + '\n' + \ timestart + " --> " + timestop + '\n' + \ text + '\n') elif decodeTime(timestop) > decodeTime(nextTimestart): # Overlap detected. Fix the value of timestop and write. newFile.write(index + '\n' + \ timestart + " --> " + \ encodeTime(decodeTime(nextTimestart)-80) + '\n' + \ text + '\n') else: # No overlap. Just write the subtitle. newFile.write(index + '\n' + \ timestart + " --> " + timestop + '\n' + \ text + '\n') newFile.close() return subs # ========== fromSub = "/home/brian/Desktop/yuki.sub" toSub = "/home/brian/Desktop/new.sub" fs = raw_input("Converting from " + fromSub + ".\nPlease press enter or " + \ "enter a new file location:\n") ts = raw_input("Writing to " + toSub + ".\nPlease press enter or " + \ "enter a new file location:\n") if fs != "": fromSub = fs if ts != "": toSub = ts fixToNew(fromSub,toSub) print "Successfully fixed" + "\n" + fromSub + "\nto\n" + toSub