HLS with Transport Streams (TS)

USP supports adding AES encryption. The encryption is applied on-the-fly, so there is no preprocessing involved.

The options for enabling encryptions are stored in the server manifest file.

For HLS AES encryption a CEK (Content Encryption Key) and a license acquisition URL (the location where the player retrieves the key) are needed.

Demo streams can be found in the Unified Streaming Demo.

Note

For HLS TS Output TransDRM is required when working with pre-encrypted content. If using CPIX you will need to use the --decrypt_cpix option alongside the --cpix option when creating your manifest

Adding AES-128 Encryption

Next is creating a server manifest file with enabled encryption. You need to provide the following options:

--hls.key

The key id (KID) and content encryption key (CEK) are passed with the --hls.key option where KID and CEK are separated by a colon, e.g. --hls.key=KID:CEK

As no KID is used for AES-128, this can be left empty. The CEK is a (random) 128 bit value and must be coded in hex (base16).

--hls.license_server_url

The URL used by the player to retrieve the key.

Content Key

You can use openssl for generating a random key:

#!/bin/bash

openssl rand 16 > video.key

The file video.key holds the encryption key that will be requested by the player. If openssl returns "unable to write 'random state'", remove ~/.rnd then try once more.

Example

The following command creates a server manifest file with the key information embedded:

#!/bin/bash

mp4split -o video.ism \
  --hls.key=:`cat video.key | hexdump -e '16/1 "%02x"'` \
  --hls.license_server_url=https://license-server/video.key \
  video.ismv

The generated server manifest file (video.ism) now holds the key information. When a client requests a .m3u8 playlist the webserver module will automatically insert the proper #EXT-X-KEY tag and requests for the MPEG-TS fragments are encrypted on-the-fly.

An example .m3u8 playlist:

#EXTM3U
#EXT-X-VERSION:1
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="https://license-server/video.key"
#EXTINF:4, no desc
video-audio=65000-video=236000-0.ts

The following command creates a server manifest file with the key information embedded:

#!/bin/bash

mp4split -o video.ism \
   --hls.key=:000102030405060708090a0b0c0d0e0f \
   --hls.license_server_url=https://www.example.com/oceans.key \
   video.ismv

Download

Please download the hls-with-aes.sh sample script which creates the various server manifest as discussed above. The sample content is Tears of Steel.

Adding SAMPLE-AES Encryption

For SAMPLE-AES encryption the setup is similar. Please note that this is for on-the-fly encryption. For file based encryption see Packaging HTTP Live Streaming (HLS) with TS.

First we create a 128-bit CEK (Content Encryption Key) and optional 128-bit IV (Initialization Vector). These are just files with 16 random bytes. You could use for example 'openssl' to create the key.

#!/bin/bash

openssl rand 16 > content.key
openssl rand 16 > init_vector.key

The command-lines for creating the server manifest is similar to the above, except that we need to use different options.

--hls.key

The key id (KID) and content encryption key (CEK) are passed with the --hls.key option where KID and CEK are separated by a colon, e.g. --hls.key=KID:CEK

As no KID is used for AES-128, this can be left empty. The CEK is a (random) 128 bit value and must be coded in hex (base16).

--hls.key_iv

The initialization vector (automatically generated if missing).

--hls.license_server_url

The URL used by the player to retrieve the key.

--hls.playout

The string identifier 'sample_aes'.

Example

#!/bin/bash

CEK=`cat content.key | hexdump -e '16/1 "%02x"'`
KIV=`cat init_vector.key | hexdump -e '16/1 "%02x"'`

# URL that resolves to content.key
LA_URL=https://license-server/content.key

mp4split -o example.ism \
  --hls.key=:${CEK} \
  --hls.key_iv=${KIV} \
  --hls.license_server_url=${LA_URL} \
  --hls.playout=sample_aes \
  oceans-64k.ismv oceans-250k.ismv

Download

Please download the hls-with-sample-aes.sh sample script which creates the various server manifest as discussed above. The sample content is Tears of Steel.

Adding China DRM

New in version 1.7.19.

China DRM is specified with the --hls.key_format="chinadrm" option, where the appropriate signaling will be present in the media playlists.

