import itertools as ITT import json import os import subprocess as SP import sys import time from glob import glob import cffi from datetime import timedelta from dvdnav import DVDError, DVDNav from dvdread import DVDRead from ff_d2v import make_d2v, make_meta from vob_demux import demux def close_file_del_if_empty(fh): if not fh: return False if fh.tell() == 0: fh.close() os.unlink(fh.name) return False else: fh.close() return True dur_thr = 60.0 def process_m2v_files(path): for file in glob(os.path.join(path,"**", "*.m2v")): make_meta(file) make_d2v(file) for dvd_path in ITT.chain.from_iterable(map(glob, sys.argv[1:])): r = DVDRead(dvd_path) # r.grab_ifos() # r.grab_vobs() # exit() if os.path.isfile(dvd_path): basename = os.path.splitext(os.path.basename(dvd_path))[0] else: basename = r.iso_disc_name or r.udf_disc_name base_dir = os.path.join("out", "_".join([basename, r.disc_id]).replace(" ", "_")) if os.path.isdir(base_dir): print(f"Output foldrer {base_dir} exists, remove to re-rip DVD") process_m2v_files(base_dir) continue os.makedirs(base_dir, exist_ok=True) d = DVDNav(dvd_path) to_demux = [] for k, v in d.titles.items(): out_folder=os.path.join(base_dir,f"t{k:03}") v["duration"] = v["duration"].total_seconds() if v["chapters"]: v["chapters"] = [0.0]+[c.total_seconds() for c in v["chapters"]] avg_chapter_len = v["duration"] / len(v["chapters"]) # if avg_chapter_len<10: # continue d.titles[k] = v # if not v.get('audio'): # print(f"[{k}|0] Skipping title {k} because it has no audio tracks") # continue # if not v.get('vts'): # print(f"[{k}|0] Skipping title {k} because it has no title sets") # continue if v["duration"] < dur_thr: print( f"[{k}|0] Skipping title {k} because it is shorter than {dur_thr} seconds ({v['duration']} seconds)" ) continue os.makedirs(out_folder, exist_ok=True) with open(os.path.join(out_folder, f"title.json"), "w") as fh: json.dump(d.titles[k], fh, indent=4) with open(os.path.join(out_folder, f"chapters.txt"), "w") as fh: if set(v["chapters"])==set([0.0]): continue for n,t in enumerate(v["chapters"],1): if abs(t-v["duration"])<1.0: continue print(f"CHAPTER{n:02}={timedelta(seconds=t)}",file=fh) print(f"CHAPTER{n:02}NAME=Chapter {n}",file=fh) for a in range(0, 99): outfile = os.path.join(out_folder, f"{a:03}.vob") to_demux.append(outfile) fh = open(outfile, "wb") try: for block in d.get_blocks(k, a): fh.write(block) except DVDError as e: if str(e) != "Invalid angle specified!": raise close_file_del_if_empty(fh) to_demux = list(filter(os.path.isfile, to_demux)) for file in to_demux: demux(file) os.unlink(file) process_m2v_files(base_dir)