From 2a8307b98d31f23a9434ba40697d54ab15764e6a Mon Sep 17 00:00:00 2001 From: rlaphoenix Date: Tue, 16 May 2023 21:55:53 +0100 Subject: [PATCH] Decrypt DASH downloads after merging all segments Since DASH doesn't have the ability to change keys dynamically per-track (Representation), there's no need for the DASH downloader to decrypt segments as they are downloaded (like HLS). This halves the amount of processes needing to be opened as well as the I/O usage. It may result in noticeably lower CPU usage. Since the IOPS is lowered, you may even see an increase in download speed if downloading to something like a meh HDD. This also fixes decryption in some weird edge-cases where decrypting each segment individually resulted in timestamp anomalies causing shaka to fail. --- devine/core/manifests/dash.py | 40 +++++++++++++++++------------------ 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/devine/core/manifests/dash.py b/devine/core/manifests/dash.py index 8087616..d192cc6 100644 --- a/devine/core/manifests/dash.py +++ b/devine/core/manifests/dash.py @@ -445,29 +445,18 @@ class DASH: data_size = segment_save_path.stat().st_size - if isinstance(track, Audio) or init_data: + # fix audio decryption on ATVP by fixing the sample description index + # TODO: Should this be done in the video data or the init data? + if isinstance(track, Audio): with open(segment_save_path, "rb+") as f: segment_data = f.read() - if isinstance(track, Audio): - # fix audio decryption on ATVP by fixing the sample description index - # TODO: Is this in mpeg data, or init data? - segment_data = re.sub( - b"(tfhd\x00\x02\x00\x1a\x00\x00\x00\x01\x00\x00\x00)\x02", - b"\\g<1>\x01", - segment_data - ) - # prepend the init data to be able to decrypt - if init_data: - f.seek(0) - f.write(init_data) - f.write(segment_data) - - if drm: - # TODO: What if the manifest does not mention DRM, but has DRM - drm.decrypt(segment_save_path) - track.drm = None - if callable(track.OnDecrypted): - track.OnDecrypted(track) + segment_data = re.sub( + b"(tfhd\x00\x02\x00\x1a\x00\x00\x00\x01\x00\x00\x00)\x02", + b"\\g<1>\x01", + segment_data + ) + f.seek(0) + f.write(segment_data) return data_size @@ -524,10 +513,19 @@ class DASH: download_sizes.clear() with open(save_path, "wb") as f: + if init_data: + f.write(init_data) for segment_file in sorted(save_dir.iterdir()): f.write(segment_file.read_bytes()) segment_file.unlink() + if drm: + # TODO: What if the manifest does not mention DRM, but has DRM + drm.decrypt(save_path) + track.drm = None + if callable(track.OnDecrypted): + track.OnDecrypted(track) + track.path = save_path save_dir.rmdir()