axiomatic-systems / Bento4

Full-featured MP4 format, MPEG DASH, HLS, CMAF SDK and tools
http://www.bento4.com
1.93k stars 478 forks source link

Support for HLS fmp4 clear key AES-128 #234

Open awakenedguy opened 6 years ago

awakenedguy commented 6 years ago

Is this scenario supported by mp4dash?

barbibulle commented 6 years ago

I'm not sure what you mean by 'HLS with clear-key'. Clear-key is a way to provide a "no-drm" key delivery method for MPEG DASH. With HLS, the equivalent is to just put the URL of the key in the HLS playlist, pointing to a file with the key. With mp4dash with the --hls option, there are several ways to specify what key references you want to add. The simplest is with the --hls-key-url option, where you can pass the URL to your key. The other key URL options are for use with fairplay and/or widevine, but those are URIs/named that are specific for those DRM systems, not pointers to 'clear' keys. Have you tried the --hls-key-url option?

awakenedguy commented 6 years ago

Right, I meant simply HLS encrypted with AES-128 where URL of the key is simply in the playlist. It is simple to do with mp4hls for MPEG-TS, but I don't know how to do the same for fMP4.

The docs doesn't mention that at all, same for mp4dash command line options, it is nowhere to be found. I tried everything I could, and concluded that the scenario is probably unsupported, which seems strange, since all complex DRM's, as well as SAMPLE-AES are supported :)

I tried to simply add --hls-key-url key.bin option (launched with pre-generated correct 16 bytes key.bin by my script), as you suggested, despite the fact that it obviously has already that value by default, and it does nothing, the output is unencrypted. I guess that I normally have to specify the encryption scheme in order for packager to encrypt the content. What I want is content entirely encrypted with AES-128 CBC, so it (normally) corresponds to cbc1.

But when I add --encryption-key=${keyIdHex}:${keyHex}:${ivHex}, it says the following:

ERROR: --hls requires --encryption-cenc-scheme=cbcs

That makes me believe that SAMPLE-AES is supported for HLS fMP4, but AES-128 is apparently not.

So I ended up doing it myself in my script - parse all output subfolders with unencrypted HLS fMP4 content, generate a random key and iv for each stream, call openssl aes-128-cbc -e -in $file -out $output -nosalt -iv $iv -K $key independently for each of thousands chunks, parse and modify playlist files to include the missing line #EXT-X-KEY:METHOD=AES-128,URI="key.bin",IV=0x... right after #EXT-X-MAP:URI="init.mp4" and write key.bin files to each respective subfolder. That is exactly what I tried to make packager do, but failed.

The encryption is pretty slow that way, but it works, and the content plays fine as intended. Though if your packager actually supports this simple scenario, then I'll just use it, since it would probably encrypt way faster than call openssl 10000 times :)

P.S.: it is for PoC, not for actual production, where URL to the keys would obviously be different :)

awakenedguy commented 6 years ago

Though the most important scenario for me is HLS fmp4 single-file AES-128. I can't encrypt it myself with openssl and get a playable renditions, normally the packager simply rejects to package a pre-encrypted content. Is this scenario supported? If yes, how precisely it could be done with mp4dash?

maytham553 commented 2 months ago

is there any solve now ?