Choggbuster/dvd_ripper.py

66 lines
2.2 KiB
Python

import cffi
import os
import sys
import time
from dvdnav import DVDNav,DVDError
from dvdread import DVDRead
import subprocess as SP
import json
from glob import glob
import itertools as ITT
from vob_demux import demux
from ff_d2v import make_d2v
def loadlib(dll_path, *includes, **kwargs):
ffi = cffi.FFI()
for include in includes:
ffi.cdef(open(include).read(), kwargs)
return ffi, ffi.dlopen(dll_path)
for dvd_path in ITT.chain.from_iterable(map(glob,sys.argv[1:])):
r = DVDRead(dvd_path)
# r.grab_ifos()
# r.grab_vobs()
# exit()
out_folder = os.path.join(
"out", "_".join([r.disc_id, r.udf_disc_name or r.iso_disc_name]).replace(" ", "_")
)
os.makedirs(out_folder, exist_ok=True)
d = DVDNav(dvd_path)
to_demux = []
for k, v in d.titles.items():
v["duration"] = v["duration"].total_seconds()
v["chapters"] = [c.total_seconds() for c in v["chapters"]]
d.titles[k] = v
with open(os.path.join(out_folder, f"{k:03}.json"), "w") as fh:
json.dump(v, fh)
for a in range(0,99):
block=0
outfile = os.path.join(out_folder, f"t{k:03}_a{a:03}_b{block:03}.vob")
to_demux.append(outfile)
fh = open(outfile, "wb")
try:
for block in d.get_blocks(k, a):
if isinstance(block, int):
outfile = os.path.join(out_folder, f"t{k:03}_a{a:03}_b{block:03}.vob")
to_demux.append(outfile)
if fh:
fh.close()
fh = open(outfile, "wb")
else:
fh.write(block)
except DVDError as e:
if str(e)!="Invalid angle specified!":
raise
if fh.tell()==0:
fh.close()
os.unlink(fh.name)
while fh.name in to_demux:
to_demux.remove(fh.name)
for file in to_demux:
demux(file)
os.unlink(file)
for file in glob(os.path.join(out_folder,"*.m2v")):
make_d2v(file)