[object Object] Icon

Learn how to create, start, manage and modify Encodings

[object Object] Icon

Learn how to create, start, manage and modify Players

[object Object] Icon

Learn how to create, start, manage and modify Analyticss

Docs Home
User shortcuts for search
Focus by pressing f
Hide results by pressing Esc
Navigate via   keys

Thu Aug 30 2018

How to create combined Multi DRM protected content

OverviewLink Icon

The Bitmovin API and player allows you to use multiple DRMs in parallel. This means that you encode, encrypt and package your content once and you can playback with several different DRMs, such as Widevine, PlayReady, PrimeTime, etc. This is especially important if you want to increase your device reach.

Due to fragmentation in the market it is not possible to reach all major devices with just one DRM. Therefore, you need to use multiple in parallel, which is possible as all DRM systems use AES for encryption. If you use the same key in the different DRM systems for the same video you just need to add additional metadata for each DRM to this video and then it can be played back by with DRM systems. In detail it’s a little bit more complex as this needs additional logic on the encoding as well as on the player side, but Bitmovin provides you with solutions for both.

What you also need for such a setup is a 3rd party multi DRM provider such as Irdeto, EZDRM, ExpressPlay, Axinom, etc. It’s also possible to create your own licensing backend if you have a contract with Google (Widevine), Microsoft (PlayReady), Adobe (PrimeTime) or Apple (Fairplay) directly and you implement the specification.

Encoding ConfigurationLink Icon

This tutorial is based on this full example, which is available on Github and is using our Bitmovin PHP API client, however we do offer API clients in other languages as well. If you haven't created any encodings with our API clients yet, we recommend you to read the getting started guide called "Create an Encoding with our API" first, before you continue.

Lets start with the preparation of required information we need in order to protect your content using Playready DRM. This values will be provided by your multi DRM licensing server provider such as Irdeto, EZDRM, ExpressPlay, Axinom, etc.

1$cencDrmKey = "0123456789abcdef0123456789abcdef";
2$cencDrmKid = "0123456789abcdef0123456789abcdef";
3$widevinePssh = "widevine-pssh-key-in-base64";
4$playreadyLaUrl = "https://example.com/playready-la-url";

The parameters of the configuration have the following meaning:

-key: This is the common content encryption key -kid: This is the common unique identifier for your content key in hex format -widevinePssh: This is the value for the Widevine pssh box -playreadyLaUrl: This is the URL to the PlayReady license server

We will use this information to create a CENC DRM resource, which will be created for each fMP4 Muxing you want to be encrypted and protected with Widevine and PlayReady DRM. Further we have to provide a output location, where those encrypted segments should be stored at. Therefore, we don't provide the output location with the fMP4 Muxing, but with the CENC DRM resource instead.

1$fmp4Muxing1080p = createFmp4Muxing($apiClient, $encoding, $videoStream1080p, null, null);
2$audioFmp4Muxing128 = createFmp4Muxing($apiClient, $encoding, $audioStream128, null, null);
4$cencDrmEncodingOutput1080p = createEncodingOutput($s3Output, $outputPath . 'video/1080p/dash/drm/');
5$cencDrm1080p = createCencDrm($cencDrmKey, $cencDrmKid, array($cencDrmEncodingOutput1080p), $widevinePssh, $playreadyLaUrl);
6$videoFmp4Drm1080p = $apiClient->encodings()->muxings($encoding)->fmp4Muxing()->drm($fmp4Muxing1080p)->cencDrm()->create($cencDrm1080p);
8$audioCencDrmEncodingOutput128 = createEncodingOutput($s3Output, $outputPath . 'audio/128kbps/dash/drm/');
9$audioCencDrm128 = createCencDrm($cencDrmKey, $cencDrmKid, array($audioCencDrmEncodingOutput128), $widevinePssh, $playreadyLaUrl);
10$audioFmp4Drm128 = $apiClient->encodings()->muxings($encoding)->fmp4Muxing()->drm($audioFmp4Muxing128)->cencDrm()->create($audioCencDrm128);

Hint: If you would provide a output location for the muxing as well, our API would store unencrypted segments to the given output location as well.

Give us feedback