Configuring the Brightcove Player for DRM

Product(s)
Video Cloud
Brightcove Player
Role(s)
Player Developer
Task(s)
Protect Videos
Topic(s)
DRM

In this topic, you will learn how Brightcove Player implements digital rights management (DRM). The document first shows how to implement the DRM plugin, then is followed by details of the plugin and how it is implemented.

Brightcove is embracing the following technologies to deliver DRM protected content to the widest possible variety of browsers and devices:

  • MPEG-DASH with Native/EME supported CENC DRMs
  • HLS with FairPlay

To use DRM with Brightcove Player you must:

  • Produce DRM enabled content
  • Enable Brightcove Player to use the DRM plugin
  • In some cases, configure the DRM plugin to use your license server

Terminology

Review these key terms used in this document.

Term Definition
DRM From Wikipedia: Digital rights management (DRM) is a class of copy protection technologies that are used by hardware and software manufacturers, publishers, copyright holders, and individuals with the intent to control the use of digital content and devices after sale.
MPEG-DASH From Wikipedia: Dynamic Adaptive Streaming over HTTP (DASH), also known as MPEG-DASH, is an adaptive bitrate streaming technique that enables high quality streaming of media content over the Internet delivered from conventional HTTP web servers. Similar to Apple's HTTP Live Streaming (HLS) solution, MPEG-DASH works by breaking the content into a sequence of small HTTP-based file segments, each segment containing a short interval of playback time of a content that is potentially many hours in duration, such as a movie or the live broadcast of a sports event.
CENC From the ISO standard: The 'CENC' Common Encryption Scheme 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.
Encrypted Media Extensions (EME) From Wikipedia: EME is a W3C draft specification for providing a communication channel between web browsers and digital rights management (DRM) agent software. This allows the use of HTML5 video to play back DRM-wrapped content without the need for third-party media plugins, like Microsoft Silverlight.

Implement using Players module

To implement the DRM Plugin in Studio, and enable DRM based on your account setup, follow these steps:

  1. Open the PLAYERS module and either create a new player or locate the player to which you wish to add DRM functionality.
  2. Click the link for the player to open the player's properties.
  3. Click Playback in the left navigation menu.
  4. Next, check the Enable DRM checkbox.
    DRM checkbox in Studio
  5. To publish the player, click Publish & Embed > Publish Changes.
  6. To close the open dialog, click Close.

DRM plugin architecture

The DRM plugin (videojs-drm) is a wrapper around two plugins:

  • videojs-silverlight
  • videojs-contrib-eme

The videojs-drm plugin version 5 uses the player's built-in DASH playback capabilities. This utilizes VHS, which is the next and renamed version of the built-in videojs-contrib-hls plugin.

As of player 6.26.0 the player supports DASH multiperiod. For earlier versions of the player, the Shaka player is required for DASH multiperiod.

If you want to use the Shaka Player for DASH playback, like it did in version 4, you can include the following script along with videojs-drm version 5 script:

https://players.brightcove.net/videojs-shaka/1/videojs-shaka.js
 

The videojs-silverlight plugin allows for playback of DASH content on certain Internet Explorer browsers.

The videojs-contrib-eme plugin allows for playback of FairPlay HLS content.

Playback technologies used

Brightcove Player utilizes different DRM playback technologies with different browsers. The following details the DRM technologies used with Brightcove Player:

  • FairPlay: Apple's DRM system
  • PlayReady: Microsoft's DRM system
  • Widevine: Google's DRM system

The following table details the relationship between the browser (latest version), format and playback technology used in Brightcove Player:

Browser Format Playback Technology Rendition Type Used
to Deliver DRM Content
Chrome Desktop DASH with Widevine Native/EME MPEG-DASH
Chrome Mobile1 DASH with Widevine Native/EME MPEG-DASH
Internet Explorer2 DASH with PlayReady Silverlight MPEG-DASH
Edge DASH with PlayReady Native/EME MPEG-DASH
Safari HLS with FairPlay Native HLS HLS
Firefox DASH with Widevine Native/EME MPEG-DASH

1DRM playback using Chrome Mobile on iOS is not supported.

