Choggbuster/vob_demux.py

108 lines
2.9 KiB
Python

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])