shaka-project / shaka-packager

A media packaging and development framework for VOD and Live DASH and HLS applications, supporting Common Encryption for Widevine and other DRM Systems.
https://shaka-project.github.io/shaka-packager/
Other
2.01k stars 511 forks source link

How to implement plain AES-128 encryption while packaging for HLS? #776

Open sbbullet opened 4 years ago

sbbullet commented 4 years ago

System Info

Operating System: Ubuntu 20.04 packager Version: v2.3.0-5bf8ad5-release

How to implement plain AES-128 encryption in HLS? I didn't find it in the documentation and other issues.

What is the expected result? Plain AES-128 encryption to be implemented so that players like shaka and videoJS will play them without any configuration. AES-128 encryption of HLS like that done by Bento4 is expected.

I just want to encrypt my HLS stream using plain AES-128 encryption and provide a URL to access the key but I can't actually find how to implement that using shaka-packager. Please point me in the right direction @kqyang . Thank you in advance.

kqyang commented 4 years ago

@sbbullet Certainly.

Here are the changes needed. Let us know if you have questions.

sbbullet commented 4 years ago

Thank you @kqyang for your support. I will try propagating these changes as per your suggestion but I don't think I will be able to make it work since I am just a beginner to encryption and really don't know much about how to modify open-source projects but I will try my best.

I am curious whether it will output plain SAMPLE-AES encrypted content just using the current options. If yes, could you please tell me which options to use? At the core, I just need to implement plain encryption; be it AES-128 or SAMPLE-AES, and must be playable in firefox, chrome, and iOS safari clients by just providing URL for fetching decryption key in the hsl_key_uri option with some authorization involved and no extra setup for the player.

kqyang commented 4 years ago

I am curious whether it will output plain SAMPLE-AES encrypted content just using the current options. If yes, could you please tell me which options to use?

You can follow the examples here: https://google.github.io/shaka-packager/html/tutorials/raw_key.html#using-raw-key, specifically "Example with FairPlay using ‘cbcs’ protection scheme", but skip the "protection_systems".

sbbullet commented 4 years ago

Hello @kqyang , I followed the tutorial and did package the content as well but the content can't be played. The key URL is being hit and the response is received as well. The response is base64 encoded value of key provided in the packager option.

The packager command I used is as:

packager \
  'in={$this->videoFolder}/input720.mp4,stream=audio,segment_template={$this->videoFolder}/segmented/audio/\$Number\$.aac,playlist_name={$this->video->slug}/segmented/audio/audio_main.m3u8,hls_group_id=audio' \
  'in={$this->videoFolder}/input360.mp4,stream=video,segment_template={$this->videoFolder}/segmented/video/360p_\$Number\$.ts,playlist_name={$this->video->slug}/segmented/video/360p_main.m3u8,iframe_playlist_name={$this->video->slug}/segmented/video/360p_iframe.m3u8' \
  'in={$this->videoFolder}/input540.mp4,stream=video,segment_template={$this->videoFolder}/segmented/video/540p_\$Number\$.ts,playlist_name={$this->video->slug}/segmented/video/540p_main.m3u8,iframe_playlist_name={$this->video->slug}/segmented/video/540p_iframe.m3u8' \
  'in={$this->videoFolder}/input720.mp4,stream=video,segment_template={$this->videoFolder}/segmented/video/720p_\$Number\$.ts,playlist_name={$this->video->slug}/segmented/video/720p_main.m3u8,iframe_playlist_name={$this->video->slug}/segmented/video/720p_iframe.m3u8' \
  --segment_duration 4 \
  --fragment_duration 4 \
  --protection_scheme cbcs \
  --enable_raw_key_encryption \
  --keys label=:key_id=c67a47172d17c1deb95c29a52912d3c8:key=fa3fe0aff6fd7997cde83936f072325c \
  --iv 11223344556677889900112233445566 \
  --hls_key_uri http://localhost:3000/api/get-key \
  --hls_master_playlist_output \"{$this->mpdPath}/{$this->video->slug}.m3u8\"

