CENC and PIFF (Multi DRM)


When your content is stored protected on disk in 'PIFF' (Protected Interoperable File Format) format (E.g. it is fragmented-MP4 protected with PlayReady) the Origin converts it on-the-fly to DASH with Common Encryption (CENC). This allows for playout in both the Smooth Streaming format and DASH. (Please read about the background as well.)

Possible playouts using PIFF as ingest format include:

  • Silverlight (HTTP Smooth Streaming with PlayReady).

  • IE11 / Win8.1 (MPEG-DASH with PlayReady)

  • Chrome (MPEG-DASH with Widevine)

  • Android (MPEG-DASH with Marlin)

This setup is special since Unified Origin uses the encryption information stored in the server manifest file to synthesize the required "pssh" boxes for DASH playout.

Supporting multiple DRM systems is a feature of CENC and requires that the different DRM systems share a common KID (Key ID) and CEK (Content Encryption Key). You have to align the PlayReady license server and Widevine license server to make sure that they use the same KID:CEK combination.

There is no need to re-encode or repackage your existing catalog.

You may need to create or update the USP server manifest file, but only when it is missing the key information. If it has been created with a recent version then it is already present.

Protection System Specific Header box

If the content contains the signaling for PlayReady and/or Widevine (the "pssh" boxes) then they are used for signaling of the DRM systems.

The CENC signaling is added to all output formats it applies to (PlayReady, Widevine and Marlin).

When a "pssh" box is not present for a DRM system then the Origin synthesizes one just-in-time.


The "pssh" box for Widevine is synthesized according to the following rules:

  • The key_id field is set to the KID as specified in the "tenc" box.

  • The provider field is set to 'usp-cenc'.

  • The content_id field is copied from the key_id field (in base64).

  • The track_type is left empty.

  • The policy is left empty.


Marlin doesn't use a "pssh" box, and only uses the signaling in the MPD.


After creation of the server manifest, e.g.:


mp4split -o piff2cenc.ism \

playout of HSS with PlayReady is still possible as it would 'normally'. No further commandline triggers are needed, the player can fetch the /Manifest as it would normally.

Clear Content

When your content is 'clear' (not encrypted) it is still possible to synthesize the "pssh" box, provided you pass key_id, content_key (and optionally the license_server_url).


In this case you do not pass the drm_specific_data as mentioned under Adding Widevine Modular DRM (and thus cannot make use of track_type or policy).


Playready license server

MUST have CORS headers setup properly. Most notably it needs "soapaction" added to the Access-Control-Allow-Headers.


In order to have playout on Chrome, you have to make sure that the Media and Encryption extensions are enabled. You can see the flags when going to the URL chrome://flags/

  • Disable Media Source API: Disable

  • Enable Encrypted Media Extensions: Enable

  • Disable prefixed Encrypted Media Extensions: Disable

  • Media Source API uitschakelen: Uitschakelen

  • Gecodeerde Media-extensies inschakelen: Inschakelen

  • Vooraf gecodeerde media-extensies uitschakelen: Uitschakelen


CENC based content can also be used as source and then PIFF based content is created from it. For this the correct --brand use is important

Both brands "iso6" and "piff" need to be specified so the files:

  • have a "sidx" and "mfra" index.

  • have a "pssh" and "uuid" box.

  • have "saiz"/"saio"/"senc" and "uuid" box in the movie fragments.

  • the timescale for all tracks is set to 10MHz.

The following example creates a server manifest after packaging and encrypting and MP4 to MPEG-DASH content. This content then can be used with the origin to dynamically create HSS (Smooth) with PlayReady or MPEG-DASH with Widevine/PlayReady.



KID_UUID=10000000-1000-1000-1000-100000000001 #UUID representation of KID
CEK_B64="OiobaN0r2bLusl6ExHdmaA==" #Base64 byte array representation of CEK


MP4SPLIT=mp4split --license-key=/path/your-license.key #Add path to your license key


$MP4SPLIT -o oceans-64k-pr.mp4 \
  oceans-64k-250k.mp4 --track_type=audio --track_language=eng

$MP4SPLIT -o oceans-250k-pr.mp4 \
  oceans-64k-250k-pr.mp4 --track_type=video

$MP4SPLIT -o $NAME.ism \
  oceans-64k-pr.mp4 oceans-250k-pr.mp4

Multi DRM and Manifest Generation

Typically manifest are created and store keys in the manifest alongside the content. This is the most common case.

However, for security reasons or other it might not be feasible to store manifests locally. There are various options to work with manifests that are stored remotely or created dynamically. See for instance the Dynamic Manifests page:

1.7.25 and later scan all metadata so nothing extra is needed to stream HSS(Smooth)+PR or DASH+PR using dynamic manifests:

There are two approaches to achieve this, namely 1) using the proxy approach or 2) use different manifests / a manifest creation process.

The following example creates a client manifest with PR blob, without any DRM parameters in a manifest using the first method:


curl -v http://demo.unified-streaming.com/direct/demo.unified-streaming.com/video/tears-of-steel/tears-of-steel-pr.ismv/Manifest

The following example uses the second method:


curl -v http://demo.unified-streaming.com/ism2/CACHE_ID.ism/Manifest?url=http%3A%2F%2Fdemo.unified-streaming.com%2Fvideo%2Ftears-of-steel%2Ftears-of-steel-pr.ismv

But the SMIL generator must match the file, all tracks with track id. The following php file does that for the content referenced in the example: smil2.php

The apache config required for this is the following:

<Directory "/var/www/usp/ism2">
  IsmProxyPass http://demo.unified-streaming.com/smil2.php/