HLS with Widevine for Android
As of the version of 2.6.0, ExoPlayer started supporting Widevine + HLS playback. WideVine is the one of the DRM schemes defined by Google. There are other schemes like FairPlay by Apple, PlayReady by Microsoft too.
The image shown below is how Widevine contents are delivered and played on a device. A key is stored on a license server, and the player gets the key from a license server to play. As you see in the picture, player has to have a Widevine CDM embedded on the device to decrypt the content.
Widevine for Android
To play Widevine contents on ExoPlayer, the Android OS needs to be API level +19 for cenc mode, +25 for cbcs mode.
protection scheme
You might have wondered what are cenc mode
and cbcs mode
. Those are about how contents are encrypted and there are actually four types of protection scheme.
- cenc mode: AES-CTR mode and Sub-Sample encryption
- cbc1 mode: AES-CBC mode and Sub-Sample encryption
- cens mode: AES-CTR mode and Sub-Sample + patterned encryption
- cbcs mode: AES-CBC mode and Sub-Sample + patterned encryption
CTR and CBC are AES encryption mode and Full-Sample encryption means video samples are all encrypted with the specified AES mode, on the other hand Sub-Sample encryption encrypts the partial of each sample. It seems like ExoPlayer only support cenc mode
and cbcs mode
for now.
HLS Playlist
The easiest way to create a content of HLS +fMp4 + Widevine is to use shaka-packager. I wrote a post about making Widevine contents, so please check it out if you are interested.
Anyways, a HLS playlist created for a Widevine content would be like this below.
video/init.mp4
is an initialization file for the initialization, it would be used to keep track of the position of the media files, and also contains information about the track.
video/1.mp4
, video/2.mp4
, video/3.mp4
… are video files, but you might have noticed that EXT-X-KEY
is in between video/1.mp4
and video/2.mp4
. The reason why video/1.mp4
is before EXT-X-KEY
is because video/1.mp4
is not encrypted and video files after that are all encrypted with Widevine. Media segments are encrypted with sample-AES, so it is possible not to encrypt all the content, and the first content may or may not be encrypted.
Let’s look at the EXT-X-KEY
tag which shows how the segments are encrypted.
METHOD
: This indicates the encryption method. For a Widevine content, it would be SAMPLE-AES-CTR
, which means cenc mode, or SAMPLE-AES
, which is cbcs mode.
KEYFORMATVERSION
: This defines key format version, and the value would be 1.
KEYID
: This is a default key identifier that uniquely identifies the key to decrypt samples.
KEYFORMAT
: This describes the UUID for Widevine, which is known as SystemID. Each DRM scheme has their own UUID, and for Widevine the value would be edef8ba9–79d6–4ace-a3c8–27dcd51d21ed. If you are interested in what others are, this site would be helpful for you
URI
: This is a base64 encoded PSSH box. PSSH box is the one of the boxes defined for mp4 file, and the initialization file like init.mp4 has the same information as well.
I hope this could help someone try to play widevine contents on Android.
thanks.
References
Widevine DRM for HLS: https://storage.googleapis.com/wvdocs/Widevine_DRM_HLS.pdf
Getting Started with Widevine DRM: https://storage.googleapis.com/wvdocs/Widevine_DRM_Getting_Started.pdf
Common Encryption API for Widevine DRM: https://storage.googleapis.com/wvdocs/Widevine_DRM_Encryption_API.pdf