2IE11 on Windows 10 and 8.1, and IE11 on Win8 Metro, use Native/EME. All other IE versions and configurations use the Silverlight plugin.

Produce DRM content

There are two steps you must perform to create DRM enabled content:

  1. Contact your account manager to have your account(s) DRM-enabled. You can then configure your account with the proper licensing keys and ingest profiles to enable the creation of DRM protected content.
  2. Produce DRM protected content. You can choose to either upload new content or re-encode existing content as DRM. This is done by selecting the Ingest Profile that produces your desired encryption technology.

You will need to produce DRM protected content which uses either MPEG-DASH manifests with segmented and encrypted videos, or HLS FairPlay content.

Implementing FairPlay playback in code

If you wish to implement FairPlay playback using the in-page embed code you must follow these steps to use the DRM plugin:

  1. In the header of your HTML page, include the plugin's stylesheet:
    <link href="https://players.brightcove.net/videojs-drm/5/videojs-drm.css" rel="stylesheet">
    
    
  2. Include the plugin's JavaScript:
    <script src="https://players.brightcove.net/videojs-drm/5/videojs-drm.min.js"></script>
  3. If your account is set up for Dynamic Delivery, simply call the EME plugin to initialize it.

    <script type="text/javascript">
      videojs.getPlayer('myPlayerID').ready(function() {
        var myPlayer = this;
        myPlayer.eme();
    });
    </script>

     

    If your account is NOT set up for Dynamic Delivery, then you need to call and configure the EME plugin with FairPlay credential information.

    videojs.getPlayer('myPlayerID').ready(function() {
      var myPlayer = this;
      myPlayer.eme({
        "applicationId": "YOUR_APPLICATION_ID",
        "publisherId": "YOUR_PUBISHER_ID"
      });
    });
    </script>

