You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
3.2 KiB
99 lines
3.2 KiB
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)
|
|
|