forked from DRMTalks/devine
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.
This commit is contained in:
parent
bdc1203514
commit
2a8307b98d
|
@ -445,30 +445,19 @@ class DASH:
|
||||||
|
|
||||||
data_size = segment_save_path.stat().st_size
|
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:
|
with open(segment_save_path, "rb+") as f:
|
||||||
segment_data = f.read()
|
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(
|
segment_data = re.sub(
|
||||||
b"(tfhd\x00\x02\x00\x1a\x00\x00\x00\x01\x00\x00\x00)\x02",
|
b"(tfhd\x00\x02\x00\x1a\x00\x00\x00\x01\x00\x00\x00)\x02",
|
||||||
b"\\g<1>\x01",
|
b"\\g<1>\x01",
|
||||||
segment_data
|
segment_data
|
||||||
)
|
)
|
||||||
# prepend the init data to be able to decrypt
|
|
||||||
if init_data:
|
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
f.write(init_data)
|
|
||||||
f.write(segment_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)
|
|
||||||
|
|
||||||
return data_size
|
return data_size
|
||||||
|
|
||||||
progress(total=len(segments))
|
progress(total=len(segments))
|
||||||
|
@ -524,10 +513,19 @@ class DASH:
|
||||||
download_sizes.clear()
|
download_sizes.clear()
|
||||||
|
|
||||||
with open(save_path, "wb") as f:
|
with open(save_path, "wb") as f:
|
||||||
|
if init_data:
|
||||||
|
f.write(init_data)
|
||||||
for segment_file in sorted(save_dir.iterdir()):
|
for segment_file in sorted(save_dir.iterdir()):
|
||||||
f.write(segment_file.read_bytes())
|
f.write(segment_file.read_bytes())
|
||||||
segment_file.unlink()
|
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
|
track.path = save_path
|
||||||
save_dir.rmdir()
|
save_dir.rmdir()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue