#!/usr/bin/env python # # HH:MM:SS.SSS - starts with 00:00:00.0000 import optparse import string import math def generateMkvXml(line, chapterNum): matroskaXml = "\t\t\n" matroskaXml += "\t\t\t" + line.rstrip('\n') + "\n" matroskaXml += "\t\t\t\n" matroskaXml += "\t\t\t\tChapter " + str(chapterNum) + "\n" matroskaXml += "\t\t\t\teng\n" matroskaXml += "\t\t\t\n" matroskaXml += "\t\t\n" return matroskaXml def returnTime( ptsMark, offset ): ptsFreq = 45000 ptsMark -= offset ptsTime = float(ptsMark) / float(ptsFreq) ptsHour = math.modf(ptsTime / 3600) ptsMinute = math.modf(float(ptsHour[0]) * 60) ptsSecond = ptsMinute[0] * 60 if ptsSecond >= 10: return '%(hour)02d:%(minute)02d:%(second)02.3F' % {'hour': ptsHour[1], 'minute': ptsMinute[1], 'second': ptsSecond} else: return '%(hour)02d:%(minute)02d:0%(second)02.3F' % {'hour': ptsHour[1], 'minute': ptsMinute[1], 'second': ptsSecond} def main(): p = optparse.OptionParser(description=' Deconstructs the MPLS file and converts the PTS information to create properly formatted XML chapter file for Matroska. This program needs the MPLS file from the BluRay disc associated with the M2TS file(s) that you are processing.', prog='bdchapters', version='BluRay Chapter Converter 0.3', usage='%prog -i [inputfile] -o [outputfile]') p.add_option('--input', '-i', action="store", help='the MPLS file from the BluRay disc', dest="inputfile") p.add_option('--output', '-o', action="store", help='the output XML file', dest="outputfile") (options, arguments) = p.parse_args() if options.inputfile == None: p.error("no inputfile specified.") elif options.outputfile == None: options.outputfile = options.inputfile + ".xml" print "\n" print 'Input file: %s' % options.inputfile print 'Output file: %s' % options.outputfile print "\n" matroskaXmlHeader = "\n\n\n\t\n" matroskaXmlFooter = "\t\n" input = open(options.inputfile, 'rb') output = open(options.outputfile, 'w') output.write(matroskaXmlHeader) count = 0 bytelist = [] ptsinfo = [] input.seek(-14, 2) for x in range(14): bytelist.append(input.read(1)) ptsinfo.append(ord(bytelist[4])*(256**3) + ord(bytelist[5])*(256**2) + ord(bytelist[6])*(256) + ord(bytelist[7])) while True: input.seek(-28, 1) bytelist = [] for x in range(14): bytelist.append(input.read(1)) if ord(bytelist[13]) != 0: break ptsinfo.append(ord(bytelist[4])*(256**3) + ord(bytelist[5])*(256**2) + ord(bytelist[6])*(256) + ord(bytelist[7])) if ptsinfo[-1] == ptsinfo[-2]: ptsinfo.pop([-1]) break ptsOffset = ptsinfo[-1] ptsinfo.sort() for x in ptsinfo: count += 1 timeStamp = returnTime( x, ptsOffset ) output.write(generateMkvXml(timeStamp, count)) output.write(matroskaXmlFooter) input.close() output.close() if __name__ == '__main__': main()