Streaming DRM protected content with Bitmovin Player Web SDK

As DRM (Digital Rights Management) protected content is often crucial for certain streaming infrastructures, this tutorial aims to help you get started with Bitmovin Player Web SDK DRM setup.

Briefly about DRM

In a nutshell, DRM systems provide the ability to control how people can consume your content while securing it against piracy using various encryption schemes. As the topic itself is quite complex we will not cover the details of how it works as part of this tutorial, but if you are completely new to the topic of DRM and you want to learn more you can visit our dedicated article - What is DRM and How Does it Work. More advanced resources can also be found in the What's next section below.

All the DRM solutions mentioned in this tutorial are self sufficient systems that can be used independently of one another.

As the device portfolio that needs to be covered for streaming across the user base is very diverse in terms of DRM systems support, it leads to a need to use a so called Common Encryption Schema (CENC). This approach allows different DRM systems to decrypt commonly encrypted content to save the infrastructure costs. This means that Multi-DRM content packaging output supports more DRM systems, so more devices can be covered.

Example of CENC present in MPEG-DASH mpd manifest file

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

This tutorial focuses on DRM systems that are most commonly used across the OTT industry. We will cover examples for Widevine (Google), PlayReady (Microsoft) and FairPlay (Apple) systems and we will also mention the ClearKey encryption system as a free security alternative. You can check the complete support list in our Bitmovin Player DRM support page.

Multi-DRM example

This approach is the simplest way to setup DRM playback with Bitmovin Player to cover most devices. The DRMConfig object in the Bitmovin Player Web SDK API is used to configure the DRM details required for successful playback. This DRMConfig object is part of the SourceConfig object that gets passed to the player.load method.

Considering the stream has Multi-DRM output for Playready and Widevine, all you need to do is to add drm property to the SourceConfig object and add one property for each DRM system, containing its DRM system-specific configuration object.

The most important property to add is the license acqusition URL LA_URL, which specifies the URI to the DRM license server. Note that each DRM system configuration can differ and license servers may require additional configuration. We will try to cover some cases in other examples but full configuration options are available in our API docs.

var config = {
  key: '<YOUR PLAYER KEY>',
  cast: {
    enable: true
  }
};

var source = {
  dash: 'https://bitmovin-a.akamaihd.net/content/art-of-motion_drm/mpds/11331.mpd',
  hls: 'https://bitmovin-a.akamaihd.net/content/art-of-motion_drm/m3u8s/11331.m3u8',
  smooth: 'https://test.playready.microsoft.com/smoothstreaming/SSWSS720H264/SuperSpeedway_720.ism/manifest',
  drm: {
    widevine: {
      LA_URL: 'https://widevine-proxy.appspot.com/proxy'
    },
    playready: {
      LA_URL: 'https://playready.directtaps.net/pr/svc/rightsmanager.asmx?PlayRight=1&ContentKey=EAtsIJQPd5pFiRUrV9Layw=='
    }
  }
};

var player = new bitmovin.player.Player(document.getElementById('player'), config);

player.load(source);

You can run this example or test your own stream on our DRM Demo Page

Widevine

The Bitmovin Player supports Widevine system through Encrypted Media Extensions. This DRM system is available on platforms like Chrome, Firefox, MSEdge (Chromium Based), Smart TVs (LG WebOS, Samsung Tizen) and more.

Widevine is usually very easy to setup for playback using a license server URL configured via LA_URL property using the WidevineModularDRMConfig interface. The license server URL can be also defined inside of the stream manifest, but player will prefer the one defined in the DRMConfig if it is present.

Audio and video Robustness

Through the configuration it is possible to define the robustness, or security level of the DRM key system. If a string specifies a higher security level than the system is able to support playback will fail. Setting of the required security level is configurable using videoRobustness and audioRobustness properties which can have specific string value. This configuration also helps to get rid of the warning thrown by Chrome regarding the robustness.

// SourceConfig object to be passed to Bitmovin Player instance
var source = {
  dash: 'https://bitmovin-a.akamaihd.net/content/art-of-motion_drm/mpds/11331.mpd',
  drm: {
    widevine: {
      LA_URL: 'https://widevine-proxy.appspot.com/proxy',
      audioRobustness : 'HW_SECURE_DECODE',
      videoRobustness : 'HW_SECURE_DECODE',
    },
  },
};

Preparing license message

