devine-dl / devine

Modular Movie, TV, and Music Archival Software
GNU General Public License v3.0
367 stars 84 forks source link

Unable to decrypt HLS video with a unique AES key per segment #24

Closed rlaphoenix closed 1 year ago

rlaphoenix commented 1 year ago

Describe the bug For example, if we have the following file

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-TARGETDURATION:5
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="hls_2400_keyfile_0.key",IV=0x00000000000000000000000000000001
#EXTINF:5.000000,
hls_2400-00000.ts
#EXT-X-KEY:METHOD=AES-128,URI="hls_2400_keyfile_0.key",IV=0x00000000000000000000000000000002
#EXTINF:5.000000,
hls_2400-00001.ts
#EXT-X-KEY:METHOD=AES-128,URI="hls_2400_keyfile_0.key",IV=0x00000000000000000000000000000003
#EXTINF:5.000000,
hls_2400-00002.ts
#EXT-X-KEY:METHOD=AES-128,URI="hls_2400_keyfile_0.key",IV=0x00000000000000000000000000000004
#EXTINF:5.000000,
hls_2400-00003.ts
#EXT-X-KEY:METHOD=AES-128,URI="hls_2400_keyfile_0.key",IV=0x00000000000000000000000000000005

All the keys will be retrieved but only the first one will actually be used as each of them are added as DRM objects, which the DL code uses the first-available one to use as decryption. Therefore, it will only sucessfully decrypt the first segment, unless further segments use the same key and IV.

Expected behavior It should remember which segment uses which key. This is quite a problem though. The downloader code runs fully before the decrypter code. Therefore, by the time the download has finished, the decryptor has no information on which data is which segment, as they would have all been concatenated.

The only solution would be to move the decryptor code to run every time a segment is downloaded and link the DRM information to each segment. This would require a fair amount of development efforts and time as you would need to deal with both HLS and DASH, and both ClearKey and Widevine. You would also need to deal with reducing unnecessary calls (e.g., if the key file for a track was already downloaded, and is being reused).

Screenshots N/A

Additional context One of the main problems here would be linking a segment of video with DRM. And not all services use DASH or HLS in a way that is segmented. Some services give you the ability to download a singular file per track.

I should also mention that shaka-packager does not return any kind of warning or return code when this occurs. It simply processes what it can, and effectively skips the rest of the data, returning a small file than you would expect.

rlaphoenix commented 1 year ago

Fixed in https://github.com/rlaphoenix/devine/commit/42aaa03941754a3e5653674f865a1507562bae09