Absorb original file and path in Decrypt, Repack, & Range Operations

To possibly support download resuming in the future, the file names for the decrypt, repack, and change range functions were simplified and once output has finished it then deletes the original input file and re-uses the original input file path.

The file names were changed to just append `_repack`, `_decrypted`, `_full_range` etc. to the filename rather than using a duplex extension (`.repack.mp4`, `.decrypted.mp4`, `.range0.mp4`).

This is all so that code to check if the file was already downloaded can be simpler. Instead of having to check if 4x different possible file names for a completed download existed, it checks one.
This commit is contained in:
rlaphoenix 2024-01-12 01:11:47 +00:00
parent ee56bc87c2
commit 0116c278af
4 changed files with 18 additions and 16 deletions

View File

@ -822,13 +822,10 @@ class dl:
save_dir = save_path.parent save_dir = save_path.parent
def cleanup(): def cleanup():
# e.g., foo.mp4 # track file (e.g., "foo.mp4")
save_path.unlink(missing_ok=True) save_path.unlink(missing_ok=True)
# e.g., foo.mp4.aria2 # aria2c control file (e.g., "foo.mp4.aria2")
save_path.with_suffix(f"{save_path.suffix}.aria2").unlink(missing_ok=True) save_path.with_suffix(f"{save_path.suffix}.aria2").unlink(missing_ok=True)
for file in config.directories.temp.glob(f"{save_path.stem}.*{save_path.suffix}"):
# e.g., foo.decrypted.mp4, foo.repack.mp4, and such
file.unlink()
if save_dir.exists() and save_dir.name.endswith("_segments"): if save_dir.exists() and save_dir.name.endswith("_segments"):
shutil.rmtree(save_dir) shutil.rmtree(save_dir)

View File

@ -230,12 +230,12 @@ class Widevine:
if not path or not path.exists(): if not path or not path.exists():
raise ValueError("Tried to decrypt a file that does not exist.") raise ValueError("Tried to decrypt a file that does not exist.")
decrypted_path = path.with_suffix(f".decrypted{path.suffix}") output_path = path.with_stem(f"{path.stem}_decrypted")
config.directories.temp.mkdir(parents=True, exist_ok=True) config.directories.temp.mkdir(parents=True, exist_ok=True)
try: try:
arguments = [ arguments = [
f"input={path},stream=0,output={decrypted_path}", f"input={path},stream=0,output={output_path}",
"--enable_raw_key_decryption", "--keys", "--enable_raw_key_decryption", "--keys",
",".join([ ",".join([
*[ *[
@ -294,7 +294,7 @@ class Widevine:
path.unlink() path.unlink()
if not stream_skipped: if not stream_skipped:
shutil.move(decrypted_path, path) shutil.move(output_path, path)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
if e.returncode == 0xC000013A: # STATUS_CONTROL_C_EXIT if e.returncode == 0xC000013A: # STATUS_CONTROL_C_EXIT
raise KeyboardInterrupt() raise KeyboardInterrupt()

View File

@ -229,20 +229,21 @@ class Track:
if not executable: if not executable:
raise EnvironmentError("FFmpeg executable \"ffmpeg\" was not found but is required for this call.") raise EnvironmentError("FFmpeg executable \"ffmpeg\" was not found but is required for this call.")
repacked_path = self.path.with_suffix(f".repack{self.path.suffix}") original_path = self.path
output_path = original_path.with_stem(f"{original_path.stem}_repack")
def _ffmpeg(extra_args: list[str] = None): def _ffmpeg(extra_args: list[str] = None):
subprocess.run( subprocess.run(
[ [
executable, "-hide_banner", executable, "-hide_banner",
"-loglevel", "error", "-loglevel", "error",
"-i", self.path, "-i", original_path,
*(extra_args or []), *(extra_args or []),
# Following are very important! # Following are very important!
"-map_metadata", "-1", # don't transfer metadata to output file "-map_metadata", "-1", # don't transfer metadata to output file
"-fflags", "bitexact", # only have minimal tag data, reproducible mux "-fflags", "bitexact", # only have minimal tag data, reproducible mux
"-codec", "copy", "-codec", "copy",
str(repacked_path) str(output_path)
], ],
check=True, check=True,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
@ -258,7 +259,8 @@ class Track:
else: else:
raise raise
self.swap(repacked_path) self.swap(output_path)
self.move(original_path)
def move(self, target: Union[str, Path]) -> bool: def move(self, target: Union[str, Path]) -> bool:
""" """

View File

@ -188,17 +188,20 @@ class Video(Track):
Video.Codec.HEVC: "hevc_metadata" Video.Codec.HEVC: "hevc_metadata"
}[self.codec] }[self.codec]
changed_path = self.path.with_suffix(f".range{range_}{self.path.suffix}") original_path = self.path
output_path = original_path.with_stem(f"{original_path.stem}_{['limited', 'full'][range_]}_range")
subprocess.run([ subprocess.run([
executable, "-hide_banner", executable, "-hide_banner",
"-loglevel", "panic", "-loglevel", "panic",
"-i", self.path, "-i", original_path,
"-codec", "copy", "-codec", "copy",
"-bsf:v", f"{filter_key}=video_full_range_flag={range_}", "-bsf:v", f"{filter_key}=video_full_range_flag={range_}",
str(changed_path) str(output_path)
], check=True) ], check=True)
self.swap(changed_path) self.swap(output_path)
self.move(original_path)
def ccextractor( def ccextractor(
self, track_id: Any, out_path: Union[Path, str], language: Language, original: bool = False self, track_id: Any, out_path: Union[Path, str], language: Language, original: bool = False