HTTP Live Streaming (HLS)

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) is needed.

Demo streams can be found in the Unified Streaming Demo.

AES-128

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=http://www.example.com/video/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="http://www.example.com/video/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.

SAMPLE-AES

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

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"'`

mp4split -o example.ism \
  --hls.key=:${CEK} \
  --hls.key_iv=${KIV} \
  --hls.license_server_url=http://example.com/content.key \
  --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.

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.

Adobe 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
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=${URL} \
  --hls.playout=faxs_sample_aes \
  --hls.inline_drm \
  --hds.drm_specific_data=${DRM_DATA} \
  video-500k.ismv video-800k.ismv video-1500k.ismv

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 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.

Conax PlayReady

New in version 1.7.1.

This option supports adding PlayReady to HLS using Conax.

The webserver adds protection to the HLS audio and video streams on-the-fly with Conax PlayReady HLS.

USP provides the following options for Conax PlayReady HLS protection:

--conax.key

The 128 bits Key ID (KID) and 128 bits Content Encryption Key (CEK) are passed with the --conax.key option where KID and CEK are separated by a colon, e.g. --conax.key=KID:CEK

Both KID and CEK must be coded in hex (base16).

Note

The KID from a PlayReady License server may be formatted as a little-endian GUID. In that case you have to change the endianess as we always use a big-endian UUID representation of the KID.

--conax.key_iv

Specifies the initialization vector (64 bits).

--conax.license_server_url

A string returned by the Conax API in the format: conax:drm_id:BASE64_ENCODED_INFO

--hls.playout

Set to 'conax' to enable HLS + Conax PlayReady

The following example creates a VOD server manifest with MP4Split and will embed the key information in the server manifest.

Example for generating a server manifest with Conax Playready DRM:

mp4split -o conax.ism  \
  --conax.key=7C9AA2B68306466F882D75BED922CD25:27eb4cef2afa2afe8fe5d2c374cd60e
  --conax.license_server_url="conax:drm_id:base64_encoded_info:NOTE:returned_from_Conax_API"  \
  --hls.playout=conax
video.ismv

Once you generate server manifest file, as seen in the example above, all the key information is embedded in the server manifest.

When a client requests an .m3u8 playlist the webserver module will automatically insert the proper tags and requests for the MPEG-TS fragments are encrypted on-the-fly.

An example .m3u8 playlist:

#EXTM3U
#EXT-X-VERSION:2
## Created with Unified Streaming Platform(version=1.7.2)
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-ALLOW-CACHE:NO
#EXT-X-TARGETDURATION:5
#EXT-X-KEY:METHOD=AES-128-CX,URI="conax:drm_id:base64_encoded_info:NOTE:returned_from_API",IV=0x97F92BAE7D8510A10000000100000000
#USP-X-TIMESTAMP-MAP:MPEGTS=900000,LOCAL=00:00:00.000
#EXTINF:4, no desc
conax-audio=65000-video=236000-1.ts

Viaccess-Orca (Discretix) PlayReady

This option supports PlayReady HLS using Viaccess-Orca (Discretix).

The webserver adds protection to the HLS audio and video streams on-the-fly with Discretix PlayReady HLS.

USP provides the following options for Viaccess-Orca (Discretix) PlayReady HLS protection:

--dxdrm.key

The 128 bits Key ID (KID) and 128 bits Content Encryption Key (CEK) are passed with the --dxdrm.key option where KID and CEK are separated by a colon, e.g. --dxdrm.key=KID:CEK

Both KID and CEK must be coded in hex (base16).

Note

The KID from a PlayReady License server may be formatted as a little-endian GUID. In that case you have to change the endianess as we always use a big-endian UUID representation of the KID.

--dxdrm.key_iv

Specifies the initialization vector (64 bits).

--dxdrm.license_server_url

The URL of the license server(s) used.

The following example creates a VOD server manifest with MP4Split and will embed the key information in the server manifest.

Example for generating a server manifest with Discretix Playready DRM:

mp4split -o discretix.ism  \
  --dxdrm.key=7C9AA2B68306466F882D75BED922CD25:27eb4cef2afa2afe8fe5d2c374cd60e
  --dxdrm.license_server_url="http://playready.directtaps.net/pr/svc/rightsmanager.asmx?PlayRight=1&UseSimpleNonPersistentLicense=1"  \
