Radiant Media Player

DASH & HLS DRM



DASH & HLS DRM documentation sections:


Supported DASH & HLS DRM

Radiant Media Player supports the following DRM with DASH and/or HLS streaming. Our implementation relies on DRM features provided by Shaka Player.

Our DRM implementation relies on Encrypted Media Extensions (EME) support in the browser. Complementary to EME support a browser must have a compatible Content Decryption Module (CDM) to decrypt the DRM content.

You can use either one DRM or a combination of multiple DRM for wider browser support. The player will automatically pick the correct DRM for the targeted browser based on information provided within the DASH or HLS manifest and player settings.


Supported browsers for DASH & HLS DRM

See our compatibility table for a list of browsers where DASH or HLS DRM is supported with Radiant Media Player.

On macOS Safari FairPlay DRM is also supported with Radiant Media Player. On iOS no DRM option is currently available as Apple does not provide support for FairPlay DRM on iOS. Knowing that we recommend using HLSe (AES-128/SAMPLE-AES encrypted HLS) as a fallback for iOS. See here for an example using DASH DRM and HLSe as a fallback.

In order to provide decent browser coverage you are likely to have to use a multi-DRM approach. Combining Widevine and PlayReady is a common standard in the industry.


Player configuration


General consideration

It ain't rocket science - following the below guidelines should help you get started with DASH or HLS DRM rapidly.

You can go through our DASH & HLS with Shaka Player documentation for a better understanding of available streaming options.

To play DRM-protected content with DASH or HLS, the player only needs to know 2 things: the URL of the DRM license server and what options are required to fetch and validate the license. Below you will also find various configuration options to support custom & advanced DRM use-cases.


Choosing a Key System

Radiant Media Player is key-system-agnostic, meaning it does not prefer any key systems over any others. We use EME to ask the browser what it supports, and make no assumptions. If the browser supports multiple key systems, the first supported key system in the DASH or HLS manifest is used. The interoperable encryption standard that DRM vendors are implementing is called Common Encryption (CENC). Some DASH manifests don't specify any particular key system at all, but instead state that any CENC system will do:

<ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc"/>

If this is the only <ContentProtection> element in the manifest, Radiant Media Player will try all key systems it knows. If the browser supports it and you configured a license server URL for it, we'll use it.


Player settings

shakaDrm: Object

This is where we feed the player the license server URL and other DRM-related options. The shakaDrm object supports 3 properties:

shakaDrm.servers: Object

This is where license server URLs are passed to the player. Example for a combination of Widevine, PlayReady & Clear Key license servers:

shakaDrm: {
  servers: {
    'com.widevine.alpha': 'https://foo.bar/drm/widevine',
    'com.microsoft.playready': 'https://foo.bar/drm/playready',
    'org.w3.clearkey': 'http://foo.bar/drm/clearkey'
  }
}
shakaDrm.clearKeys: Object

The EME specification requires browsers to support a common key system called "Clear Key". Clear Key uses unencrypted keys to decrypt CENC content, and can be useful for diagnosing problems and testing integrations. To configure Clear Key, use the configuration field shakaDrm.clearKeys and provide a map of key IDs to content keys (both in HEX format). Example:

shakaDrm: {
  clearKeys: {
    'deadbeefdeadbeefdeadbeefdeadbeef': '18675309186753091867530918675309',
    '02030507011013017019023029031037': '03050701302303204201080425098033'
  }
}
shakaDrm.advanced: Object

We have several advanced options available to give you access to the full EME configuration. The configuration field shakaDrm.advanced is an object mapping key system IDs to their advanced settings. For example, to require hardware security in Widevine:

shakaDrm: {
  servers: {
    'com.widevine.alpha': 'https://foo.bar/drm/widevine'
  },
  advanced: {
    'com.widevine.alpha': {
      'videoRobustness': 'HW_SECURE_ALL',
      'audioRobustness': 'HW_SECURE_ALL'
    }
  }
}

Refer to this Google documentation page for a list of supported properties in the shakaDrm.advanced object.

Follows a player code example with DASH Widevine DRM (works on latest Chrome, Firefox or Opera).