When the hls_key_uri is requested the response we get back is the base64 encoded key value. image

EXT-X-KEY:METHOD=SAMPLE-AES,URI="http://localhost:3000/api/get-key",IV=0x11223344556677889900112233445566,KEYFORMAT="identity"

I am using latest videojs player. I checked with shaka player too and found that the issue of not being able to play keyformat 'identity' has still not being fixed.

The video is not being played even after all this. Please help me if you have any idea what I am doing wrong. I would be happy if you provide me an invitation link to your slack channel so that we can communicate more efficiently there.

kqyang commented 4 years ago

When the hls_key_uri is requested the response we get back is the base64 encoded key value

Please return a raw key instead of base64 encoded key.

sbbullet commented 4 years ago

I tried as you said but no luck. 6seconds played because shaka-packager default has clear lead set to 6s. Just look at this image I attached. I used the same key and key_id. The manifest looks like this. Looks like I am not the only one who wants to see the AES-128 encryption being implemented in shaka-packager. A lot of people will benefit from this implementation. It's a great package, no doubt but the basic implementation of AES-128 encryption not being there makes it a little bit less than a legendary packager. I hope you will understand.

The dashif website also has mentioned you as one of the best packagers available. Also, I think we don't need key_id for AES-128 and SAMPLE-AES plain encryption. I don't it might be ignored if provided (when you implement AES-128).

We appreciate what you are doing and hope to see this feature implemented soon. Thank you.

#EXTM3U
#EXT-X-VERSION:6
## Generated with https://github.com/google/shaka-packager version v2.3.0-5bf8ad5-release
#EXT-X-TARGETDURATION:5
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:4.000,
720p_1.ts
#EXTINF:4.000,
720p_2.ts
#EXT-X-DISCONTINUITY
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="http://127.0.0.1:8000/get-key",IV=0x11223344556677889900112233445566,KEYFORMAT="identity"

image

kqyang commented 4 years ago

@sbbullet What your service return is still not the raw bytes. It is returning the hex representation.

As an example, you can try set "--keys label=:key_id=30313233343536373839303132333435:key=30313233343536373839303132333435" in packager and return "0123456789012345" in http://localhost:3000/api/get-key.

sbbullet commented 4 years ago

No luck again. The packaged files are uploaded here

#EXTM3U
#EXT-X-VERSION:6
## Generated with https://github.com/google/shaka-packager version v2.3.0-5bf8ad5-release
#EXT-X-TARGETDURATION:5
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:4.000,
720p_1.ts
#EXTINF:4.000,
720p_2.ts
#EXT-X-DISCONTINUITY
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="http://127.0.0.1:8000/get-key",IV=0x11223344556677889900112233445566,KEYFORMAT="identity"

Pacakger Command

                                          --segment_duration 4 \
                                          --fragment_duration 4 \
                                          --protection_scheme cbcs \
                                          --enable_raw_key_encryption \
                                          --keys label=:key_id=30313233343536373839303132333435:key=30313233343536373839303132333435 \
                                          --iv 11223344556677889900112233445566 \
                                          --hls_key_uri http://127.0.0.1:8000/get-key \

image

kqyang commented 4 years ago

Can you remove --hls_key_uri http://localhost:3000/api/get-key during packaging and test it again? Let's rule out the player and site factor first.

sbbullet commented 4 years ago

Can you remove --hls_key_uri http://localhost:3000/api/get-key during packaging and test it again? Let's rule out the player and site factor first.

Yep, I will try it asap and get back to you with results.

sbbullet commented 4 years ago

Hey @kqyang, I tried as you told and still no luck.

Packager params

                                          --segment_duration 4 \
                                          --fragment_duration 4 \
                                          --protection_scheme cbcs \
                                          --enable_raw_key_encryption \
                                          --keys label=:key_id=30313233343536373839303132333435:key=30313233343536373839303132333435 \
                                          --iv 11223344556677889900112233445566 \
                                          --hls_master_playlist_output \"{$this->mpdPath}/{$this->video->slug}.m3u8\"

Manifest

