Media Source Extensions and Encrypted Media Extensions provide websites with new options for streaming premium audio and video. These specifications provide a framework for building media websites that can work across multiple browsers on a broad range of devices, including phones, consumer electronics, and PCs. We first talked about these APIs in our 2013 post, Professional Quality Video. We’ve been busy since then, and it’s a time for an update. In this post, we will share some guidance on building sites that work across browsers, and are excited to introduce a new Test Drive demo showing interoperable playback of protected content.

Specification Changes

The specifications for both Media Source Extensions (MSE) and Encrypted Media Extensions (EME) are still in development. Microsoft first supported them in Internet Explorer 11 on Windows 8.1, using an “ms” prefix for the EME APIs to denote they were likely to change. Since that time, the EME spec has added new APIs for requesting keySystem access and new operations supported under MediaKeySession, among other changes. These have been implemented in Microsoft Edge on Windows 10 PCs and, for the first time, Windows phones.

Both prefixed and the new unprefixed APIs are supported in Microsoft Edge, while IE11 has prefixed support only. This means that a website built to use the prefixed API will continue to work on Microsoft Edge and IE11. Websites that use the unprefixed APIs should work on Microsoft Edge, but developers should verify their implementations on Edge to confirm this. There are some details that require developer attention to achieve interoperable EME. There’s more on this below.

Multiple DRM Providers

EME was designed to support multiple Digital Rights Management (DRM) providers (“keySystems”) using Content Decryption Modules. The API itself is intended to be DRM neutral. Each browser that supports EME has implemented at least one CDM.

A key underpinning that makes this work is the development of ISO MPEG Common Encryption. By using common encryption, web media services can set up uniform content libraries that are compatible with more than one DRM solution. A service can choose to support more than one DRM without having to encrypt content for each individual DRM.

In practice, this means that websites encrypt files once, and support one or more DRM license servers to enable playback on individual web browsers. So, they can support a PlayReady DRM license server to enable playback on IE11, Microsoft Edge or non-Windows browser which supports a PlayReady CDM; and other DRM license servers (Widevine, Adobe Access, FairPlay, etc…) to enable playback on other browsers. This ability to have one encrypted library work with multiple keySystems is an important feature of EME. Websites must though include some code for each keySystem and browser combination the designers wish to support.

Interoperable Demo

To demonstrate these concepts, we’ve updated our Professional Quality Video demo from three years ago.We had two goals for this update:

  1. Implement prefixed/unprefixed EME selection so that the demo works properly on existing IE11 browsers using the prefixed API, and on Microsoft Edge using the updated unprefixed API.
  2. Implement keySystem switching to allow the demo to run on Microsoft browsers and other browsers.

Microsoft Azure Media Services hosts the content for our demo. Azure Media Services allows you to get PlayReady or Widevine (the keySystem that is supported natively in Google Chrome) licenses from the cloud and stream multi-DRM protected content to various platforms and devices. This provided the opportunity to expand our demo so that it works either on Microsoft browsers using PlayReady DRM or Chrome using Widevine.

Please refer to Using PlayReady and/or Widevine dynamic common encryption for more information on how to use different content protection systems with Azure Media Services.

The following sections explain key implementation points from the Professional Quality Video Updated – Interoperable Playback demo.

Detect Updated EME

The demo first needs to determine what version of EME is available. In the code below, we feature detect to see if requestMediaKeySystemAccess is supported, and use that as an indicator for the updated EME support in the browser:

if (window.navigator.requestMediaKeySystemAccess) {
// unprefixed EME (Edge/Chrome)
videoElement.addEventListener('encrypted', this.getNewKeySession, false);
else {
// prefixed EME (IE11)
videoElement.addEventListener('msneedkey', this.getNewPrefixedKeySession, false);

The demo elects to use the unprefixed EME when it is available, but the choice here is up to the webpage developers. Unprefixed EME doesn’t isolate the browser to Microsoft Edge only. For our supported browser set, it could be either Microsoft Edge or Chrome.

Detect keySystem

Next, we call requestMediaKeySystemAccess with a PlayReady configuration that has its keySystem string and formats we’d like to play. This API is implemented as a Promise. If PlayReady isn’t supported, the Promise is rejected. If that happens, we call requestMediaKeySystemAccess again, but this time with a Widevine configuration. If that Promise is rejected, then no playback of protected media is possible for our demo. A successful Promise return on either configuration means playback can proceed with the supported keySystem. Here’s a code snippet that demonstrates this:

// Try PlayReady
navigator.requestMediaKeySystemAccess('', [{
initDataTypes: ['keyids', 'cenc'],
audioCapabilities: [{ contentType: 'audio/mp4; codecs="mp4a"' }],
videoCapabilities: [{ contentType: 'video/mp4; codecs="avc1"' }]
]).then(function (keySystemAccess) { /* Promise succeeded. Call createMediaKeys */},function () {
// Promise was rejected for PlayReady. Try Widevine.
navigator.requestMediaKeySystemAccess('com.widevine.alpha', [{
initDataTypes: ['keyids', 'webm'],
audioCapabilities: [{ contentType: 'audio/webm; codecs="opus"'}],
videoCapabilities: [{ contentType: 'video/webm; codecs="vp9"'}]
]).then(function (keySystemAccess) { /* Promise succeeded. Call createMediaKeys */ }, function () {
// Neither Promise succeeded. Browser does not support Widevine or PlayReady

Accommodate DRM Specifics

A key difference between PlayReady and Widevine involves how the DRM challenge is handled. For PlayReady, the challenge must be parsed from the XML returned by the EME onmessage event and the app must then set the header values to fetch the key via XMLHttpRequest. This works the same as the prefixed EME support for PlayReady:

// In the keySession.addEventListener(‘message’) callback.
... Set up an XHR to the license server ...
if (/*keySystem type is PlayReady*/) {
// For PlayReady CDMs, we need to dig the Challenge out of the XML.
var keyMessageXml = new DOMParser().parseFromString(String.fromCharCode.apply(null, new Uint16Array(event.message)), 'application/xml');
challenge = atob(keyMessageXml.getElementsByTagName('Challenge')[0].childNodes[0].nodeValue);
// Set up the headers for XHR
var headerNames = keyMessageXml.getElementsByTagName('name');
var headerValues = keyMessageXml.getElementsByTagName('value');
for (var i = 0; i < headerNames.length; i++) {
xhr.setRequestHeader(headerNames[i].childNodes[0].nodeValue, headerValues[i].childNodes[0].nodeValue);
// For WideVine CDMs, the challenge is the keyMessage.
challenge = event.message;

Something else to notice is the way the license URL is used between prefixed EME and unprefixed EME. In prefixed EME, the license server URL is passed to the onmskeymessage event. In unprefixed EME, the website needs to supply the license server URL directly.


Media Source Extensions and Encrypted Media Extensions continue to be the best option for website developers that want to support streaming media on a broad range of browsers and devices. We’ve updated our demo to provide help accomplishing this. Please send us your feedback so we can further improve our media support in Microsoft Edge!

– Jesse Mohrland, Software Engineer, Microsoft Edge
– Jerry Smith, Senior Program Manager, Microsoft Edge

Source: Using Encrypted Media Extensions for interoperable protected media | Microsoft Edge Dev Blog