Follow these steps to use the DRM Plugin with FairPlay protected content:

  1. In the header of your HTML page, include the plugin's stylesheet:
    <link href="https://players.brightcove.net/videojs-drm/5/videojs-drm.css" rel="stylesheet">
  2. Include the plugin's JavaScript:
    <script src="https://players.brightcove.net/videojs-drm/5/videojs-drm.min.js"></script>
  3. In a JavaScript block in the page, call and configure the EME plugin with FairPlay credential information by providing getCertificate, getContentId and getLicense functions to the EME plugin. These functions are specific to your own FairPlay license server implementation, and may be passed directly to the EME plugin before a src is set:
    <script type="text/javascript">
      videojs.getPlayer('myPlayerID').ready(function() {
        var myPlayer = this;
        myPlayer.eme({
          keySystems: {
            'com.apple.fps.1_0': {
            getCertificate: function (emeOptions, callback) {
            // request certificate
            // if err, callback(err)
            // if success, callback(null, certificate) where certificate
            // is a Uint8Array
          },
          getContentId: function (emeOptions, initData) {
            // return content ID as a string
            },
            getLicense: function (emeOptions, contentId, keyMessage, callback) {
              // request key
              // if err, callback(err)
              // if success, callback(null, key) as an arraybuffer
            }
          }
        }
      });
    </script>

Note that the FairPlay information can also be passed as part of each src object. The emeOptions are provided as a parameter to all functions. They are a reference to plugin options merged with (overwritten by) the source options of the current source. It is available to make it easier to access options so that you don't have to maintain them yourself.

player.src({
  type: 'application/vnd.apple.mpegurl',
  src: 'http://www.example.com/path/to/master.m3u8',
  keySystems: {
    "com.apple.fps.1_0": {
      getCertificate: function(emeOptions, callback) { ... },
      getContentId: function(emeOptions, initData) { ... },
      getLicense: function(emeOptions, contentId, keyMessage, callback) { ... }
    }
  }
});

For example, if you need to use an applicationId and publisherId for the getCertificate request, you can pass in plugin options this way:

{
  keySystems: {
    "com.apple.fps.1_0": {
      getCertificate: function(emeOptions, callback) {
      var applicationId = emeOptions.applicationId; // 'application-id'
      var publisherId = emeOptions.publisherId; // 'publisher-id'
      // ...
    }
      // ...
    }
  },
  applicationId: 'application-id'
  publisherId: 'publisher-id'
}

Or, if you need a source-specific publisherId you can overwrite it via the source options:

// plugin options
{
  keySystems: {
    "com.apple.fps.1_0": {
    getCertificate: function(emeOptions, callback) {
    var applicationId = emeOptions.applicationId; // 'application-id'
    var publisherId = emeOptions.publisherId; // 'source-specific-publisher-id'
    // ...
  },
    // ...
  }
},
applicationId: 'application-id'
publisherId: 'publisher-id'
}
// source options
player.src({
  src: '<URL>',
  type: 'application/vnd.apple.mpegurl',
  publisherId: 'source-specific-publisher-id'
});

The following is an example implementation, passing the options in as src options, retrieving the content ID from the hostname, fixed license and certificate URIs, and a license URI that requires a POST with a body of the key message:

var uint8ArrayToString = function(array) {
return String.fromCharCode.apply(null, new Uint16Array(array.buffer));
};
var getHostnameFromUri = function(uri) {
  var link = document.createElement('a');
  link.href = uri;
  return link.hostname;
};
var getCertificate = function(emeOptions, callback) {
  videojs.xhr({
    uri: emeOptions.certificateUri,
    responseType: 'arraybuffer'
    }, function(err, response, responseBody) {
    if (err) {
      callback(err);
      return;
    }
    callback(null, new Uint8Array(responseBody));
  });
};
var getContentId = function(emeOptions, initData) {
  return getHostnameFromUri(uint8ArrayToString(initData));
};
var getLicense = function(emeOptions, contentId, keyMessage, callback) {
  videojs.xhr({
    uri: emeOptions.licenseUri,
    method: 'POST',
    responseType: 'arraybuffer',
    body: keyMessage,
    headers: {
      'Content-type': 'application/octet-stream'
    }
    }, function(err, response, responseBody) {
    if (err) {
      callback(err);
      return;
    }
    callback(null, responseBody);
  });
};
player.src({
  type: 'application/vnd.apple.mpegurl',
  src: 'http://www.example.com/path/to/master.m3u8',
  keySystems: {
    "com.apple.fps.1_0": {
    getCertificate: getCertificate,
    getContentId: getContentId,
    getLicense: getLicense
  }
  },
  certificateUri: 'http://example.com/fairplay/certificate/endpoint',
  licenseUri: 'http://example.com/fairplay/license/endpoint'
});

Implementing Widevine playback in code

If you wish to implement Widevine playback using the in-page embed code you must follow these steps to use the DRM plugin:

  1. In the header of your HTML page, include the plugin's stylesheet:
    <link href="https://players.brightcove.net/videojs-drm/5/videojs-drm.css" rel="stylesheet">
  2. Include the plugin's JavaScript:
    <script src="https://players.brightcove.net/videojs-drm/5/videojs-drm.min.js"></script>
  3. Next, simply call the EME plugin to initialize it.
    <script type="text/javascript">
      videojs.getPlayer('myPlayerID').ready(function() {
        var myPlayer = this;
        myPlayer.eme();
      });
    </script>

For Widevine Modular content, you need to configure your player to use your Widevine licensing server using the player's source handler.

To update an instance of a player on your web page, you can use the player's source handler. Here is an example of using the keySystemsOptions array with the player.src() function:

player.src({
  src: 'http://example.com/my/manifest.mpd',
  type: 'application/dash+xml',
  keySystemOptions: [
  {
    name: 'com.widevine.alpha',
    options: {
    licenseUrl: 'http://m.widevine.com/proxy'
  }
  }]
});

You can also use the updateSourceData function as follows:

videojs.Html5DashJS.updateSourceData = function(source) {
source.keySystemOptions = [{
name: 'com.widevine.alpha',
options: {
serverURL:'https://example.com/anotherlicense'
}
}];
return source;
};

For more details, see the videojs-contrib-dash information on GitHub.

Supporting other DRM providers

The plugin has implemented a path that allows customers to implement support for other DRM providers. This is mostly useful for Fairplay, as Fairplay requires custom logic necessary to get license information. Adding a vendor.name to keySystems on a given source will attempt to utilize this logic, and include the necessary certificate and license information. An example for Azure follows:

player.ready(function(){
  player.eme();
  player.src({
  src: 'http://example.com/src-url.m3u8'
  type: '',
  keySystems: {
    'com.apple.fps.1_0': {
    vendor: {
    name: 'azure'
  },
  certificateUri: 'https://example.com/your-certificate-uri.cer',
  licenseUri: 'https://example.com/your-license-uri'
  }
  }
  });
});

Here is an example for castLabs:

var player = videojs.getPlayer('myPlayerID');
player.ready(function(){
  player.eme();
  player.src({
    src: 'http://example.com/src-url.m3u8'
    type: '',
    keySystems: {
      'com.apple.fps.1_0': {
      vendor: {
      name: 'castlabs',
      options: {
      authToken: 'your-auth-token',
      customData: 'your-custom-data'
    }
    }
    certificateUri: 'https://example.com/your-certificate-uri.cer',
    licenseUri: 'https://example.com/your-license-uri'
    }
    }
  });
});

This example loads Widevine and PlayReady sources:

player.src({
  type: 'application/dash+xml',
  src: '<some src>',
     keySystems: {
  'com.widevine.alpha': '<license url>',
  'com.microsofth.playready': '<license url>'
  }
});

Enable debugging

To enable debugging for your DRM DASH content, add the following shaka scripts to your Brightcove Player:

<!-- Script for the drm plugin -->
<script src="https://players.brightcove.net/videojs-drm/5/videojs-drm.min.js"></script>
<!-- Script for the shaka plugin -->
<script src="https://players.brightcove.net/videojs-shaka/1/videojs-shaka.js"></script>
<!-- Script for shaka debug plugin  -->
<script src="https://players.brightcove.net/videojs-shaka/1/videojs-shaka.debug.js"></script>

The following is an example of the debugging at player load:

Debugging in console at startup

The following is an example of the debugging after the video has begun to play:

Debugging in console after playing

DASH-IF

The Brightcove Player supports DASH Industry Forum (DASH-IF) assets, passing through Brightcove data to Native/EME. See http://dashif.org for more information on DASH-IF, and http://dashif.org/reference/players/javascript/latest/samples/dash-if-reference-player/app/sources.json for examples of the additional data required to playback DASH-IF test assets.

Known issues

  • DRM assets and Chrome: When using the Standard (iframe) player implementation with the DRM plugin, allow="encrypted-media" is required to be able to play DRM assets in Chrome.
    <iframe src="https://players.brightcove.net/123456789/BydO6uuuu_default/index.html?videoId=5783262319001"
    allowfullscreen
    webkitallowfullscreen
    mozallowfullscreen
    width="640" height="360"
    allow="encrypted-media"></iframe>
  • Special event for Silverlight/IE11: In most cases if you wish to programmatically interact with the player you would wait for either the ready or loadedmetadata  event to be dispatched. However, if you wish to programmatically interact with the player when using the Silverlight tech in IE11, AND playing DRM content, you should wait for the canplay event.
  • On iOS, only Safari provides the necessary DRM browser APIs (EME), WebViews do not currently have EME support. Therefore Fairplay DRM will only work on Safari.

Changelog

25 Oct 2018

As of player 6.26.0 the player supports DASH multiperiod. For ealier versions of the player, the Shaka player is required for DASH multiperiod.

24 Oct 2018

v5.4.2

  • Don't set up EME early if no init data in manifest

24 Oct 2018

v5.4.1

  • Exposed API to immediately set up EME

20 Sep 2018

v5.4.0

  • Trigger DRM key status changes on player tech

23 Aug 2018

v5.3.1

  • Added field for automatic initialization from registry

30 Mar 2018

v5.3.0

  • Support in-manifest DRM init data

20 Feb 2018

v5.2.2

  • Add certificate for BC Widevine sources when using VHS

20 Feb 2018

v5.2.1

  • Support key rotation
  • Use HTTPS links for Silverlight installer

17 Jan 2018

v5.2.0

  • Add Castlabs third-party integration

3 Jan 2018

v5.1.0

  • Add custom third-party vendor logic to keySystems

15 Dec 2017

v5.0.0

  • Support DRM DASH playback with VHS

14 Nov 2017

v4.5.0

  • Preload Widevine server certificate
  • Added preload none support

8 Nov 2017

v4.4.1

  • Fixed issue where loadstart would not fire when using Silverlight

6 Sep 2017

v4.4.0

  • Parse ms:laurl and mspr:pro from manifest
  • Fixed issue where text tracks would not be removed on source change

3 Aug 2017

v4.3.5

  • Fixed minification process

31 Jul 2017

v4.3.4

  • Fixed duration rounding in Silverlight when using the dashPreprocessing option

27 Jul 2017

v4.3.3

  • Report frame stats from Silverlight playback

25 Jul 2017

v4.3.2

  • Automatically log debug information in debug script

19 Jul 2017

v4.3.1

  • Fixed intermittent license acquisition error when switching sources in Silverlight

12 Jul 2017

v4.3.0

  • Call player error on critical errors

11 Jul 2017

v4.2.7

  • Fixed an source change issue in Silverlight by clearing IsEnded on unload

10 Jul 2017

v4.2.6

  • Fixed an issue where representations did not accurately reflect manifest

10 Jul 2017

v4.2.5

  • Fixed an issue where Silverlight representations wouldn't populate
  • Fixed an issue where Silverlight would error on source change

10 Jul 2017

v4.2.4

  • Fixed an issue where VTTCue shims would conflict

3 Jul 2017

v4.2.3

  • Fixed an issue where playback has stalled within 0.5s of the end
  • Fixed an error during source change in Silverlight

21 Jun 2017

v4.2.2

  • Fixed an issue with limiting renditions on player resize

20 Jun 2017

v4.2.1

  • Don't exclude variants that are missing key status info

15 Jun 2017

v4.2.0

  • In-manifest text track support

15 Jun 2017

v4.1.1

  • Clear representations state between sources in Silverlight

9 Jun 2017

v4.1.0

  • Update from Shaka Player v2.0.8 to Shaka Player v2.1.3

9 Jun 2017

v4.0.1

  • Fixed source not supported error in IE when switching sources
  • Warn when skipping DASH sources on insecure contexts
  • Timeout when Silverlight playback halts

1 May 2017

v4.0.0

  • Use Shaka Player for DASH playback

25 Apr 2017

v3.4.2

  • Show role in audio track label

24 Apr 2017

v3.4.1

  • Disable videojs-errors progress event watcher

3 Apr 2017

v3.4.0

  • Used Native/EME ABR limiting methods to set quality levels
  • Updated to Native/EME 2.4.1

21 Feb 2017

v3.3.2

  • Reverted to Native/EME 2.3.0 to fix quality selection issues

13 Feb 2017

v3.3.1

  • Updated videojs-contrib-eme to support delayed setup

13 Feb 2017

v3.3.0

  • Updated to Native/EME 2.4.1
  • Updated videojs-contrib-eme to support video.js 6

9 Feb 2017

v3.2.1

  • Fixed updating source in canHandleSource

8 Feb 2017

v3.2.0

  • Added multiple audio track support
  • Added video.js 6 forward compatibility
  • Allows passing in dashjs options with player constructor

6 Jan 2017

v3.1.0

  • Support the quality levels API

9 Dec 2016

v3.0.6

  • Fixed representation whitelisting

7 Dec 2016

v3.0.5

  • Correctly hide player overlays when Silverlight is disabled/not installed

1 Nov 2016

v3.0.4

  • Add PlayReady key system if it doesn't exist in the catalog response

3 Oct 2016

v3.0.3

  • Update to dashjs 2.3.0
  • Rename project to videojs-drm

27 Sep 2016

v3.0.2

  • Disable dashjs debug logging

9 Sep 2016

v3.0.1

  • Update techOrder to HTML5, Silverlight

8 Sep 2016

v3.0.0

  • Added Fairplay DRM support for HLS

24 Aug 2016

v2.3.0

  • Expose dashjs mediaPlayer as player.dash.mediaPlayer

25 Jul 2016

v2.2.1

  • Update to dashjs 2.2.0

8 Jul 2016

v2.2.0

  • Update videojs-silverlight to support dashjs on Firefox