video.ismv

Once you generate server manifest file, as seen in the example above, all the key information is embedded in the server manifest.

When a client requests an .m3u8 playlist the webserver module will automatically insert the proper tag (#EXT-X-DXDRMINFO:KEYREF) and requests for the MPEG-TS fragments are encrypted on-the-fly.

An example .m3u8 playlist:

#EXTM3U
#EXT-X-VERSION:1
#EXT-X-DXDRM:VERSION=3.0,MECHANISM=PLAYREADY
#EXT-X-DXDRMINFO:KEYREF="x-keyref://playready?KID=tqKafAaDb0aILXW+2SLNJQ==",
HEADER="PABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgB0AHEASwBhAGYAQQBhAEQAYgAwAGEASQBMAFgAVwArADIAUwBMAE4ASgBRAD0APQA8AC8ASwBJAEQAPgA8AEMASABFAEMASwBTAFUATQA+AGEAUABSAEsAaABjAEwAcQBxAGEAQQA9ADwALwBDAEgARQBDAEsAUwBVAE0APgA8AEwAQQBfAFUAUgBMAD4AaAB0AHQAcAA6AC8ALwBwAGwAYQB5AHIAZQBhAGQAeQAuAGQAaQByAGUAYwB0AHQAYQBwAHMALgBuAGUAdAAvAHAAcgAvAHMAdgBjAC8AcgBpAGcAaAB0AHMAbQBhAG4AYQBnAGUAcgAuAGEAcwBtAHgAPwBQAGwAYQB5AFIAaQBnAGgAdAA9ADEAJgBhAG0AcAA7AFUAcwBlAFMAaQBtAHAAbABlAE4AbwBuAFAAZQByA   HMAaQBzAHQAZQBuAHQATABpAGMAZQBuAHMAZQA9ADEAPAAvAEwAQQBfAFUAUgBM AD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA="
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=319060,CODECS="mp4a.40.2,avc1.66.30",RESOLUTION=304x128
dxdrm-audio=65000-video=236000.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=68900,CODECS="mp4a.40.2"
dxdrm-audio=65000.m3u8

Irdeto PlayReady

Follow the link for how to use Irdeto PlayReady for HLS.

PlayReady Envelope

New in version 1.6.9.

USP supports adding 'Playready Envelope' (PRE) encryption to presentations played out to for instance the Inside Secure player. 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 PlayReady Envelope encryption a KID:CEK and a license acquisition URL is needed.

--iss.key

The 128 bits Key ID (KID) and 128 bits Content Encryption Key (CEK) are passed with the --iss.key option where KID and CEK are separated by a colon, e.g. --iss.key=KID:CEK

Both KID and CEK must be coded in base16 (hex).

Note

The KID from a PlayReady License server may be formatted as a little-endian GUID. In that case you have to change the endianess as we always use a big-endian UUID representation of the KID.

--iss.license_server_url

The URL of the license server used.

--hls.playout

The string 'playready_envelope' indicating PRE.

Example

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

#!/bin/bash

KID=7C9AA2B68306466F882D75BED922CD25
CEK=827eb4cef2afa2afe8fe5d2c374cd60e
LA_URL="http://playready.directtaps.net/pr/svc/rightsmanager.asmx?PlayRight=1&UseSimpleNonPersistentLicense=1"

MP4SPLIT_OPTIONS=
MP4SPLIT_OPTIONS+=" --iss.key=${KID}:${CEK}"
MP4SPLIT_OPTIONS+=" --iss.license_server_url=${LA_URL}"
MP4SPLIT_OPTIONS+=" --hls.playout=playready_envelope"

mp4split -o video.ism ${MP4SPLIT_OPTIONS} video.ismv

Server Manifest and Playlist

The generated server manifest file (video.ism) now holds the key information. When a client requests an .m3u8 playlist the webserver module will provide it. Please note that with PRE no signalling is to be found in the m3u8. Requests for the MPEG-TS fragments are encrypted on-the-fly (and will contain the signalling).