DASH/HLS/DRM resources throughout this page are provided by 3rd-party - availability may change - use your own test vectors for best results.

<!-- Include Radiant Media Player JavaScript file in your <body> or <head> -->
<script src="https://cdn.radiantmediatechs.com/rmp/4.6.31/js/rmp.min.js" 
  integrity="sha384-0e5VoJys67yt6cz1Ibu8uYZquAAscPyK6qP2a/u8FXKlgeC6BO1dM2r8H4asqJCI"
  crossorigin="anonymous"></script>
<!-- Set up your wrapper div with its unique id -->
<div id="rmpPlayer"></div>
<!-- Set up player configuration options -->
<script>
var bitrates = {
  dash: '//storage.googleapis.com/shaka-demo-assets/angel-one-widevine/dash.mpd'
};
var settings = {
  licenseKey: 'your-license-key',
  bitrates: bitrates,
  width: 640,
  height: 360,
  poster: 'https://www.radiantmediaplayer.com/images/poster-rmp-showcase.jpg',
  shakaDrm: {
    servers: {
      'com.widevine.alpha': '//cwip-shaka-proxy.appspot.com/no_auth'
    }
  }
};
var elementID = 'rmpPlayer';
var rmp = new RadiantMP(elementID);
rmp.init(settings);
</script>

Now an example with fMP4 HLS Widevine DRM (works on latest Chrome, Firefox or Opera).

<!-- Include Radiant Media Player JavaScript file in your <body> or <head> -->
<script src="https://cdn.radiantmediatechs.com/rmp/4.6.31/js/rmp.min.js" 
  integrity="sha384-0e5VoJys67yt6cz1Ibu8uYZquAAscPyK6qP2a/u8FXKlgeC6BO1dM2r8H4asqJCI"
  crossorigin="anonymous"></script>
<!-- Set up your wrapper div with its unique id -->
<div id="rmpPlayer"></div>
<!-- Set up player configuration options -->
<script>
var bitrates = {
  hls: '//storage.googleapis.com/shaka-demo-assets/angel-one-widevine-hls/hls.m3u8'
};
var settings = {
  licenseKey: 'your-license-key',
  bitrates: bitrates,
  width: 640,
  height: 360,
  poster: 'https://www.radiantmediaplayer.com/images/poster-rmp-showcase.jpg',
  hlsEngine: 'shakaplayer',
  shakaDrm: {
    servers: {
      'com.widevine.alpha': '//cwip-shaka-proxy.appspot.com/no_auth'
    }
  }
};
var elementID = 'rmpPlayer';
var rmp = new RadiantMP(elementID);
rmp.init(settings);
</script>

License server authentication

Your license server may require some form of authentication so that it only delivers licenses to paying users. In this section we're going to use various license server endpoints that require various forms of authentication. If you need live example to test your set up you can refer to this Google documentation page.

We provide support for 3 authentication modes: header authentication, parameter authentication & cookie authentication

Authentication is provided through the shakaRequestConfiguration player setting. You can refer to our DASH & HLS with Shaka Player for more information as this setting may also be used outside DRM context.

Header authentication

In this case your license server requires a specific header value to deliver a license. If you try to use it without setting the authentication header, you will see Error code 6007 in the player logs, which means LICENSE_REQUEST_FAILED. The JavaScript console will show you a failed HTTP request with HTTP status code 401 (Unauthorized), and playback will hang when you get to the encrypted part of the stream.

To provide header authentication we will use the player shakaRequestConfiguration setting as follows:

shakaRequestConfiguration: {
  license: {
    headers: {
      'CWIP-Auth-Header': 'VGhpc0lzQVRlc3QK'
    }
  }
}

Full player example - this example is provided for Widevine DRM - test in Chrome:

<!-- Include Radiant Media Player JavaScript file in your <body> or <head> -->
<script src="https://cdn.radiantmediatechs.com/rmp/4.6.31/js/rmp.min.js" 
  integrity="sha384-0e5VoJys67yt6cz1Ibu8uYZquAAscPyK6qP2a/u8FXKlgeC6BO1dM2r8H4asqJCI"
  crossorigin="anonymous"></script>