In some workflows it may be required to prepare the license acquisition message which will be sent to the license acquisition server. As many DRM providers expect different, vendor-specific message, this can be done using the prepareMessage property to which a function should be assigned. The parameter passed to the function is the key message event object as given by the Widevine Content Decryption Module (CDM). Also the prepareLicense option can be used for custom widevine servers where the response is not just the license itself, but instead the license is e.g. wrapped in an JSON object.

// SourceConfig object to be passed to Bitmovin Player instance
var source = {
  dash: 'https://bitmovin-a.akamaihd.net/content/art-of-motion_drm/mpds/11331.mpd',
  drm: {
    widevine: {
      LA_URL: 'https://widevine-proxy.appspot.com/proxy',
        prepareMessage : (keyMessage) => {
          return keyMessage.message;
        },
      },
    },
  },
};

The Bitmovin Player Web SDK also covers more advanced configuration options for Widevine which are described in the Widevine API docs.

PlayReady

The PlayReady DRM system is supported by most of the Microsoft platforms like Xbox, Internet Explorer, MS Edge on Windows 10+, and also Android TV and some Smart TVs, so its support is almost as widespread as Widevine. It is usually configured simply by providing the license server URL through the LA_URL property, similar to the way the Widevine is configured, but it can also have the license server URL present directly inside of the stream manifest or even the DRM system-specific data ("PSSH boxes") of the stream segments. Specific configurations may also be required to make PlayReady work with some platforms like Smart TVs (Samsung Tizen, LG WebOS).

Plaintext challenge

Specifies, whether the Challenge specified in the keymessage is provided in plaintext rather than being Base64 encoded. On most desktop browsers, the Challenge is Base64 encoded, which requires additional preprocessing before a license request can be sent. Devices like smart TVs or set-top boxes often already provide a plaintext challenge in the key message, so the preprocessing step can be skipped. Default value is false.

UTF-8 message

Specifies whether the keymessage provided by the browser is already UTF-8 encoded. On most desktop browsers, the keymessage is UTF-16 encoded, which requires additional preprocessing before a license request can be sent. Devices like smart TVs or set-top boxes often already provide a UTF-8 encoded key messages, so the preprocessing step can be skipped. The default value is false.

// SourceConfig object to be passed to Bitmovin Player instance
var source = {
  dash: 'https://bitmovin-a.akamaihd.net/content/art-of-motion_drm/mpds/11331.mpd',
  drm: {
    playready: {
      LA_URL: 'https://playready.directtaps.net/pr/svc/rightsmanager.asmx?PlayRight=1&ContentKey=EAtsIJQPd5pFiRUrV9Layw==',
      utf8message: true,
      plaintextChallenge: true,
      headers: { 'Content-Type': 'text/xml' },    
    }
  },
};

Bitmovin Player also covers more advanced configuration options for PlayReady which are described in the PlayReady system API docs.

FairPlay

The FairPlay DRM system is the only DRM system that Apple platforms support, so it is often required to enable streaming of content on these devices. As it is an Apple proprietary system it is usually packed with HLS protocol and Bitmovin Player supports it with Safari native player.

To make FairPlay work some additional configuration apart from license server URL is required. Usually it is certificateURL or directly serverCertificate as ArrayBuffer that needs to get passed all along with a specific content ID. The prepareContentId callback can be used to prepare the value of the content ID, and the prepareMessage callback can be used to append the contentID to the message sent with the license request.

FairPlay configuration example with DRM Today provider

// SourceConfig object to be passed to Bitmovin Player instance
var source = {
  hls: 'https://hls-manifest-url'
  fairplay: {
    LA_URL: 'https://license-server-url-provided-by-drmtoday',
    certificateURL: 'https://certificate-url-provided-by-drmtoday',
    headers: {
      'dt-custom-data': 'INSERT-YOUR-BASE64-ENCODED-CUSTOMDATA',
    },
    prepareMessage : (event, session) => {
      return 'spc=' + encodeURIComponent(event.messageBase64Encoded) + '&' + session.contentId;
    },
    prepareContentId : (contentId) => {
      const pattern='skd://drmtoday?';
      let parameters;
      let idx = contentId.indexOf(pattern);

      if (idx > -1) {
        parameters = contentId.substring(idx + pattern.length);
        parameters = parameters.replace(/assetid/gi, 'assetId');
        parameters = parameters.replace(/variantid/gi, 'variantId');
        return parameters;
      } else {
        return '';
      }
    }
  }
};

More examples of FairPlay implementations are present in our API docs. Also more details about FairPlay setup can be found in the DRM Today tutorial.

License request handling

