def main(args): from optparse import OptionParser p = OptionParser(description='Grabs avisynth trims and outputs chapter ' 'file, qpfile and/or cuts audio (works with cfr and ' 'vfr input)', version='VFR Chapter Creator 0.10.0', usage='%prog [options] infile.avs [outfile.avs]') p.add_option('--label', '-l', action="store", dest="label", help="Look for a trim() statement or succeeding comment only " "on lines matching LABEL. Default: case insensitive trim") p.add_option('--clip', action="store", dest="clip", help="Look for trims() using specific clip, like" "Trim(ClipX,0,100). Default: any trim") p.add_option('--line', '-g', action="store", type="int", dest="line", help="Specify directly the line used") p.add_option('--input', '-i', action="store", help='Audio file to be cut', dest="input") p.add_option('--output', '-o', action="store", help='Cut audio from MKVMerge', dest="output") p.add_option('--fps', '-f', action="store", help='Frames per second or Timecodes file', dest="fps") p.add_option('--ofps', action="store", help='Output frames per second', dest="ofps") p.add_option('--timecodes', action="store", help='Output v2 timecodes', dest="otc") p.add_option('--chapters', '-c', action="store", help='Chapters file [.{0}/.txt]'.format("/.".join( exts.keys())), dest="chapters") p.add_option('--chnames', '-n', action="store", help='Path to template file for chapter names (utf8 w/o bom)', dest="chnames") p.add_option('--template', '-t', action="store", help="Template file for chapters", dest="template") p.add_option('--uid', action="store", help="Base UID for --template or --chnames", dest="uid") p.add_option('--qpfile', '-q', action="store", help='QPFile for x264', dest="qpfile") p.add_option('--verbose', '-v', action="store_true", help='Verbose', dest="verbose") p.add_option('--merge', '-m', action="store_true", help='Merge cut files', dest="merge") p.add_option('--remove', '-r', action="store_true", help='Remove cut files', dest="remove") p.add_option('--delay', '-d', action="store", help="Set delay of audio (can be negative)", dest="delay") p.add_option('--reverse', '-b', action="store_true", help="Reverse parsing of .avs", dest="reverse") p.add_option('--test', action="store_true", help="Test mode (do not create new files)", dest="test") p.add_option('--IDR', '--idr', action="store_true", help="Set this to make qpfile with IDR frames instead of K frames", dest="IDR") p.add_option('--sbr', action="store_true", help="Set this if inputting an .aac and it's SBR/HE-AAC", dest="sbr") (o, a) = p.parse_args(args) if len(a) < 1: p.error("No avisynth script specified.") if not o.fps: o.fps = default_fps ifps = False else: ifps = True #Determine chapter type if o.chapters: chre = compile("\.({0})$(?i)".format("|".join(exts.keys()))) ret = chre.search(o.chapters) chapter_type = exts[ret.group(1).lower()] if ret else "OGM" else: chapter_type = '' if o.template and o.chnames: p.error("Choose either --chnames or --template, not both.") elif o.template and chapter_type != 'MKV': p.error("--template needs to output to .xml.") if not o.output and o.input: ret = splitext(o.input) o.output = '{0}.cut.mka'.format(ret[0]) if o.verbose: status = "Avisynth file: \t{0}\n".format(a[0]) status += "Label: \t\t{0}\n".format(o.label) if o.label else "" status += "Clip name: \t{0}\n".format(o.clip) if o.clip else "" status += ("Parsing order: \t{0}\n".format("Bottom to top" if o.reverse else "Top to bottom")) status += "Line: \t\t{0}\n".format(o.line) if o.line else "" status += ("Audio file: \t{0}{1}\n".format(o.input, "(SBR)" if o.sbr else "") if o.input else "") status += "Cut Audio file: {0}\n".format(o.output) if o.output else "" status += "Timecodes/FPS: \t{0}{1}\n".format(o.fps, " to " + o.ofps if o.ofps else "") if o.ofps != o.fps else "" status += "Output v2 Tc: \t{0}\n".format(o.otc) if o.otc else "" status += ("Chapters file: \t{0}{1}\n".format(o.chapters, " ({0})".format(chapter_type) if chapter_type else "") if o.chapters else "") status += ("Chapter Names: \t{0}\n".format(o.chnames) if o.chnames else "") status += ("Template file: \t{0}\n".format(o.template) if o.template else "") status += "QP file: \t{0} ({1} frames)\n".format(o.qpfile, 'I' if o.IDR else 'K') if o.qpfile else "" status += "\n" status += ("Merge/Rem files:{0}/{1}\n".format(o.merge, o.remove) if o.merge or o.remove else "") status += ("Verbose: \t{0}\n".format(o.verbose) if o.verbose else "") status += "Test Mode: \t{0}\n".format(o.test) if o.test else "" print(status) # Get frame numbers and corresponding timecodes from avs Trims, Trimsts, Trims2, Trims2ts, audio = parse_trims(a[0], o.fps, o.ofps, o.otc if not o.test else '', o.input, o.label, o.reverse, o.line, o.clip, o.merge) nt2 = len(Trims2ts) if o.verbose: print('In trims: {0}\n'.format(', '.join(['({0},{1})'.format(i[0], i[1]) for i in Trims]))) print('In timecodes: {0}\n'.format(', '.join(['({0},{1})'.format(i[0], i[1]) for i in Trimsts]))) print('Out trims: {0}\n'.format(', '.join(['({0},{1})'.format(i[0], i[1]) for i in Trims2]))) print('Out timecodes: {0}\n'.format(', '.join(['({0},{1})'.format( fmt_time(i[0]), fmt_time(i[1])) for i in Trims2ts]))) # make qpfile if o.qpfile and not o.template: if not o.test: write_qpfile(o.qpfile, Trims2, o.IDR) if o.verbose: print('Writing keyframes to {0}\n'.format(o.qpfile)) # make audio cuts if o.input: split_audio(audio, o.input, o.output, o.delay, o.sbr, o.merge, o.remove, o.verbose, o.test) # make offseted avs if len(a) > 1: try: from chapparse import writeAvisynth fNum = [i[0] for i in Trims2] set = {'avs': '"' + a[1] + '"', 'input': '', 'resize': ''} writeAvisynth(set, fNum) except ImportError: print('Script chapparse.py needed for avisynth output to work.') # write chapters if chapter_type: if chapter_type == 'MKV': Trims2ts = [(fmt_time(i[0]), fmt_time(i[1]) if i[1] != 0 else None) for i in Trims2ts] if o.template: from templates import AutoMKVChapters as amkvc output = o.chapters[:-4] if not o.test else None chaps = amkvc(o.template, output=output, avs=a[0], trims=Trims2ts, kframes=Trims2, uid=o.uid, label=o.label, ifps=ifps, clip=o.clip, idr=o.IDR) else: # Assign names to each chapter if --chnames chapter_names = [] if o.chnames: with open(o.chnames, encoding='utf-8') as f: [chapter_names.append(line.strip()) for line in f.readlines()] if not o.chnames or len(chapter_names) < len(Trims2ts): # The if statement is for clarity; it doesn't actually do # anything useful for i in range(len(chapter_names), len(Trims2ts)): chapter_names.append("Chapter {:02d}".format(i + 1)) if chapter_type == 'MKV': from templates import AutoMKVChapters as amkvc tmp = amkvc.Template() tmp.trims = Trims2ts tmp.kframes = Trims2 if o.qpfile: tmp.qpf = o.qpfile tmp.idr = o.IDR ed = tmp.Edition() ed.default = 1 ed.num_chapters = len(chapter_names) ed.uid = int(o.uid) * 100 if o.uid else tmp.uid * 100 cuid = ed.uid ed.chapters = [] for i in range(len(chapter_names)): ch = tmp.Chapter() cuid += 1 ch.uid = cuid ch.name = [chapter_names[i]] ch.start, ch.end = (Trims2ts[i][0], Trims2ts[i][1]) ed.chapters.append(ch) tmp.editions = [ed] chaps = tmp if not o.test: if chapter_type == 'MKV': chaps.toxml(o.chapters[:-4]) else: with open(o.chapters, "w", encoding='utf-8') as output: if chapter_type == 'OGM': chap = ('CHAPTER{1:02d}={0}\nCHAPTER{1:02d}' 'NAME={2}\n') elif chapter_type == 'X264': chap = '{0} {2}\n' Trims2ts = [fmt_time(i[0], 1) for i in Trims2ts] [output.write(chap.format(Trims2ts[i], i + 1, chapter_names[i])) for i in range(len(Trims2ts))] if o.verbose: print("Writing {} Chapters to {}". format(chapter_type, o.chapters))
def main(args): from optparse import OptionParser p = OptionParser(description='Grabs avisynth trims and outputs chapter ' 'file, qpfile and/or cuts audio (works with cfr and ' 'vfr input)', version='VFR Chapter Creator 0.10.0', usage='%prog [options] infile.avs [outfile.avs]') p.add_option('--label', '-l', action="store", dest="label", help="Look for a trim() statement or succeeding comment only " "on lines matching LABEL. Default: case insensitive trim") p.add_option('--clip', action="store", dest="clip", help="Look for trims() using specific clip, like" "Trim(ClipX,0,100). Default: any trim") p.add_option('--line', '-g', action="store", type="int", dest="line", help="Specify directly the line used") p.add_option('--input', '-i', action="store", help='Audio file to be cut', dest="input") p.add_option('--output', '-o', action="store", help='Cut audio from MKVMerge', dest="output") p.add_option('--fps', '-f', action="store", help='Frames per second or Timecodes file', dest="fps") p.add_option('--ofps', action="store", help='Output frames per second', dest="ofps") p.add_option('--timecodes', action="store", help='Output v2 timecodes', dest="otc") p.add_option('--chapters', '-c', action="store", help='Chapters file [.{0}/.txt]'.format("/.".join( exts.keys())), dest="chapters") p.add_option('--chnames', '-n', action="store", help='Path to template file for chapter names (utf8 w/o bom)', dest="chnames") p.add_option('--template', '-t', action="store", help="Template file for chapters", dest="template") p.add_option('--uid', action="store", help="Base UID for --template or --chnames", dest="uid") p.add_option('--qpfile', '-q', action="store", help='QPFile for x264', dest="qpfile") p.add_option('--verbose', '-v', action="store_true", help='Verbose', dest="verbose") p.add_option('--merge', '-m', action="store_true", help='Merge cut files', dest="merge") p.add_option('--remove', '-r', action="store_true", help='Remove cut files', dest="remove") p.add_option('--delay', '-d', action="store", help="Set delay of audio (can be negative)", dest="delay") p.add_option('--reverse', '-b', action="store_true", help="Reverse parsing of .avs", dest="reverse") p.add_option('--test', action="store_true", help="Test mode (do not create new files)", dest="test") p.add_option('--IDR', '--idr', action="store_true", help="Set this to make qpfile with IDR frames instead of K frames", dest="IDR") p.add_option('--sbr', action="store_true", help="Set this if inputting an .aac and it's SBR/HE-AAC", dest="sbr") (o, a) = p.parse_args(args) if len(a) < 1: p.error("No avisynth script specified.") if not o.fps: o.fps = default_fps ifps = False else: ifps = True #Determine chapter type if o.chapters: chre = compile("\.({0})$(?i)".format("|".join(exts.keys()))) ret = chre.search(o.chapters) chapter_type = exts[ret.group(1).lower()] if ret else "OGM" else: chapter_type = '' if o.template and o.chnames: p.error("Choose either --chnames or --template, not both.") elif o.template and chapter_type != 'MKV': p.error("--template needs to output to .xml.") if not o.output and o.input: ret = splitext(o.input) o.output = '{0}.cut.mka'.format(ret[0]) if o.verbose: status = "Avisynth file: \t{0}\n".format(a[0]) status += "Label: \t\t{0}\n".format(o.label) if o.label else "" status += "Clip name: \t{0}\n".format(o.clip) if o.clip else "" status += ("Parsing order: \t{0}\n".format("Bottom to top" if o.reverse else "Top to bottom")) status += "Line: \t\t{0}\n".format(o.line) if o.line else "" status += ("Audio file: \t{0}{1}\n".format(o.input, "(SBR)" if o.sbr else "") if o.input else "") status += "Cut Audio file: {0}\n".format(o.output) if o.output else "" status += "Timecodes/FPS: \t{0}{1}\n".format(o.fps, " to " + o.ofps if o.ofps else "") if o.ofps != o.fps else "" status += "Output v2 Tc: \t{0}\n".format(o.otc) if o.otc else "" status += ("Chapters file: \t{0}{1}\n".format(o.chapters, " ({0})".format(chapter_type) if chapter_type else "") if o.chapters else "") status += ("Chapter Names: \t{0}\n".format(o.chnames) if o.chnames else "") status += ("Template file: \t{0}\n".format(o.template) if o.template else "") status += "QP file: \t{0} ({1} frames)\n".format(o.qpfile, 'I' if o.IDR else 'K') if o.qpfile else "" status += "\n" status += ("Merge/Rem files:{0}/{1}\n".format(o.merge, o.remove) if o.merge or o.remove else "") status += ("Verbose: \t{0}\n".format(o.verbose) if o.verbose else "") status += "Test Mode: \t{0}\n".format(o.test) if o.test else "" print(status) # Get frame numbers and corresponding timecodes from avs Trims, Trimsts, Trims2, Trims2ts, audio = parse_trims(a[0], o.fps, o.ofps, o.otc if not o.test else '', o.input, o.label, o.reverse, o.line, o.clip) nt2 = len(Trims2ts) if o.verbose: print('In trims: {0}\n'.format(', '.join(['({0},{1})'.format(i[0], i[1]) for i in Trims]))) print('In timecodes: {0}\n'.format(', '.join(['({0},{1})'.format(i[0], i[1]) for i in Trimsts]))) print('Out trims: {0}\n'.format(', '.join(['({0},{1})'.format(i[0], i[1]) for i in Trims2]))) print('Out timecodes: {0}\n'.format(', '.join(['({0},{1})'.format( fmt_time(i[0]), fmt_time(i[1])) for i in Trims2ts]))) # make qpfile if o.qpfile and not o.template: if not o.test: write_qpfile(o.qpfile, Trims2, o.IDR) if o.verbose: print('Writing keyframes to {0}\n'.format(o.qpfile)) # make audio cuts if o.input: from subprocess import call, check_output from sys import getfilesystemencoding if Trims[0][0] == '0': includefirst = True audio = audio[1:] else: includefirst = False cuttimes = [] # get mkvmerge version get_mkvmerge_version = check_output([mkvmerge, "--version"]).decode() ver = [int(n) for n in get_mkvmerge_version.split()[1][1:].split('.')] parts_able = ver >= [5,6,0] # first version with --split parts if parts_able: if includefirst: cuttimes = ['-{}'.format(audio.pop(0))] if not includefirst and len(audio) == 1: cuttimes = '{}-'.format(audio[0]) else: cuttimes = ',+'.join(cuttimes + ['{}-{}'.format(audio[i], audio[i + 1]) for i in range(0,len(audio),2)]) else: cuttimes = ','.join(audio) max_audio = len(audio) + 2 # get info from mkvmerge ident = check_output([mkvmerge, "--identify-for-mmg", o.input]) identre = compile("Track ID (\d+): audio( \(AAC\) " "\[aac_is_sbr:true\])?") ret = (identre.search(ident.decode(getfilesystemencoding())) if ident else None) tid = ret.group(1) if ret else '0' sbr = ("0:1" if o.sbr or ret.group(2) else "0:0" if o.input.endswith("aac") else "") # determine delay delre = compile('DELAY ([-]?\d+)') ret = delre.search(o.input) delay = ('{0}:{1}'.format(tid, o.delay if o.delay else ret.group(1)) if o.delay or ret else None) cutCmd = [mkvmerge, '-o', o.output] if not parts_able: cutCmd[-1] += '.split.mka' if delay: cutCmd.extend(['--sync', delay]) if sbr: cutCmd.extend(['--aac-is-sbr', sbr]) cutCmd.extend([o.input, '--split']) if parts_able: cutCmd.extend(['parts:' + cuttimes]) else: cutCmd.extend(['timecodes:' + cuttimes]) if o.verbose: print('Cutting: {0}\n'.format( ' '.join(['"{0}"'.format(i) for i in cutCmd]))) else: cutCmd.append('-q') if not o.test: cutExec = call(cutCmd) if cutExec == 1: print("Mkvmerge exited with warnings: {0:d}".format(cutExec)) elif cutExec == 2: exit("Failed to execute mkvmerge: {0:d}".format(cutExec)) if o.merge and not parts_able: merge = [] for i in range(1, max_audio): if ((includefirst == True and i % 2 != 0) or (includefirst == False and i % 2 == 0)): merge.append('{0}{1}.split-{2:03d}.mka'.format('+' if len(merge) > 0 else '', o.output, i)) mergeCmd = [mkvmerge, '-o', o.output] mergeCmd.extend(merge) if o.verbose: print('\nMerging: {0}\n'.format(' '.join(['"{0}"'.format(i) for i in mergeCmd]))) else: mergeCmd.append('-q') if not o.test: mergeExec = call(mergeCmd) if mergeExec == 1: print("Mkvmerge exited with warnings: {0:d}".format( mergeExec)) elif mergeExec == 2: exit("Failed to execute mkvmerge: {0:d}".format(mergeExec)) if o.remove and not parts_able: remove = ['{0}.split-{1:03d}.mka'.format(o.output, i) for i in range(1, max_audio)] if o.verbose: print('\nDeleting: {0}\n'.format(', '.join(remove))) if not o.test: from os import unlink [unlink(i) if isfile(i) else True for i in remove] # make offseted avs if len(a) > 1: try: from chapparse import writeAvisynth fNum = [i[0] for i in Trims2] set = {'avs': '"' + a[1] + '"', 'input': '', 'resize': ''} writeAvisynth(set, fNum) except ImportError: print('Script chapparse.py needed for avisynth output to work.') # write chapters if chapter_type: if chapter_type == 'MKV': Trims2ts = [(fmt_time(i[0]), fmt_time(i[1]) if i[1] != 0 else None) for i in Trims2ts] if o.template: from templates import AutoMKVChapters as amkvc output = o.chapters[:-4] if not o.test else None chaps = amkvc(o.template, output=output, avs=a[0], trims=Trims2ts, kframes=Trims2, uid=o.uid, label=o.label, ifps=ifps, clip=o.clip, idr=o.IDR) else: # Assign names to each chapter if --chnames chapter_names = [] if o.chnames: with open(o.chnames, encoding='utf-8') as f: [chapter_names.append(line.strip()) for line in f.readlines()] if not o.chnames or len(chapter_names) < len(Trims2ts): # The if statement is for clarity; it doesn't actually do # anything useful for i in range(len(chapter_names), len(Trims2ts)): chapter_names.append("Chapter {:02d}".format(i + 1)) if chapter_type == 'MKV': from templates import AutoMKVChapters as amkvc tmp = amkvc.Template() tmp.trims = Trims2ts tmp.kframes = Trims2 if o.qpfile: tmp.qpf = o.qpfile tmp.idr = o.IDR ed = tmp.Edition() ed.default = 1 ed.num_chapters = len(chapter_names) ed.uid = int(o.uid) * 100 if o.uid else tmp.uid * 100 cuid = ed.uid ed.chapters = [] for i in range(len(chapter_names)): ch = tmp.Chapter() cuid += 1 ch.uid = cuid ch.name = [chapter_names[i]] ch.start, ch.end = (Trims2ts[i][0], Trims2ts[i][1]) ed.chapters.append(ch) tmp.editions = [ed] chaps = tmp if not o.test: if chapter_type == 'MKV': chaps.toxml(o.chapters[:-4]) else: with open(o.chapters, "w", encoding='utf-8') as output: if chapter_type == 'OGM': chap = ('CHAPTER{1:02d}={0}\nCHAPTER{1:02d}' 'NAME={2}\n') elif chapter_type == 'X264': chap = '{0} {2}\n' Trims2ts = [fmt_time(i[0], 1) for i in Trims2ts] [output.write(chap.format(Trims2ts[i], i + 1, chapter_names[i])) for i in range(len(Trims2ts))] if o.verbose: print("Writing {} Chapters to {}". format(chapter_type, o.chapters))
def main(args): from optparse import OptionParser p = OptionParser(description='Grabs avisynth trims and outputs chapter ' 'file, qpfile and/or cuts audio (works with cfr and ' 'vfr input)', version='VFR Chapter Creator 0.10.0', usage='%prog [options] infile.avs [outfile.avs]') p.add_option('--label', '-l', action="store", dest="label", help="Look for a trim() statement or succeeding comment only " "on lines matching LABEL. Default: case insensitive trim") p.add_option('--clip', action="store", dest="clip", help="Look for trims() using specific clip, like" "Trim(ClipX,0,100). Default: any trim") p.add_option('--line', '-g', action="store", type="int", dest="line", help="Specify directly the line used") p.add_option('--input', '-i', action="store", help='Audio file to be cut', dest="input") p.add_option('--output', '-o', action="store", help='Cut audio from MKVMerge', dest="output") p.add_option('--fps', '-f', action="store", help='Frames per second or Timecodes file', dest="fps") p.add_option('--ofps', action="store", help='Output frames per second', dest="ofps") p.add_option('--timecodes', action="store", help='Output v2 timecodes', dest="otc") p.add_option('--chapters', '-c', action="store", help='Chapters file [.{0}/.txt]'.format("/.".join( exts.keys())), dest="chapters") p.add_option('--chnames', '-n', action="store", help='Path to template file for chapter names (utf8 w/o bom)', dest="chnames") p.add_option('--template', '-t', action="store", help="Template file for chapters", dest="template") p.add_option('--uid', action="store", help="Base UID for --template or --chnames", dest="uid") p.add_option('--qpfile', '-q', action="store", help='QPFile for x264', dest="qpfile") p.add_option('--verbose', '-v', action="store_true", help='Verbose', dest="verbose") p.add_option('--merge', '-m', action="store_true", help='Merge cut files', dest="merge") p.add_option('--remove', '-r', action="store_true", help='Remove cut files', dest="remove") p.add_option('--delay', '-d', action="store", help="Set delay of audio (can be negative)", dest="delay") p.add_option('--reverse', '-b', action="store_true", help="Reverse parsing of .avs", dest="reverse") p.add_option('--test', action="store_true", help="Test mode (do not create new files)", dest="test") p.add_option( '--IDR', '--idr', action="store_true", help="Set this to make qpfile with IDR frames instead of K frames", dest="IDR") p.add_option('--sbr', action="store_true", help="Set this if inputting an .aac and it's SBR/HE-AAC", dest="sbr") (o, a) = p.parse_args(args) if len(a) < 1: p.error("No avisynth script specified.") if not o.fps: o.fps = default_fps ifps = False else: ifps = True #Determine chapter type if o.chapters: chre = compile("\.({0})$(?i)".format("|".join(exts.keys()))) ret = chre.search(o.chapters) chapter_type = exts[ret.group(1).lower()] if ret else "OGM" else: chapter_type = '' if o.template and o.chnames: p.error("Choose either --chnames or --template, not both.") elif o.template and chapter_type != 'MKV': p.error("--template needs to output to .xml.") if not o.output and o.input: ret = splitext(o.input) o.output = '{0}.cut.mka'.format(ret[0]) if o.verbose: status = "Avisynth file: \t{0}\n".format(a[0]) status += "Label: \t\t{0}\n".format(o.label) if o.label else "" status += "Clip name: \t{0}\n".format(o.clip) if o.clip else "" status += ("Parsing order: \t{0}\n".format( "Bottom to top" if o.reverse else "Top to bottom")) status += "Line: \t\t{0}\n".format(o.line) if o.line else "" status += ("Audio file: \t{0}{1}\n".format( o.input, "(SBR)" if o.sbr else "") if o.input else "") status += "Cut Audio file: {0}\n".format(o.output) if o.output else "" status += "Timecodes/FPS: \t{0}{1}\n".format( o.fps, " to " + o.ofps if o.ofps else "") if o.ofps != o.fps else "" status += "Output v2 Tc: \t{0}\n".format(o.otc) if o.otc else "" status += ("Chapters file: \t{0}{1}\n".format( o.chapters, " ({0})".format(chapter_type) if chapter_type else "") if o.chapters else "") status += ("Chapter Names: \t{0}\n".format(o.chnames) if o.chnames else "") status += ("Template file: \t{0}\n".format(o.template) if o.template else "") status += "QP file: \t{0} ({1} frames)\n".format( o.qpfile, 'I' if o.IDR else 'K') if o.qpfile else "" status += "\n" status += ("Merge/Rem files:{0}/{1}\n".format(o.merge, o.remove) if o.merge or o.remove else "") status += ("Verbose: \t{0}\n".format(o.verbose) if o.verbose else "") status += "Test Mode: \t{0}\n".format(o.test) if o.test else "" print(status) # Get frame numbers and corresponding timecodes from avs Trims, Trimsts, Trims2, Trims2ts, audio = parse_trims( a[0], o.fps, o.ofps, o.otc if not o.test else '', o.input, o.label, o.reverse, o.line, o.clip, o.merge) nt2 = len(Trims2ts) if o.verbose: print('In trims: {0}\n'.format(', '.join( ['({0},{1})'.format(i[0], i[1]) for i in Trims]))) print('In timecodes: {0}\n'.format(', '.join( ['({0},{1})'.format(i[0], i[1]) for i in Trimsts]))) print('Out trims: {0}\n'.format(', '.join( ['({0},{1})'.format(i[0], i[1]) for i in Trims2]))) print('Out timecodes: {0}\n'.format(', '.join([ '({0},{1})'.format(fmt_time(i[0]), fmt_time(i[1])) for i in Trims2ts ]))) # make qpfile if o.qpfile and not o.template: if not o.test: write_qpfile(o.qpfile, Trims2, o.IDR) if o.verbose: print('Writing keyframes to {0}\n'.format(o.qpfile)) # make audio cuts if o.input: split_audio(audio, o.input, o.output, o.delay, o.sbr, o.merge, o.remove, o.verbose, o.test) # make offseted avs if len(a) > 1: try: from chapparse import writeAvisynth fNum = [i[0] for i in Trims2] set = {'avs': '"' + a[1] + '"', 'input': '', 'resize': ''} writeAvisynth(set, fNum) except ImportError: print('Script chapparse.py needed for avisynth output to work.') # write chapters if chapter_type: if chapter_type == 'MKV': Trims2ts = [(fmt_time(i[0]), fmt_time(i[1]) if i[1] != 0 else None) for i in Trims2ts] if o.template: from templates import AutoMKVChapters as amkvc output = o.chapters[:-4] if not o.test else None chaps = amkvc(o.template, output=output, avs=a[0], trims=Trims2ts, kframes=Trims2, uid=o.uid, label=o.label, ifps=ifps, clip=o.clip, idr=o.IDR) else: # Assign names to each chapter if --chnames chapter_names = [] if o.chnames: with open(o.chnames, encoding='utf-8') as f: [ chapter_names.append(line.strip()) for line in f.readlines() ] if not o.chnames or len(chapter_names) < len(Trims2ts): # The if statement is for clarity; it doesn't actually do # anything useful for i in range(len(chapter_names), len(Trims2ts)): chapter_names.append("Chapter {:02d}".format(i + 1)) if chapter_type == 'MKV': from templates import AutoMKVChapters as amkvc tmp = amkvc.Template() tmp.trims = Trims2ts tmp.kframes = Trims2 if o.qpfile: tmp.qpf = o.qpfile tmp.idr = o.IDR ed = tmp.Edition() ed.default = 1 ed.num_chapters = len(chapter_names) ed.uid = int(o.uid) * 100 if o.uid else tmp.uid * 100 cuid = ed.uid ed.chapters = [] for i in range(len(chapter_names)): ch = tmp.Chapter() cuid += 1 ch.uid = cuid ch.name = [chapter_names[i]] ch.start, ch.end = (Trims2ts[i][0], Trims2ts[i][1]) ed.chapters.append(ch) tmp.editions = [ed] chaps = tmp if not o.test: if chapter_type == 'MKV': chaps.toxml(o.chapters[:-4]) else: with open(o.chapters, "w", encoding='utf-8') as output: if chapter_type == 'OGM': chap = ('CHAPTER{1:02d}={0}\nCHAPTER{1:02d}' 'NAME={2}\n') elif chapter_type == 'X264': chap = '{0} {2}\n' Trims2ts = [fmt_time(i[0], 1) for i in Trims2ts] [ output.write( chap.format(Trims2ts[i], i + 1, chapter_names[i])) for i in range(len(Trims2ts)) ] if o.verbose: print("Writing {} Chapters to {}".format(chapter_type, o.chapters))