#EXTM3U
#EXT-X-VERSION:6
## Generated with https://github.com/google/shaka-packager version v2.3.0-5bf8ad5-release
#EXT-X-TARGETDURATION:5
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:4.000,
720p_1.ts
#EXTINF:4.000,
720p_2.ts
#EXT-X-DISCONTINUITY
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="data:text/plain;base64,MDEyMzQ1Njc4OTAxMjM0NQ==",IV=0x11223344556677889900112233445566,KEYFORMAT="identity"

Screenshot image

kqyang commented 4 years ago

What problem are you seeing? Also, can you test it in Safari?

I think we have internal tests covering that and it is working for us.

sbbullet commented 4 years ago

What problem are you seeing? Also, can you test it in Safari?

I think we have internal tests covering that and it is working for us.

It gets stalled after 6 seconds (clear lead is set to 6s by default). Unfortunately, I don't have an iPhone or Mac to test it in Safari. Please test it with the latest videoJS. Shaka Player doesn't' support keyformat=identity in HLS. I am using these CDNs for latest videoJS.

Also, can you please tell me what players are you using to play those files?

  <link href="//vjs.zencdn.net/7.8.2/video-js.min.css" rel="stylesheet">
  <script src="//vjs.zencdn.net/7.8.2/video.min.js"></script>
kqyang commented 4 years ago

Can you remove the clear lead during packaging (--clear_lead=0) and try again? videoJS may not have implemented clear lead support properly. Also, please capture the error messages.

sbbullet commented 4 years ago

Okay. I will try it asap and get back to you.

sbbullet commented 4 years ago

Hello @kqyang , tried it with (--clear-lead 0) but still no luck. It would be much helpful for us if you guys work on implementing AES-128 encryption as well. Pretty much all packagers have that feature but aren't as great as shaka packager in terms of customization. Your small effort will help a lot of people including me who can't afford DRM for encryption. I hope you will understand.

The packaged files are uploaded here

image

kqyang commented 4 years ago

@astinus-1 Can you try if it works: https://github.com/google/shaka-packager/issues/776#issuecomment-637000618?

sbbullet commented 4 years ago

Hey @kqyang, I'm just curious if we have any slack channel. I found that we have a Google group but that's pretty much passive. I hope you will take the initiative of creating a slack group or an active group so that we people can have active communication. Let's make this world a better place together.

kqyang commented 4 years ago

No, we don't have a slack channel. Let's keep all the conversations on GitHub which is better overall.

sbbullet commented 4 years ago

That's totally fine. Thank you @kqyang

sbbullet commented 4 years ago

Hey @kqyang, are we planning to work on this very soon, or have we started working on this? Please, update me whenever you feel necessary. Thank you in advance.

berkant commented 4 years ago

Can we still not encrypt a whole segment, so it appears exactly like a binary blob like ffmpeg does?

sbbullet commented 4 years ago

Hello @kqyang , I just would like to know if we will be able to see this feature anytime soon? If so how much time would it take you guys to release this feature? I would be happy to know if you could just tell me what's being on your side. Thanks in advance.

kqyang commented 4 years ago

No. We do not have plan to work on it. That being said, we welcome external contributions. See https://github.com/google/shaka-packager/issues/776#issuecomment-635808873.

lys1737 commented 4 years ago

ffmpeg can encrypt a whole segment on HLS+TS and play well in exo-player, but it isn't to support to get a drm licence like widevine. I think is not important for shaka-packager to implement AES-128 without drm.

ffmpeg -y -i h264_main_720p_3000.ts -codec copy -bsf h264_mp4toannexb \
 -hls_time 6 -hls_playlist_type vod \
 -hls_key_info_file enckey.keyinfo \
 -hls_segment_filename "h264_main_720p_3000_%d.ts" \
 h264_test.m3u8
Chokoabigail commented 1 year ago

Hi @joeyparrish , sorry for pumping this old issue up. Does shaka-packager currently support fmp4 AES-128 encryption?

joeyparrish commented 3 months ago

Still not supported, still open to PRs for this. Some details above in comments from KQ.