<!-- Set up your wrapper div with its unique id -->
<div id="rmpPlayer"></div>
<!-- Set up player configuration options -->
<script>
var bitrates = {
  dash: '//storage.googleapis.com/shaka-demo-assets/sintel-widevine/dash.mpd'
};
var settings = {
  licenseKey: 'your-license-key',
  bitrates: bitrates,
  width: 640,
  height: 360,
  poster: 'https://www.radiantmediaplayer.com/images/poster-rmp-showcase.jpg',
  shakaDrm: {
    servers: {
      'com.widevine.alpha': '//cwip-shaka-proxy.appspot.com/header_auth'
    }
  },
  shakaRequestConfiguration: {
    license: {
      headers: {
        'CWIP-Auth-Header': 'VGhpc0lzQVRlc3QK'
      }
    }
  }
};
var elementID = 'rmpPlayer';
var rmp = new RadiantMP(elementID);
rmp.init(settings);
</script>
Parameter authentication

Now, we'll try authentication using URL parameters. In this case the license server endpoint requires a specific URL parameter to deliver a license. If you try to use it without setting the parameter, you will see Error code 6007 (LICENSE_REQUEST_FAILED) in player logs just as before with header authentication.

Again to provide parameter authentication we will use the player shakaRequestConfiguration setting as follows:

shakaRequestConfiguration: {
  license: {
    parameters: '?CWIP-Auth-Param=VGhpc0lzQVRlc3QK'
  } 
}

Full player example - this example is provided for Widevine DRM - test in Chrome:

<!-- Include Radiant Media Player JavaScript file in your <body> or <head> -->
<script src="https://cdn.radiantmediatechs.com/rmp/4.6.31/js/rmp.min.js" 
  integrity="sha384-0e5VoJys67yt6cz1Ibu8uYZquAAscPyK6qP2a/u8FXKlgeC6BO1dM2r8H4asqJCI"
  crossorigin="anonymous"></script>
<!-- Set up your wrapper div with its unique id -->
<div id="rmpPlayer"></div>
<!-- Set up player configuration options -->
<script>
var bitrates = {
  dash: '//storage.googleapis.com/shaka-demo-assets/sintel-widevine/dash.mpd'
};
var settings = {
  licenseKey: 'your-license-key',
  bitrates: bitrates,
  width: 640,
  height: 360,
  poster: 'https://www.radiantmediaplayer.com/images/poster-rmp-showcase.jpg',
  shakaDrm: {
    servers: {
      'com.widevine.alpha': '//cwip-shaka-proxy.appspot.com/param_auth'
    }
  },
  shakaRequestConfiguration: {
    license: {
      parameters: '?CWIP-Auth-Param=VGhpc0lzQVRlc3QK'
    }
  }
};
var elementID = 'rmpPlayer';
var rmp = new RadiantMP(elementID);
rmp.init(settings);
</script>

Now, let's try using cookies for authentication. In this case the license server endpoint requires a specific cookie to deliver a license. If you try to use it without setting the parameter, you will see Error code 6007 (LICENSE_REQUEST_FAILED) in player logs. Cookies are set by a server to be returned to that server, and are not sent by the JavaScript application. So to set the required cookie value for this test example, point your browser to the server's set_cookie page. Cookies are considered "credentials" by the browser's XmlHttpRequest API, and credentials may not be sent cross-origin unless explicitly requested by the application AND explicitly allowed by the destination server. Our cookie_auth license server endpoint sends back headers that allow credentialed requests, so we also need to tell the player to send credentials cross-site.

Again to provide cookie authentication we will use the player shakaRequestConfiguration setting as follows:

shakaRequestConfiguration: {
  license: {
    credentials: true
  } 
}

Full player example - this example is provided for Widevine DRM - test in Chrome:

<!-- Include Radiant Media Player JavaScript file in your <body> or <head> -->
<script src="https://cdn.radiantmediatechs.com/rmp/4.6.31/js/rmp.min.js" 
  integrity="sha384-0e5VoJys67yt6cz1Ibu8uYZquAAscPyK6qP2a/u8FXKlgeC6BO1dM2r8H4asqJCI"
  crossorigin="anonymous"></script>
