Choggbuster is a set of python scripts aimed at automated preprocessing of video DVDs for archival and filtering
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

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)