Example

#!/bin/bash

CEK=CONTENT_ENCRYPTION_KEY_IN_HEX
IV=KEY_IV_IN_HEX
LA_URL=http://LICENSE_SERVER_URL

mp4split -o video.ism \
  --hls.key=:${CEK} \
  --hls.key_iv=${IV} \
  --hls.license_server_url=${LA_URL} \
  --hls.playout=aes \
  --hls.key_format="chinadrm" \
  video-500k.ismv video-750k.ismv video-1500k.ismv

Adding FairPlay DRM

New in version 1.7.2.

This is similar to the SAMPLE-AES described in the previous paragraph with two additional tags added to the EXT-X-KEY tag.

The KEYFORMAT is set to "com.apple.streamingkeydelivery" and the KEYFORMATVERSIONS is set to "1".

To enable the additional signaling, you have to change the --hls.playout option from 'sample_aes' to 'sample_aes_streamingkeydelivery'.

Note that, while sample_aes only requires an iOS device, the client application is required to be developed using Apple's FairPlay SDK for it to be able to work with sample_aes_streamingkeydelivery.

--hls.playout

The string identifier sample_aes_streamingkeydelivery.

Special care needs to be taken with the content_key/key_iv, this needs to 32 bytes.

It can be created like this:

#!/bin/bash

openssl rand 32 > presentation.key

Here content_key is the first 16 and key_iv the second 16. Pass these separately as --hls.key and --hls.key_iv.

Alternatively you can create two 16 byte values and cat them together in a single file.

The player will fetch it using the 'fairplay sdk'.

Note

Dolby Digital Plus, also known as Enhanced AC-3 or EC-3 audio streams are supported as well. See HLS Sample-AES Audio Formats for further reference.

Adding Marlin DRM

New in version 1.6.9.

USP supports adding Marlin protection to HLS presentations using AES. The options for enabling encrypted playout are stored in the server manifest file. For Marlin HLS AES encryption the KID and CEK are specified as Adding Marlin DRM. Additionally, Marlin playout allows a content id attribute to be specified as a CID query parameter of the license server URL.

Options for Marlin

You need to provide the following options:

--hls.playout=marlin

Enable Marlin AES encryption

--marlin.key

The KID and CEK are passed with the --marlin.key option where KID and CEK are separated by a colon, e.g. --marlin.key=KID:CEK

Note that both KID and CEK must be coded in hex (base16).

--marlin.license_server_url

The license server URL, where ?CID=... is stripped from the URL and instead passed as a separate attribute in #EXT-X-KEY

Example

The following command creates a server manifest file for HLS playout with AES Marlin DRM:

mp4split -o video.ism \
  --hls.playout=marlin \
  --marlin.key=b366360da82e9c6e0b0984002a362cf2:a0a1a2a3a4a5a6a7a8a9aaabacadaeaf \
  --marlin.license_server_url=urn:marlin-drm?CID=content1234 \
video.mp4

The generated .m3u8 playlists will contain a line like:

#EXT-X-KEY:METHOD=AES-128,URI="urn:marlin-drm",CID="content1234"

Clients and Playout

For playout you need a Marlin capable player, for instance Intertrust's Wasabi Marlin Client SDK for more information.

Adding Primetime DRM

There are two variants for Adobe Primetime with HLS, AES-128 and SAMPLE-AES. By default, AES-128 is used unless a different hls playout type is specified. The following example shows the preparation of a server manifest file for Adobe Primetime SAMPLE-AES.

#!/bin/bash

CEK=CONTENT_ENCRYPTION_KEY_IN_HEX
IV=KEY_IV_IN_HEX
LA_URL=http://LICENSE_SERVER_URL
DRM_DATA=BASE64_DRM_DATA

mp4split -o video.ism \
  --hls.key=:${CEK} \
  --hls.key_iv=${IV} \
  --hls.license_server_url=${LA_URL} \
  --hls.playout=faxs_sample_aes \
  --hls.inline_drm \
  --hds.drm_specific_data=${DRM_DATA} \
  video-500k.ismv video-750k.ismv video-1500k.ismv