MPEG-DASH

USP supports Common Encryption for MPEG-DASH. Supported DRMs are

  • Adobe Primetime
  • Marlin
  • Playready
  • Widevine
  • Latens

The encryption is applied on-the-fly, so there is no preprocessing involved. The options for enabling encryption are stored in the server manifest file.

Demo streams can be found in the Unified Streaming Demo.

Common Encryption (CENC)

The Common Encryption Scheme (CENC) specifies standard encryption and key mapping methods that can be utilized by one or more digital rights and key management systems (DRM systems) to enable decryption of the same file using different DRM systems. The scheme operates by defining a common format for the encryption related metadata necessary to decrypt the protected streams, yet leaves the details of rights mappings, key acquisition and storage, DRM compliance rules, etc. up to the DRM system or systems supporting the 'cenc' scheme.

Options for CENC

--mpd.inline_drm

Signals to put the encryption headers in both the client manifest (the .mpd file requested by DASH players) and the initialization segment.

More concretely, the client manifest will have the following additional information:

<!-- PlayReady -->
<ContentProtection
  schemeIdUri="urn:uuid:9A04F079-9840-4286-AB92-E65BE0885F95"
  value="MSPR 2.0">
  <cenc:pssh>BASE64_PSSH</cenc:pssh>
  <mspr:IsEncrypted>1</mspr:IsEncrypted>
  <mspr:IV_Size>8</mspr:IV_Size>
  <mspr:kid>BASE64_KID</mspr:kid>
  <mspr:pro>BASE64_DATA</mspr:pro>
</ContentProtection>
<!-- Widevine -->
<ContentProtection
  schemeIdUri="urn:uuid:EDEF8BA9-79D6-4ACE-A3C8-27DCD51D21ED">
  <cenc:pssh>BASE64_PSSH</cenc:pssh>
</ContentProtection>

Example

#!/bin/bash

KID=key-id-in-hex
CEK=content-key-in-hex
WV_PSSH=BASE64_PSSH_BOX

mp4split --package-mpd \
  -o tears-of-steel-400k-dash.mp4 \
  --widevine.key=${KID}:${CEK} \
  --widevine.drm_specific_data=${WV_PSSH} \
  tears-of-steel-400k.mpd

mp4split --package-mpd \
  --mpd.inline_drm \
  -o tears-of-steel-400k.mpd \
  tears-of-steel-400k-dash.mp4

The first step creates an MPEG-DASH compliant file from the input mp4. The second step creates the MPD with the encryption headers in the MPD as well.

Multi DRM

The CENC IBC demo features simultaneous PlayReady and Verimatrix encryption from the same MPEG-DASH url to both Android and iOS players,

The CENC scheme specifies standard encryption and key mapping methods that can be utilized by one or more digital rights management (DRM) and key management systems to enable decryption of the same file using different DRM systems. Such an approach supports a broader range of accessible clients from a single content stream.

The scheme operates by defining a common format for the encryption related metadata necessary to decrypt the protected streams, yet leaves the details of rights mappings, key acquisition and storage, DRM compliance rules, etc. up to the DRM system or systems supporting CENC, enabling multi-DRM protection for adaptive streaming.

Attention

For multi DRM to work with different key providers (Widevine and PlayReady for example), the same key id and content key must be used with all the key providers, e.g the Widevine content key and key id must be the same as the PlayReady content key and key id.

Example

#!/bin/bash

KID=key-id-in-hex
CEK=content-key-in-hex

PLAYREADY_LA_URL=the-playready-url
WV_PSSH=BASE64_PSSH_BOX

mp4split -o test.ism \
  --iss.key=${KID}:${CEK} \
  --iss.license_server_url=$(PLAYREADY_LA_URL) \
  --widevine.key=${KID}:${CEK} \
  --widevine.drm_specific_data=${WV_PSSH} \
  test.ismv

The above command line will the provide for the following in the .mpd generated:

<!-- Common Encryption -->
<ContentProtection
  schemeIdUri="urn:mpeg:dash:mp4protection:2011"
  value="cenc"
  cenc:default_KID="8D1A585A-A0B4-A942-917A-C1B659142B2A">
</ContentProtection>
<!-- PlayReady -->
<ContentProtection
  schemeIdUri="urn:uuid:9A04F079-9840-4286-AB92-E65BE0885F95">
