def run(self, clean_up: bool = True, make_comp: bool = True) -> None: """ :param clean_up: Perform clean-up procedure after encoding :param make_comp: Create a slowpics-compatible comparison between src, flt, and enc """ v_encoder = X265Encoder('settings/x265_settings_BD') v_lossless_encoder = FFV1Encoder() self.clip = dither_down(self.clip) video_track = VideoStream(self.file.name_clip_output, 'HEVC BDRip by LightArrowsEXE@Kaleido', JAPANESE) audio_files = video_source(self.file.path.to_str(), out_file=self.file.a_src_cut, trim_list=resolve_trims( self.file.trims_or_dfs), trims_framerate=self.file.clip.fps, frames_total=self.file.clip.num_frames, flac=False, aac=True, silent=False) audio_tracks: List[AudioStream] = [] for track in audio_files: audio_tracks += [ AudioStream(VPath(track), 'AAC 2.0', JAPANESE, XML_TAG) ] muxer = Mux(self.file, streams=(video_track, audio_tracks, None)) config = RunnerConfig(v_encoder=v_encoder, v_lossless_encoder=v_lossless_encoder, a_extracters=None, a_cutters=None, a_encoders=None, muxer=muxer) runner = SelfRunner(self.clip, self.file, config) runner.run() if clean_up: runner.do_cleanup() for at in audio_files: try: os.remove(at) except FileNotFoundError: Status.warn(f"File {at} not found! Skipping...") if make_comp: try: generate_comparison(self.file, self.file.name_file_final.to_str(), self.clip) except ValueError as e: print(e)
def run(self, clean_up: bool = True, zones: Optional[Dict[Tuple[int, int], Dict[str, Any]]] = None) -> None: """ :param clean_up: Perform clean-up procedure after encoding :param zones: Zones for x265 """ v_encoder = X265Encoder('settings/x265_settings', zones=zones) v_lossless_encoder = FFV1Encoder() self.clip = dither_down(self.clip) video_track = VideoStream(self.file.name_clip_output, 'HEVC BDRip by LightArrowsEXE@Kaleido', JAPANESE) audio_files = video_source(self.file.path.to_str(), out_file=self.file.a_src_cut, trim_list=resolve_trims( self.file.trims_or_dfs), trims_framerate=self.file.clip.fps, frames_total=self.file.clip.num_frames, flac=True, aac=False, silent=False) audio_tracks: List[AudioStream] = [] for track in audio_files: audio_tracks += [AudioStream(VPath(track), 'FLAC 2.0', JAPANESE)] muxer = Mux(self.file, streams=(video_track, audio_tracks, None)) config = RunnerConfig(v_encoder=v_encoder, v_lossless_encoder=v_lossless_encoder, a_extracters=None, a_cutters=None, a_encoders=None, muxer=muxer) runner = SelfRunner(self.clip, self.file, config) runner.run() if clean_up: runner.do_cleanup() for at in audio_files: try: os.remove(at) except FileNotFoundError: Status.warn(f"File {at} not found! Skipping...")
def pick_settings(f: FileInfo) -> str: ep = f.name[-2:] try: int(ep) except ValueError: ep = f.name[-5:] settings_file = f'settings/x265_settings_BD_{ep}' if not os.path.exists(settings_file): Status.warn( f"Couldn't find \"{settings_file}\"; using default settings") settings_file = 'settings/x265_settings_BD' return settings_file
def patch( self, ranges: Union[Union[int, Tuple[int, int]], List[Union[int, Tuple[int, int]]]], clean_up: bool = True, external_file: Optional[Union[os.PathLike[str], str]] = None) -> None: """ :ranges: Frame ranges that require patching. Expects as a list of tuples or integers (can be mixed). Examples: [(0, 100), (400, 600)]; [50, (100, 200), 500] :param clean_up: Perform clean-up procedure after patching :external_file: File to patch into. This is intended for videos like NCs with only one or two changes so you don't need to encode the entire thing multiple times. It will copy the given file and rename it to ``FileInfo.name_file_final``. If None, performs regular patching. """ v_encoder = X265Encoder('settings/x265_settings') self.clip = dither_down(self.clip) if external_file: if os.path.exists(external_file): Status.info( f"Copying {external_file} to {self.file.name_file_final}") shutil.copy(external_file, self.file.name_file_final) else: Status.warn( f"{self.file.name_file_final} already exists; please ensure it's the correct file!" ) runner = Patch( clip=self.clip, ranges=ranges, # type:ignore[arg-type] encoder=v_encoder, file=self.file, ) runner.run() new = f"{self.file.name_file_final.to_str()[:-4]}_new.mkv" Status.info(f"Replacing {self.file.name_file_final} -> {new}") os.replace(new, self.file.name_file_final) if clean_up: runner.do_cleanup()
def pick_settings(f: FileInfo) -> str: ep = f.name[-2:] try: int(ep) except ValueError: ep = f.name[-3:] base = 'settings/x265_settings_BD' settings_file = f'{base}_{ep}' if not os.path.exists(settings_file): # Double-check, there's probably a nicer way to write out there but oh well ep = f.name[-7:] settings_file = f'{base}_{ep}' if not os.path.exists(settings_file): Status.warn(f"Couldn't find \"{settings_file}\"; falling back to default settings") settings_file = base else: Status.info(f"Succesfully found {settings_file}") return settings_file
def run(self, clean_up: bool = True, make_comp: bool = True, BDMV: bool = False, zones: Optional[Dict[Tuple[int, int], Dict[str, Any]]] = None) -> None: """ :param clean_up: Perform clean-up procedure after encoding :param make_comp: Create a slowpics-compatible comparison between src, flt, and enc """ # assert self.file.a_src v_encoder = X265Encoder(pick_settings(self.file), zones=zones) v_lossless_encoder = FFV1Encoder() self.clip = dither_down(self.clip) if BDMV: # For use with BDMVs, *not* Switch/PS4 rips audio_files = video_source(self.file.path.to_str(), out_file=self.file.a_src_cut, trim_list=resolve_trims( self.file.trims_or_dfs), trims_framerate=self.file.clip.fps, flac=True, aac=False, silent=False) audio_tracks: List[AudioStream] = [] for track in audio_files: audio_tracks += [ AudioStream(VPath(track), 'FLAC 2.0', JAPANESE) ] else: a_extracters = FfmpegAudioExtracter(self.file, track_in=0, track_out=0) a_cutters = EztrimCutter(self.file, track=1) credit = 'HEVC GameRip by LightArrowsEXE@Kaleido' if not BDMV \ else 'HEVC BDRip by LightArrowsEXE@Kaleido' muxer = Mux( self.file, streams=(VideoStream( self.file.name_clip_output, credit, JAPANESE), audio_tracks[0] if BDMV else AudioStream( self.file.a_src_cut.set_track(1), 'AAC 2.0', JAPANESE), None)) config = RunnerConfig(v_encoder, v_lossless_encoder, None if BDMV else a_extracters, None if BDMV else a_cutters, None, muxer) runner = SelfRunner(self.clip, self.file, config) runner.run() if clean_up: runner.do_cleanup() for at in audio_files: try: os.remove(at) except FileNotFoundError: Status.warn(f"File {at} not found! Skipping") if make_comp: try: generate_comparison(self.file, self.file.name_file_final.to_str(), self.clip) except ValueError as e: Status.fail(str(e))
def run(self, clean_up: bool = True, make_comp: bool = True, zones: Optional[Dict[Tuple[int, int], Dict[str, Any]]] = None) -> None: """ :param clean_up: Perform clean-up procedure after encoding :param make_comp: Create a slowpics-compatible comparison between src, flt, and enc """ assert self.file.a_src v_encoder = X265Encoder(pick_settings(self.file), zones=zones) self.clip = dither_down(self.clip) audio_files = video_source(self.file.path.to_str(), trim_list=resolve_trims( self.file.trims_or_dfs), trims_framerate=self.file.clip.fps, flac=False, aac=True, silent=False) audio_tracks: List[AudioStream] = [] for track in audio_files: audio_tracks += [ AudioStream(VPath(track), 'AAC 2.0', JAPANESE, XML_TAG) ] if self.chapter_list: assert self.file.chapter assert self.file.trims_or_dfs if not isinstance(self.chapter_offset, int): self.chapter_offset = self.file.trims_or_dfs[ 0] * -1 # type: ignore chapxml = MatroskaXMLChapters(self.file.chapter) chapxml.create(self.chapter_list, self.file.clip.fps) chapxml.shift_times(self.chapter_offset, self.file.clip.fps) # type: ignore chapxml.set_names(self.chapter_names) chapters = ChapterStream(chapxml.chapter_file, JAPANESE) muxer = Mux(self.file, streams=(VideoStream( self.file.name_clip_output, 'HEVC BDRip by LightArrowsEXE@Kaleido', JAPANESE), audio_tracks, chapters if self.chapter_list else None)) config = RunnerConfig(v_encoder, None, None, None, None, muxer) runner = SelfRunner(self.clip, self.file, config) runner.run() try: if make_comp: generate_comparison(self.file, self.file.name_file_final.to_str(), self.clip) except ValueError as e: Status.fail(str(e)) if clean_up: runner.do_cleanup() for at in audio_files: try: os.remove(at) except FileNotFoundError: Status.warn(f"File \"{at}\" not found! Skipping")
def run(self, clean_up: bool = True, make_comp: bool = True) -> None: """ :param clean_up: Perform clean-up procedure after encoding :param make_comp: Create a slowpics-compatible comparison between src, flt, and enc """ assert self.file.a_src assert self.file.a_src_cut v_encoder = X265Encoder('settings/x265_settings') self.clip = dither_down(self.clip) # Silly to encode AAC -> AAC, but the bitrate is gonna be so comparatively high that it *shouldn't* matter audio_files = video_source(self.file.path.to_str(), trimlist=verify_trim( self.file.trims_or_dfs), framerate=self.file.clip.fps, noflac=True, noaac=False, silent=False) audio_tracks: List[AudioStream] = [] for track in audio_files: Status.warn(track) audio_tracks += [ AudioStream(VPath(track), 'AAC 2.0', JAPANESE, XML_TAG) ] if self.chapter_list: assert self.file.chapter assert self.file.trims_or_dfs Path("/chapters").mkdir(parents=True, exist_ok=True) if not isinstance(self.chapter_offset, int): self.chapter_offset = self.file.trims_or_dfs[ 0] * -1 # type: ignore chapxml = MatroskaXMLChapters(self.file.chapter) chapxml.create(self.chapter_list, self.file.clip.fps) chapxml.shift_times(self.chapter_offset, self.file.clip.fps) # type: ignore chapxml.set_names(self.chapter_names) chapters = ChapterStream(chapxml.chapter_file, JAPANESE) muxer = Mux(self.file, streams=(VideoStream( self.file.name_clip_output, 'HEVC BDRip by LightArrowsEXE@Kaleido', JAPANESE), audio_tracks, chapters if self.chapter_list else None)) config = RunnerConfig(v_encoder, None, None, None, None, muxer) runner = SelfRunner(self.clip, self.file, config) runner.run() #appendCRC(self.file.name_file_final) if make_comp: try: generate_comparison(self.file, self.file.name_file_final.to_str(), self.clip) except ValueError as e: Status.fail(f"{e}") if clean_up: runner.do_cleanup() for f in audio_files: try: os.remove(f) except FileExistsError as e: Status.warn(str(e))