Choggbuster/dvd_ripper.py

66 lines
2.2 KiB
Python
Raw Normal View History

import cffi
import os
import sys
import time
2021-10-28 19:27:15 +00:00
from dvdnav import DVDNav,DVDError
from dvdread import DVDRead
import subprocess as SP
import json
2021-10-28 19:27:15 +00:00
from glob import glob
import itertools as ITT
from vob_demux import demux
from ff_d2v import make_d2v
2021-10-28 19:27:15 +00:00
def loadlib(dll_path, *includes, **kwargs):
ffi = cffi.FFI()
for include in includes:
2021-10-28 19:27:15 +00:00
ffi.cdef(open(include).read(), kwargs)
return ffi, ffi.dlopen(dll_path)
2021-10-28 19:27:15 +00:00
for dvd_path in ITT.chain.from_iterable(map(glob,sys.argv[1:])):
r = DVDRead(dvd_path)
# r.grab_ifos()
# r.grab_vobs()
# exit()
2021-10-28 19:27:15 +00:00
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)