import json import os import subprocess as SP import sys import shutil def get_streams(path): proc = SP.Popen( [ "ffprobe", "-probesize", str(0x7FFFFFFF), "-analyzeduration", str(0x7FFFFFFF), "-v", "fatal", "-i", path, "-show_streams", "-show_format", "-print_format", "json", ], stdout=SP.PIPE, stdin=SP.DEVNULL, bufsize=0, ) data = json.load(proc.stdout) ret = proc.wait() if ret != 0: return [], {} return data["streams"], data["format"] def ccextract(files): ccextractor = shutil.which("ccextractor") or shutil.which("ccextractorwinfull") if ccextractor is None and os.name=="nt": ccextractor=os.path.expandvars(os.path.join("${PROGRAMFILES(X86)}","CCExtractor","ccextractorwinfull.exe")) if not os.path.isfile(ccextractor): print("WARNING: CCExtractor not found") return [] new_files=[] for file in files: outfile=os.path.splitext(file)[0] outfile=os.path.extsep.join([outfile, "cc.srt"]) ret=SP.call([ccextractor, "-sc", "-sbs", "-autodash", "-trim","-nobom","-o", outfile, file]) if ret==10: if os.path.isfile(outfile): os.unlink(outfile) continue new_files.append(outfile) return new_files types = {"mpeg2video": "m2v", "ac3": "ac3", "dvd_subtitle": "sub.mkv", "eia_608": "srt"} def demux(path): folder = os.path.dirname(path) basename = os.path.splitext(os.path.basename(path))[0] streams, _ = get_streams(path) cmd = [ "ffmpeg", "-y", "-probesize", str(0x7FFFFFFF), "-analyzeduration", str(0x7FFFFFFF), "-i", path, "-strict", "-2", ] caption_files = [] for stream in streams: codec = stream["codec_name"] ext = types.get(codec, codec) hex_id = stream["id"] codec_name = stream["codec_long_name"] outfile = os.path.join(folder, f"{basename}_{hex_id}") if codec == "dvd_nav_packet": continue outfile = os.path.extsep.join([outfile, ext]) print(hex_id, codec_name, codec) if codec == "mpeg2video": caption_files.append(outfile) cmd += [ "-map", f"0:#{hex_id}", "-vcodec", "copy", "-acodec", "copy", "-scodec", "copy", "-strict", "-2", outfile, ] SP.check_call(cmd) ccextract(caption_files) for file in os.listdir(folder): if os.path.isfile(file): if os.stat(file).st_size==0: os.unlink(file) if __name__ == "__main__": demux(sys.argv[1])