</ContentProtection>
<!-- Widevine -->
<ContentProtection
  schemeIdUri="urn:uuid:EDEF8BA9-79D6-4ACE-A3C8-27DCD51D21ED">
</ContentProtection>
<!-- Marlin -->
<ContentProtection
  schemeIdUri="urn:uuid:5E629AF5-38DA-4063-8977-97FFBD9902D4">
...

CENC signalling

In order for multi DRM to work all CENC DRMs need to be signalled so the player can select the DRM it supports.

For instance, when PlayReady is used both Widevine and Marlin are signalled as well.

Signalling Widevine and synthesizing the "pssh" box from Playready encrypted source content is what makes PIFF to CENC (Multi DRM) work.

However, there are other use cases as well:

  • non CENC multi DRM
  • Widevine, Playready or Marlin only (non conforming players)
  • a specific order in the DRM signalling (non conforming players)

If you are not using PIFF to CENC (Multi DRM) but you do require multiple DRMs then you would need to provide the individual DRM options on the command line; following the documentation of the various DRMs (outlined in Unified Origin - DRM).

Please note that if you use only Widevine, both Widevine and Marlin will be signalled. Similarly, if you use only Marlin, both Marlin and Widevine will be signalled.

If you require only one DRM or a specific order it is possible to rewrite or filter the manifest to the order you would like using mod_substitute for Apache or Nginx's nginx_substitutions_filter. Alternatively, Lua can be used as embedded scripting language with both webservers for more control.

Adobe Primetime DRM

New in version 1.7.18.

Options for Primetime

The options for enabling encryption are stored in the server manifest file. For Primetime DASH encryption a content encryption key (CEK) and key id (KID) are required. You need to provide the following options:

--hds.key

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

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

--hds.drm_specific_data

The drm specific data used for Primetime DRM, in the case of MPEG-DASH this will be used for the "pssh" box. Please refer to the Adobe documentation on how to obtain this. Can either be a Base64 string or a file with the decoded Base64 data. The file name must include a '.'

Example

#!/bin/bash

KID=000102030405060708090a0b0c0d0e0f
CEK=000102030405060708090a0b0c0d0e0f

mp4spit -o video.ism \
  --hds.key=$(KID):$(CEK) \
  --hds.drm_specific_data=pssh.bin \
  video.ismv

Marlin DRM

Marlin is a DRM platform, created by an open-standards community initiative called the Marlin Developer Community (MDC). The MDC was formed in 2005 by five companies: Intertrust, Panasonic, Philips, Samsung and Sony.

USP supports adding Marlin protection to MPEG DASH presentations (and HLS).

The encryption is applied on-the-fly, so there is no preprocessing involved. Please note that offline Marlin packaging is not supported.

Options for Marlin

The options for enabling encryption are stored in the server manifest file. For Marlin DASH encryption a content encryption key (CEK) and key id (KID) are required. You need to provide the following options:

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

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

--marlin.license_server_url

The license server URL

Example

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

mp4split -o video.ism \
  --marlin.key=b366360da82e9c6e0b0984002a362cf2:a0a1a2a3a4a5a6a7a8a9aaabacadaeaf
  video.ismv

PlayReady DRM

Please refer to PlayReady DRM.

Widevine Modular DRM

For Widevine Modular DRM a content encryption key (CEK) and a key id (KID) are required.

Options for Widevine

You need to provide the following options:

--widevine.key

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

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

--widevine.license_server_url

The license server URL.

--widevine.drm_specific_data

The DRM specific data provided by the license server (the Widevine PSSH data).

Can either be a Base64 string or a file with the decoded Base64 data. The file name must include a '.'

Note that the LA_URL (license acquisition URL) is not signaled in the "pssh" box and is often hard-coded in a DASH player supporting Winevine Modular itself. The recommended setting is to use the correct URL.

Example

The following script demonstrates how to call into the license server to obtain content_key, key_id, license_acquisition_url and pssh data to create a server manifest which can then be used to fetch the DASH client manifest from (the .mpd):

#!/bin/bash

la_url=http://license.uat.widevine.com/cenc/getcontentkey/widevine_test

