5
0

yt_common: subsplease is good again

This commit is contained in:
louis f 2021-04-25 09:57:06 -04:00
parent 2784de289a
commit 790e4c3569
Signed by: louis
GPG Key ID: 44D7E1DE4E23D6F2
2 changed files with 59 additions and 42 deletions

View File

@ -12,7 +12,7 @@ from typing import Any, BinaryIO, Callable, List, Optional, Sequence, Union, cas
from .config import Config from .config import Config
from .logging import log from .logging import log
from .source import AMAZON_FILENAME, ER_FILENAME, SUBSPLS_FILENAME, FUNI_INTRO, glob_crc from .source import AMAZON_FILENAME, ER_FILENAME, SUBSPLS_FILENAME, FUNI_INTRO, glob_filename
core = vs.core core = vs.core
@ -141,17 +141,14 @@ class AudioGetter():
log.success("Found Amazon audio") log.success("Found Amazon audio")
return return
# as of Ep4 SubsPlease is using new funi 128kbps aac while erai has 256kbps still
try: try:
if os.path.isfile(self.config.format_filename(ER_FILENAME)): self.audio_file = glob_filename(self.config.format_filename(SUBSPLS_FILENAME))
self.audio_file = self.config.format_filename(ER_FILENAME) self.video_src = core.ffms2.Source(self.audio_file)
self.video_src = core.ffms2.Source(self.audio_file) except FileNotFoundError:
elif os.path.isfile(glob_crc(self.config.format_filename(SUBSPLS_FILENAME))): pass
self.audio_file = glob_crc(self.config.format_filename(SUBSPLS_FILENAME)) try:
self.video_src = core.ffms2.Source(self.audio_file) self.audio_file = glob_filename(self.config.format_filename(ER_FILENAME))
log.warn("Using SubsPlease, audio may be worse than Erai-Raws") self.video_src = core.ffms2.Source(self.audio_file)
else:
raise FileNotFoundError()
except FileNotFoundError: except FileNotFoundError:
log.error("Could not find audio") log.error("Could not find audio")
raise raise
@ -203,6 +200,8 @@ class SelfRunner():
encoder: Encoder encoder: Encoder
audio: AudioGetter audio: AudioGetter
profile: str
def __init__(self, config: Config, final_filter: Callable[[], vs.VideoNode], def __init__(self, config: Config, final_filter: Callable[[], vs.VideoNode],
workraw_filter: Optional[Callable[[], vs.VideoNode]] = None) -> None: workraw_filter: Optional[Callable[[], vs.VideoNode]] = None) -> None:
self.config = config self.config = config
@ -211,35 +210,30 @@ class SelfRunner():
parser = argparse.ArgumentParser(description=f"Encode {self.config.title} Episode {self.config.epnum:02d}") parser = argparse.ArgumentParser(description=f"Encode {self.config.title} Episode {self.config.epnum:02d}")
if workraw_filter: if workraw_filter:
parser.add_argument("-w", "--workraw", help="Encode workraw, fast x264", action="store_true") parser.add_argument("-w", "--workraw", help="Encode workraw, fast x264.", action="store_true")
parser.add_argument("-s", "--start", nargs='?', type=int, help="Start encode at frame START") parser.add_argument("-s", "--start", nargs='?', type=int, help="Start encode at frame START.")
parser.add_argument("-e", "--end", nargs='?', type=int, help="Stop encode at frame END (inclusive)") parser.add_argument("-e", "--end", nargs='?', type=int, help="Stop encode at frame END (inclusive).")
parser.add_argument("-k", "--keep", help="Keep raw video", action="store_true") parser.add_argument("-k", "--keep", help="Keep raw video", action="store_true")
parser.add_argument("-b", "--encoder", type=str, help="Override detected encoder binary") parser.add_argument("-b", "--encoder", type=str, help="Override detected encoder binary.")
parser.add_argument("-f", "--force", help="Overwrite existing intermediaries", action="store_true") parser.add_argument("-f", "--force", help="Overwrite existing intermediaries.", action="store_true")
parser.add_argument("-a", "--audio", type=str, help="Force audio file") parser.add_argument("-a", "--audio", type=str, help="Force audio file")
parser.add_argument("-x", "--suffix", type=str, help="Change the suffix of the mux") parser.add_argument("-x", "--suffix", type=str, help="Change the suffix of the mux. \
parser.add_argument("-c", "--comparison", help="Output a comparison between workraw and final", Will be overridden by PROFILE if set.")
parser.add_argument("-p", "--profile", type=str, help="Set the encoder profile. \
Overrides SUFFIX when set. Defaults to \"workraw\" when WORKRAW is set, else \"final.\"")
parser.add_argument("-c", "--comparison", help="Output a comparison between workraw and final. \
Will search for the output file to include in comparison, if present.",
action="store_true") action="store_true")
args = parser.parse_args() args = parser.parse_args()
if args.comparison and workraw_filter:
log.status("Generating comparison...")
gencomp(10, "comp", src=workraw_filter(), final=final_filter())
log.status("Comparison generated.")
return
self.workraw = args.workraw if workraw_filter else False self.workraw = args.workraw if workraw_filter else False
self.profile = "workraw" if self.workraw else "final"
self.profile = args.profile or self.profile
self.suffix = args.suffix if args.suffix is not None else "workraw" if self.workraw else "premux" self.suffix = args.suffix if args.suffix is not None else "workraw" if self.workraw else "premux"
self.suffix = args.profile or self.suffix
self.clip = workraw_filter() if workraw_filter and self.workraw else final_filter() self.clip = workraw_filter() if workraw_filter and self.workraw else final_filter()
basename = "workraw-settings" if self.workraw else "final-settings"
settings_path = os.path.join(self.config.datapath, basename)
if not os.path.isfile(settings_path):
raise FileNotFoundError(f"Failed to find {settings_path}!")
start = args.start if args.start is not None else 0 start = args.start if args.start is not None else 0
if args.end is not None: if args.end is not None:
if args.end < 0: if args.end < 0:
@ -260,8 +254,27 @@ class SelfRunner():
if start >= end: if start >= end:
raise ValueError("Start frame must be before end frame!") raise ValueError("Start frame must be before end frame!")
out_name = f"{self.config.title.lower()}_{self.config.epnum:02d}_{self.suffix}.mkv"
if args.comparison and workraw_filter:
log.status("Generating comparison...")
if os.path.isfile(out_name):
pmx = core.ffms2.Source(out_name)
if pmx.num_frames == self.clip.num_frames:
pmx = pmx[start:end]
gencomp(10, "comp", src=workraw_filter()[start:end], final=final_filter()[start:end], encode=pmx)
else:
gencomp(10, "comp", src=workraw_filter()[start:end], final=final_filter()[start:end])
log.status("Comparison generated.")
return
settings_path = os.path.join(self.config.datapath, f"{self.profile}-settings")
if not os.path.isfile(settings_path):
raise FileNotFoundError(f"Failed to find {settings_path}!")
self.encoder = Encoder(self.config.epnum, settings_path, args.encoder, args.force) self.encoder = Encoder(self.config.epnum, settings_path, args.encoder, args.force)
self.video_file = self.encoder.encode(self.clip, f"{self.config.epnum:02d}_{start}_{end}", start, end) self.video_file = self.encoder.encode(self.clip, f"{self.config.epnum:02d}_{self.suffix}_{start}_{end}",
start, end)
log.status("--- LOOKING FOR AUDIO ---") log.status("--- LOOKING FOR AUDIO ---")
self.audio = AudioGetter(self.config, args.audio) self.audio = AudioGetter(self.config, args.audio)
@ -271,8 +284,7 @@ class SelfRunner():
try: try:
log.status("--- MUXING FILE ---") log.status("--- MUXING FILE ---")
if self._mux(f"{self.config.title.lower()}_{self.config.epnum:02d}_{self.suffix}.mkv", if self._mux(out_name, start == 0 and end == self.clip.num_frames) != 0:
start == 0 and end == self.clip.num_frames) != 0:
raise Exception("mkvmerge failed") raise Exception("mkvmerge failed")
except Exception: except Exception:
log.error("--- MUXING FAILED ---") log.error("--- MUXING FAILED ---")
@ -316,7 +328,7 @@ def gencomp(num: int = 10, path: str = "comp", matrix: str = "709", **clips: vs.
if len(lens) != 1: if len(lens) != 1:
raise ValueError("gencomp: 'Clips must be equal length!'") raise ValueError("gencomp: 'Clips must be equal length!'")
frames = random.sample(range(lens.pop()), num) frames = sorted(random.sample(range(lens.pop()), num))
if os.path.exists(path): if os.path.exists(path):
shutil.rmtree(path) shutil.rmtree(path)

View File

@ -16,8 +16,8 @@ from .logging import log
core = vs.core core = vs.core
SUBSPLS_FILENAME: str = "[SubsPlease] {title_long} - {epnum:02d} ({resolution}p) [$CRC].mkv" SUBSPLS_FILENAME: str = "[SubsPlease] {title_long} - {epnum:02d} ({resolution}p) [$GLOB].mkv"
ER_FILENAME: str = "[Erai-raws] {title_long} - {epnum:02d} [v0][{resolution}p].mkv" ER_FILENAME: str = "[Erai-raws] {title_long} - {epnum:02d} [v0][{resolution}p]$GLOB.mkv"
FUNI_INTRO: int = 289 FUNI_INTRO: int = 289
AMAZON_FILENAME: str = "{title_long} - {epnum:02d} (Amazon Prime CBR {resolution}p).mkv" AMAZON_FILENAME: str = "{title_long} - {epnum:02d} (Amazon Prime CBR {resolution}p).mkv"
@ -37,8 +37,8 @@ def waka_replace(src: vs.VideoNode, wakas: List[vs.VideoNode], ranges: List[List
return src, new_wakas return src, new_wakas
def glob_crc(pattern: str) -> str: def glob_filename(pattern: str) -> str:
res = glob.glob(glob.escape(pattern).replace("$CRC", "*")) res = glob.glob(glob.escape(pattern).replace("$GLOB", "*"))
if len(res) == 0: if len(res) == 0:
raise FileNotFoundError(f"File matching \"{pattern}\" not found!") raise FileNotFoundError(f"File matching \"{pattern}\" not found!")
return res[0] return res[0]
@ -74,11 +74,16 @@ class FunimationSource(DehardsubFileFinder):
return core.ffms2.Source(self.config.format_filename(AMAZON_FILENAME)) return core.ffms2.Source(self.config.format_filename(AMAZON_FILENAME))
def get_funi_filename(self) -> str: def get_funi_filename(self) -> str:
if os.path.isfile(self.config.format_filename(ER_FILENAME)): try:
return self.config.format_filename(ER_FILENAME) return glob_filename(self.config.format_filename(ER_FILENAME))
except FileNotFoundError:
pass
log.error("Erai-raws not found, falling back to SubsPlease") try:
return glob_crc(self.config.format_filename(SUBSPLS_FILENAME)) return glob_filename(self.config.format_filename(SUBSPLS_FILENAME))
except FileNotFoundError:
log.error("Could not find funimation video")
raise
def get_funi(self) -> vs.VideoNode: def get_funi(self) -> vs.VideoNode:
return core.ffms2.Source(self.get_funi_filename())[FUNI_INTRO:] return core.ffms2.Source(self.get_funi_filename())[FUNI_INTRO:]