<!-- Set up your wrapper div with its unique id -->
<div id="rmpPlayer"></div>
<!-- Set up player configuration options -->
<script>
var bitrates = {
  dash: '//storage.googleapis.com/shaka-demo-assets/sintel-widevine/dash.mpd'
};
var settings = {
  licenseKey: 'your-license-key',
  bitrates: bitrates,
  width: 640,
  height: 360,
  poster: 'https://www.radiantmediaplayer.com/images/poster-rmp-showcase.jpg',
  shakaDrm: {
    servers: {
      'com.widevine.alpha': '//cwip-shaka-proxy.appspot.com/cookie_auth'
    }
  },
  shakaRequestConfiguration: {
    license: {
      credentials: true
    } 
  }
};
var elementID = 'rmpPlayer';
var rmp = new RadiantMP(elementID);
rmp.init(settings);
</script>
Asynchronous credentials

In some scenarios, you may not know the credentials right away. You would like to make an additional request to get those credentials before you attach them to the request Radiant Media Player wants to make. Since version 4.6.16 we have simplified handling of such use cases through the shakaCustomRequestFilter player setting. Refer to this Shaka player docs for more information. Following is a player code example for using asynchronous credentials and Radiant Media Player:

<!-- Include Radiant Media Player JavaScript file in your <body> or <head> -->
<script src="https://cdn.radiantmediatechs.com/rmp/4.6.31/js/rmp.min.js" 
  integrity="sha384-0e5VoJys67yt6cz1Ibu8uYZquAAscPyK6qP2a/u8FXKlgeC6BO1dM2r8H4asqJCI"
  crossorigin="anonymous"></script>
<!-- Set up your wrapper div with its unique id -->
<div id="rmpPlayer"></div>
<!-- Set up player configuration options -->
<script>
var licenseServer = 'https://cwip-shaka-proxy.appspot.com/header_auth';
var authTokenServer = 'https://cwip-shaka-proxy.appspot.com/get_auth_token';
var authToken = null;
var elementID = 'rmpPlayer';
var rmp = new RadiantMP(elementID);
var shakaCustomRequestFilter = function (type, request) {
  console.log('shakaCustomRequestFilter callback');
  // Only add headers to license requests:
  if (type != shaka.net.NetworkingEngine.RequestType.LICENSE) return;

  // If we already know the token, attach it right away:
  if (authToken) {
    console.log('Have auth token, attaching to license request.');
    request.headers['CWIP-Auth-Header'] = authToken;
    return;
  }

  console.log('Need auth token.');
  // Start an asynchronous request, and return a Promise chain based on that.
  var authRequest = {
    uris: [authTokenServer],
    method: 'POST',
  };
  var requestType = shaka.net.NetworkingEngine.RequestType.APP;
  return rmp.shakaPlayer.getNetworkingEngine().request(requestType, authRequest).then(
    function (response) {
      // This endpoint responds with the value we should use in the header.
      authToken = shaka.util.StringUtils.fromUTF8(response.data);
      console.log('Received auth token', authToken);
      request.headers['CWIP-Auth-Header'] = authToken;
      console.log('License request can now continue.');
    });
};
var bitrates = {
  dash: 'https://storage.googleapis.com/shaka-demo-assets/sintel-widevine/dash.mpd'
};
var settings = {
  licenseKey: 'your-license-key',
  bitrates: bitrates,
  shakaDrm: {
    servers: {
      'com.widevine.alpha': licenseServer
    }
  },
  shakaCustomRequestFilter: shakaCustomRequestFilter,
  poster: 'https://www.radiantmediaplayer.com/images/poster-rmp-360.jpg'
};
rmp.init(settings);
</script>

DASH DRM with AES-128/SAMPLE-AES HLS fallback

When using a combined Widevine/PlayReady DRM approach with DASH streaming modern browser support should be fairly good. However on iOS or macOS Safari where DRM Widevine/PlayReady are not supported you can use HLSe (AES-128/SAMPLE-AES encrypted HLS) as a fallback. On macOS Safari you may also consider using Apple FairPlay DRM but this is not available in iOS Safari yet.

Player code example:

<!-- Include Radiant Media Player JavaScript file in your <body> or <head> -->
<script src="https://cdn.radiantmediatechs.com/rmp/4.6.31/js/rmp.min.js" 
  integrity="sha384-0e5VoJys67yt6cz1Ibu8uYZquAAscPyK6qP2a/u8FXKlgeC6BO1dM2r8H4asqJCI"
  crossorigin="anonymous"></script>
<!-- Set up your wrapper div with its unique id -->
<div id="rmpPlayer"></div>
<!-- Set up player configuration options -->
<script>
var bitrates = {
  dash: '//media.axprod.net/TestVectors/v7-MultiDRM-SingleKey/Manifest.mpd',
  // here is our AES-128 HLS fallback
  hls: 'https://www.rmp-streaming.com/media/rmp-segment/bbb-abr-aes/playlist.m3u8'
};
var settings = {
  licenseKey: 'your-license-key',
  bitrates: bitrates,
  width: 640,
  height: 360,
  poster: 'https://www.radiantmediaplayer.com/images/poster-rmp-showcase.jpg',
  dashFirst: true,
  hlsEngine: 'hlsjs',
  shakaDrm: {
    servers: {
      'com.widevine.alpha': '//drm-widevine-licensing.axtest.net/AcquireLicense',
      'com.microsoft.playready': '//drm-playready-licensing.axtest.net/AcquireLicense'
    }
  },
  shakaRequestConfiguration: {
    license: {
      headers: {
        'X-AxDRM-Message': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2ZXJzaW9uIjoxLCJjb21fa2V5X2lkIjoiYjMzNjRlYjUtNTFmNi00YWUzLThjOTgtMzNjZWQ1ZTMxYzc4IiwibWVzc2FnZSI6eyJ0eXBlIjoiZW50aXRsZW1lbnRfbWVzc2FnZSIsImtleXMiOlt7ImlkIjoiOWViNDA1MGQtZTQ0Yi00ODAyLTkzMmUtMjdkNzUwODNlMjY2IiwiZW5jcnlwdGVkX2tleSI6ImxLM09qSExZVzI0Y3Iya3RSNzRmbnc9PSJ9XX19.4lWwW46k-oWcah8oN18LPj5OLS5ZU-_AQv7fe0JhNjA' 
      }
    }
  }
};
var elementID = 'rmpPlayer';
var rmp = new RadiantMP(elementID);
rmp.init(settings);
</script>

ExpressPlay multi-drm example (using ExpressPlay tokens)

ExpressPlay is a Radiant Media Player technology alliance partner.

shakaDrm: {
  servers: {
    'com.widevine.alpha': 'https://wv.test.expressplay.com/hms/wv/rights/?ExpressPlayToken=AQAAAw3paXgAAABQspzLNQNh4hZbd8PGRZI0HqY47W8g4G8-y_3XjUuYCQkbT1RCyHha0YJmqoed_HxdPaqOgETYKRhqV-bbQc61IlNRjmC3YKA-XWQbM0fdeMyXIt44CeXileOMh6ngDkjwJWpIWw',
    'com.microsoft.playready': 'https://pr.test.expressplay.com/playready/RightsManager.asmx?ExpressPlayToken=AQAAAw3pWtgAAABgs-tivO_PM27AQvSjxG2CiJrtQ1MFfcIGvu2VYvd0ZSVJ7tE_48I2GJYNZLd8hwWTxwW1t3as0lkV3Ac-4fKwe3GZLe2eNpvHoRnjbej52rrFlKDbnoGthCD8PkR75tguGxBMMuxICQcUmBD52QzrL8xIuOw'
  }
}

Currently unsupported DRM-related features

The following features are not currently implemented but could be in the near future based on feedback and customer usage.


Supported DRM service providers

Radiant Media Player should work with any standard compliant DRM service providers that can encrypt media content with Widevine and/or PlayReady and/or FairPlay DRM. Below are names of DRM services that our customers have successfully used with Radiant Media Player:

Based on the solution your DRM service provider offer you may also need a solution to package your content for DASH or HLS. Wowza Streaming Engine supports on-the-fly DASH CENC encryption for on demand and live content via the PlayReady and Widevine DRM systems.

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 3.0 License.