The license request is common to all DRM systems, and is initiated by the Bitmovin Player in order to aquire the license from the provided license server. The licence is then passed into the EME API so the stream can be decrypted and played back by the device. The license request must use HTTPS and is often required to have some header configuration. Also it is worth mentioning that the web application needs to be hosted on HTTPS (or localhost for testing) in order for DRM to be made available by browsers.

If the infrastructure requires such a setup it is possile to use the headers property on the specific DRM system present in DRMConfig to add the apropriate HttpHeaders to the license requests. In addition the withCredentials property can also be configured. This will ensure that credentials such as cookies or authorization headers are sent along with the license requests.

Example Of Headers Setup

// SourceConfig object to be passed to Bitmovin Player instance
var source = {
  dash: 'https://bitmovin-a.akamaihd.net/content/art-of-motion_drm/mpds/11331.mpd',
  hls: 'https://bitmovin-a.akamaihd.net/content/art-of-motion_drm/m3u8s/11331.m3u8',
  smooth: 'https://test.playready.microsoft.com/smoothstreaming/SSWSS720H264/SuperSpeedway_720.ism/manifest',
  drm: {
    widevine: {
      LA_URL: 'https://widevine-proxy.appspot.com/proxy',
      headers: {
        'custom-header': 'INSERT-VALUE'
      },
      withCredentials: true,
    },
    playready: {
      LA_URL: 'https://playready.directtaps.net/pr/svc/rightsmanager.asmx?PlayRight=1&ContentKey=EAtsIJQPd5pFiRUrV9Layw==',
      headers: {
        'custom-header': 'INSERT-VALUE'
      },
      withCredentials: true,
    }
  }
};

Using Bitmovin Player network API

It is also possible to use the network API to intercept the license requests or responses using preprocessHttpRequest or preprocessHttpResponse properties on the network configuration.

// Bitmovin Player configuration object
var config = {
  key: '<YOUR PLAYER KEY>',
  network: {
    preprocessHttpRequest: function(type, request) {
      if (type === bitmovin.player.HttpRequestType.DRM_LICENSE_WIDEVINE) {
        // withCredentials = true
        request.credentials = 'include';
        // custom headers
        request.headers['custom-header'] = 'INSERT-VALUE';
      }
      return Promise.resolve(request);
    }
  }
};

ClearKey - free alternative

MPEG-CENC ClearKey is implemented as part of the Media Source Extensions (MSE) and Encrypted Media Extension (EME), which enable playback of protected content in web browsers. These content protection technologies protect the actual content themselves, scrambling the video with the AES-128 algorithm in either the CTR mode for DASH or the CBC mode for HLS.

The first notable advantage is that encrypted content is unviewable without access to the decryption keys. Implementing an encryption does not carry any additional costs beyond its implementation. ClearKey handling is required by the specification within EME support for all browsers, but it could be seen primarily as a reference mechanism, rather than a commercial grade security solution.

var config = {
  key: "YOUR-PLAYER-LICENSE-KEY-HERE",
};

var source = {
  dash: "https://example.com/path/to/your/clear-key/content/manifest.mpd",
  drm: {
    clearkey: [{
      key: 'YOUR-KEY-HERE',
      kid: 'YOUR-KID-HERE' //optional
    }]
  },
};

var player = new bitmovin.player.Player(document.getElementById('player'), config);

player.load(source);

ClearKey Security Considerations

Although this approach is a handy and free alternative it is also necesery to point out some security risks that come with it. With DRM systems the content is decrypted inside of CDM which is securely encapsulated inside of the system.

Although it is possible to decrypt content via CDM using the ClearKey, the Bitmovin Player Web SDK decrypts the content in the browser and it ends up unencrypted within the JavaScript scope. Also the decryption key is available in clear format in the JavaScript scope, contrary to other DRM systems where the decryption key is within an encrypted license and never available to the JavaScript application or any insecure part of the system.

For this reason there may be a room for attacks where the unencrypted content could be ripped or the keys could be stolen to decrypt the content elsewhere. Therefore this approach is not suitable to e.g. secure proprietary content.

Smart TV specifics

The DRM playback configuration for Smart TVs works pretty much the same way as in web browsers from the API perspective, but on certain plaforms some special handling is required to make the playback work conrectly. Bitmovin Player abstracts this logic into specific modules which are not part of the full bundle distribution and need to be added at load time.

In the case of LG WebOS, the WebOS module is required. More detailed information can be found in the LG WebOS tutorial. For Samsung Tizen there is a specific setup required which is also described in a separate Samsung Tizen tutorial.

What's next

DRM Related Articles

API Documentaiton

Testing Resources

Github Examples