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.
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 Full-Sample encryption
- cbc1 mode: AES-CBC mode and Full-Sample encryption
- cens mode: AES-CTR mode and Sub-Sample encryption
- cbcs mode: AES-CBC mode and Sub-Sample 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.
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/3.mp4 … are video files, but you might have noticed that
EXT-X-KEY is in between
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.
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