wvr=`curl -v -X POST \
      -H 'Content-Type: application/json' \
      -d '{"request": "ewogICJjb250ZW50X2lkIjogIlptdHFNMnhxWVZOa1ptRnNhM0l6YWc9PSIsCiAgInRyYWNrcyI6I FsKICAgIHsgInR5cGUiOiAiU0QiIH0sCiAgICB7ICJ0eXBlIjogIkhEIiB9LAogICAgeyAidHlwZSI 6ICJBVURJTyIgfQogIF0sCiAgImRybV90eXBlcyI6IFsgIldJREVWSU5FIiBdLAogICJwb2xpY3kiO iAiIgp9Cg==", "signature": "kwVLL4xVh9mnlZlPqiEWN0E+FsvG0y+/oy451XXeIMo=", "signer": "widevine_test" }' \
      $la_url`

dwvr=$(echo $wvr | python -c 'import json,sys,base64;obj=json.load(sys.stdin);print base64.b64decode(obj["response"])')

key_id=$(echo $dwvr | python -c 'import json,sys;obj=json.load(sys.stdin);print obj["tracks"][0]["key_id"]')
content_key=$(echo $dwvr | python -c 'import json,sys;obj=json.load(sys.stdin);print obj["tracks"][0]["key"]')
pssh=$(echo $dwvr | python -c 'import json,sys;obj=json.load(sys.stdin);print obj["tracks"][0]["pssh"][0]["data"]')

# Widevine API returns base64 so re-encode to base16
kid16=$(echo $key_id | base64 -d | hexdump -e '16/1 "%02x"')
cek16=$(echo $content_key | base64 -d | hexdump -e '16/1 "%02x"')

MP4SPLIT_OPTIONS=
MP4SPLIT_OPTIONS+=" --widevine.key=${kid16}:${cek16}"
MP4SPLIT_OPTIONS+=" --widevine.license_server_url=${la_url}"
MP4SPLIT_OPTIONS+=" --widevine.drm_specific_data=${pssh}"

mp4split -o tos-wv.ism ${MP4SPLIT_OPTIONS} tears-of-steel-1.ismv tears-of-steel-64k.isma

Note

Tool sets or programming languages other than bash/python may equally be used.

Clients and Playout

For a demo and the player checklist (IE11 and Chrome), see the piff-to-cenc Playback section.

Irdeto Protection System

New in version 1.7.18.

Options for IrdetoProtection

The options for enabling encryption are stored in the server manifest file. For IrdetoProtection DASH encryption a key id (KID), content encryption key (CEK) and key iv (IV) are required. You need to provide the following options:

--irdeto_cenc.key

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

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

--irdeto_cenc.key_iv

A key iv can be specified by passing the option --irdeto_cenc.key_iv=IV

The key iv must similarly be coded in hex (base16)

--irdeto_cenc.drm_specific_data

The drm specific data used for IrdetoProtection DRM, in the case of MPEG-DASH this will be used for the "pssh" box. Can either be a Base64 string or a file with the decoded Base64 data. The file name must include a '.'

Example

#!/bin/bash

KID=000102030405060708090a0b0c0d0e0f
CEK=000102030405060708090a0b0c0d0e0f
IV=000102030405060708090a0b0c0d0e0f

mp4spit -o video.ism \
  --irdeto_cenc.key=$(KID):$(CEK) \
  --irdeto_cenc.key_iv=$(IV) \
  --irdeto_cenc.drm_specific_data=pssh.bin \
  video.ismv

Latens DRM for DASH

New in version 1.7.19.

Options for Latens DRM

The options for enabling encryption are stored in the server manifest file. For Latens encryption a content encryption key (CEK) and key id (KID) are required. You need to provide the following options:

--latens.key

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

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

--latens.drm_specific_data

The DRM specific data. This is the full "pssh" box. Please refer to the Titanium CENC Key Server Interface Specification on how to obtain this. Can either be a Base64 string or a file with the decoded Base64 data. The file name must include a '.'

Example

#!/bin/bash

KID=000102030405060708090a0b0c0d0e0f
CEK=000102030405060708090a0b0c0d0e0f

mp4spit -o video.ism \
  --latens.key=$(KID):$(CEK) \
  --latens.drm_specific_data=pssh.bin \
  video.ismv