Documentation

MPEG-DASH and HLS DRM

Supported DRM

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

Our DRM implementation requires Encrypted Media Extensions (EME) support in the browser or WebView. Complementary to EME support a browser or WebView must have a compatible Content Decryption Module (CDM) to decrypt a specific DRM.

To reach all devices we support you are going to need to use a combination of multiple DRMs. The player will automatically pick the correct DRM for the targeted environment. A popular approach is to use MPEG-DASH with Widevine DRM to reach desktop, smart TVs and Android, while using Apple FairPlay HLS to reach Apple devices.

The below article explains how to use MPEG-DASH & HLS with Widevine/PlayReady/Clear Key DRM. Documentation for Apple FairPlay Streaming can be found here.

Supported browsers and WebView for each DRM

  • Browsers
    • Widevine
      • Chrome and Opera for Android 5+
      • Chrome, Firefox and Opera for Windows 7+, macOS 10.12+ and Linux
      • MS Edge 79+ for Windows 7+
      • Chrome for ChromeOS
      • Latest Amazon Silk for fireOS 6+
    • PlayReady
      • MS Edge 79+ for Windows 7+
      • MS Edge Legacy for Windows 7+
    • FairPlay
      • Safari on iOS 10+ and iPadOS 13+
      • Safari for macOS 10.12+
  • Android & iOS mobile apps (Ionic, Flutter, Apache Cordova, WebView)
    • Widevine: Android 7+
    • FairPlay: WKWebView for iOS 13+ and iPadOS 13+
  • OTT apps
    • Widevine
      • Samsung Smart TV apps (Tizen 3+)
      • LG Smart TV apps (webOS 3+)
      • Desktop apps with Electron 6+
      • Google Cast receiver application

Supported DRM service providers

To use DRM with Radiant Media Player you will need to use one of our DRM partners list below. While our player could work with other DRM services, we have not tested DRM services that are not listed below.

Player configuration

General consideration

You may go through our MPEG-DASH streaming docs for a better understanding of MPEG-DASH streaming options with Radiant Media Player in this configuration.

To play DRM-protected content with MPEG-DASH, 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 MPEG-DASH manifest is used. The interoperable encryption standard that DRM vendors are implementing is called Common Encryption (CENC). Some MPEG-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'
  }
}

About robustness levels (Widevine)

The robustness level key-system-specific string specifies a required security level for video/audio. By default it is set to '', which means that no specific robustness is required by the player. When no specific robustness is specified it is up to the device to decide what robustness it can support. By default most environments will select the less secure option when no robustness is specified and this is why, it is always recommended to explicitly set robustness levels. Also note that content owners may require a specific robustness level to allow 3rd-party entity to distribute their content. For Widevine those robustness levels are (L1 being the more secure level of robustness):

  • SW_SECURE_CRYPTO: Widevine Device Security Level 3
  • SW_SECURE_DECODE : Widevine Device Security Level 3
  • HW_SECURE_CRYPTO: Widevine Device Security Level 2
  • HW_SECURE_DECODE : Widevine Device Security Level 1
  • HW_SECURE_ALL: Widevine Device Security Level 1

Setting robustness level in Radiant Media Player is done through the shakaDrm.advanced setting:

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_CRYPTO'
    }
  }
}

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

Most environments should support L1 level with Widevine DRM, including:

  • Chrome and WebView for Android
  • Samsung and LG Smart TV

There is however one notable exception: Chrome and Firefox for Desktop (Windows or macOS) only offer L3 Google Widevine security level (software DRM). Read our Preventing Content Theft With DRM And Digital Watermarking blog for more information.

About robustness levels (PlayReady)

For PlayReady those robustness levels are (a higher value means better security):

  • 3000
  • 2000
  • 150 (testing)

Supported devices based on Security level (as of January 2022):

  • MS Edge for Windows 10+: level 3000 (a.k.a. hardware DRM)
  • MS Edge for Windows 7, 8, 8.1: level 2000 (a.k.a. software DRM)

By default com.microsoft.playready key system ignores given robustness and stays at a 2000 decryption level.

The introduction of com.microsoft.playready.recommandation key system allows for 3000 robustness (hardware DRM) - below is an example on how to use this robustness level with PlayReady:

const src = {
  dash: 'https://your-dash-url.mpd'
};
const settings = {
  licenseKey: 'your-license-key',
  src: src,
  width: 640,
  height: 360,
  // We map urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95 and
  // urn:uuid:79f0049a-4098-8642-ab92-e65be0885f95 (this is a legacy value)
  // that are used for PlayReady
  // to the new com.microsoft.playready.recommandation key system
  shakaKeySystemsByURI: {
    'urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95': 'com.microsoft.playready.recommendation',
    'urn:uuid:79f0049a-4098-8642-ab92-e65be0885f95': 'com.microsoft.playready.recommendation'
  },
  shakaDrm: {
    servers: {
      'com.microsoft.playready.recommendation': 'https://your-playready-drm-server/rightsmanager.asmx?cfg=(persist:false,sl:3000)'
    },
    advanced: {
      'com.microsoft.playready.recommendation': {
        'videoRobustness': '3000',
        'sessionType': 'temporary'
        // if you want persistent license with PlayReady 3000 robustness
        //'sessionType': 'persistent-license'
      }
    }
  },
  skin: 's1'
};
const rmp = new RadiantMP('rmp');
rmp.init(settings);

About robustness levels (Apple FairPlay)

For FairPlay those robustness levels are (a.k.a. ALLOWED-CPC - Content Protection Configuration):

  • AppleBaseline: Any Apple platform that supports FairPlay Streaming.
  • AppleMain: Any Apple platform that supports FairPlay Streaming and guarantees enhanced content protection robustness (sufficient for studio 4K/HDR playback).
  • Baseline: Any non-Apple platform that supports FairPlay Streaming. For example, any AirPlay 2-enabled smart TV.
  • Main: Any non-Apple platform that supports FairPlay Streaming and guarantees enhanced content protection robustness (sufficient for studio 4K/HDR playback).

Apple FairPlay is always hardware DRM.

Supported devices based on Security level (as of January 2022):

  • Safari 12+ for macOS, iOS, iPadOS: AppleBaseline

Player code example

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

<!-- Include Radiant Media Player - here we use the optimised build for Shaka player -->
<script src="https://cdn.radiantmediatechs.com/rmp/9.15.19/js/rmp-shaka.min.js"></script>
<!-- Player container element -->
<div id="rmp"></div>
<!-- Set up player configuration options -->
<script>
const src = {
  dash: 'https://storage.googleapis.com/shaka-demo-assets/angel-one-widevine/dash.mpd'
};
const settings = {
  licenseKey: 'your-license-key',
  src: src,
  width: 640,
  height: 360,
  contentMetadata: {
    poster: [
      'https://your-poster-url.jpg'
    ]
  },
  // passing DRM settings
  shakaDrm: {
    servers: {
      'com.widevine.alpha': 'https://cwip-shaka-proxy.appspot.com/no_auth'
    }
  }
};
const rmp = new RadiantMP('rmp');
rmp.init(settings);
</script>

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

<!-- Include Radiant Media Player - here we use the optimised build for Shaka player -->
<script src="https://cdn.radiantmediatechs.com/rmp/9.15.19/js/rmp-shaka.min.js"></script>
<!-- Player container element -->
<div id="rmp"></div>
<!-- Set up player configuration options -->
<script>
const src = {
  hls: 'https://storage.googleapis.com/shaka-demo-assets/angel-one-widevine-hls/hls.m3u8'
};
const settings = {
  licenseKey: 'your-license-key',
  src: src,
  width: 640,
  height: 360,
  contentMetadata: {
    poster: [
      'https://your-poster-url.jpg'
    ]
  },
  hlsEngine: 'shakaplayer',
  // passing DRM settings
  shakaDrm: {
    servers: {
      'com.widevine.alpha': 'https://cwip-shaka-proxy.appspot.com/no_auth'
    }
  }
};
const rmp = new RadiantMP('rmp');
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 MPEG-DASH docs 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 - see this example here

<!-- Include Radiant Media Player - here we use the optimised build for Shaka player -->
<script src="https://cdn.radiantmediatechs.com/rmp/9.15.19/js/rmp-shaka.min.js"></script>
<!-- Player container element -->
<div id="rmp"></div>
<!-- Set up player configuration options -->
<script>
const src = {
  dash: 'https://storage.googleapis.com/shaka-demo-assets/sintel-widevine/dash.mpd'
};
const settings = {
  licenseKey: 'your-license-key',
  src: src,
  width: 640,
  height: 360,
  contentMetadata: {
    poster: [
      'https://your-poster-url.jpg'
    ]
  },
  // passing DRM settings
  shakaDrm: {
    servers: {
      'com.widevine.alpha': 'https://cwip-shaka-proxy.appspot.com/header_auth'
    }
  },
  shakaRequestConfiguration: {
    license: {
      headers: {
        'CWIP-Auth-Header': 'VGhpc0lzQVRlc3QK'
      }
    }
  }
};
const rmp = new RadiantMP('rmp');
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 - here we use the optimised build for Shaka player -->
<script src="https://cdn.radiantmediatechs.com/rmp/9.15.19/js/rmp-shaka.min.js"></script>
<!-- Player container element -->
<div id="rmp"></div>
<!-- Set up player configuration options -->
<script>
const src = {
  dash: 'https://storage.googleapis.com/shaka-demo-assets/sintel-widevine/dash.mpd'
};
const settings = {
  licenseKey: 'your-license-key',
  src: src,
  width: 640,
  height: 360,
  contentMetadata: {
    poster: [
      'https://your-poster-url.jpg'
    ]
  },
  // passing DRM settings
  shakaDrm: {
    servers: {
      'com.widevine.alpha': 'https://cwip-shaka-proxy.appspot.com/param_auth'
    }
  },
  shakaRequestConfiguration: {
    license: {
      parameters: '?CWIP-Auth-Param=VGhpc0lzQVRlc3QK'
    }
  }
};
const rmp = new RadiantMP('rmp');
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 - here we use the optimised build for Shaka player -->
<script src="https://cdn.radiantmediatechs.com/rmp/9.15.19/js/rmp-shaka.min.js"></script>
<!-- Player container element -->
<div id="rmp"></div>
<!-- Set up player configuration options -->
<script>
const src = {
  dash: 'https://storage.googleapis.com/shaka-demo-assets/sintel-widevine/dash.mpd'
};
const settings = {
  licenseKey: 'your-license-key',
  src: src,
  width: 640,
  height: 360,
  contentMetadata: {
    poster: [
      'https://your-poster-url.jpg'
    ]
  },
  // passing DRM settings
  shakaDrm: {
    servers: {
      'com.widevine.alpha': 'https://cwip-shaka-proxy.appspot.com/cookie_auth'
    }
  },
  shakaRequestConfiguration: {
    license: {
      credentials: true
    } 
  }
};
const rmp = new RadiantMP('rmp');
rmp.init(settings);
</script>
Asynchronous credentials

In some scenarios, you may not know the credentials right away. An additional request to get those credentials may be needed before you attach them to the request Radiant Media Player wants to make. This can be done through the shakaCustomRequestFilter and shakaCustomResponseFilter player settings. 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 - here we use the optimised build for Shaka player -->
<script src="https://cdn.radiantmediatechs.com/rmp/9.15.19/js/rmp-shaka.min.js"></script>
<!-- Player container element -->
<div id="rmp"></div>
<!-- Set up player configuration options -->
<script>
const licenseServer = 'https://cwip-shaka-proxy.appspot.com/header_auth';
const authTokenServer = 'https://cwip-shaka-proxy.appspot.com/get_auth_token';
let authToken = null;
const rmp = new RadiantMP('rmp');
const 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.
  const authRequest = {
    uris: [authTokenServer],
    method: 'POST',
  };
  const 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.'); 
    });
};
const src = {
  dash: 'https://storage.googleapis.com/shaka-demo-assets/sintel-widevine/dash.mpd'
};
const settings = {
  licenseKey: 'your-license-key',
  src: src,
  // passing DRM settings
  shakaDrm: {
    servers: {
      'com.widevine.alpha': licenseServer
    }
  },
  shakaCustomRequestFilter: shakaCustomRequestFilter,
  contentMetadata: {
    poster: [
      'https://your-poster-url.jpg'
    ]
  }
};
rmp.init(settings);
</script>

License wrapping

The player may need to communicate extra information to the license server. Encrypted Media Extensions, the web API for DRM playback, does not offer a direct way to include extra information in a license request or extract extra information from a license response. To pass extra information, the player can "wrap" requests and "unwrap" responses with JavaScript.

Wrapping license requests

If the player has to communicate complex information to the license server along with the request, the solution is to "wrap" the license request client-side and to "unwrap" it on the license server. Since we are using Shaka Player for Widevine/PlayReady DRM handling, we need to pass a custom network request filter to the player. This is done with the shakaCustomRequestFilter setting.

Player code example for a Widevine license server:

<!-- Include Radiant Media Player - here we use the optimised build for Shaka player -->
<script src="https://cdn.radiantmediatechs.com/rmp/9.15.19/js/rmp-shaka.min.js"></script>
<!-- Player container element -->
<div id="rmp"></div>
<!-- Set up player configuration options -->
<script>
  const licenseServer = 'https://cwip-shaka-proxy.appspot.com/wrapped_request';

  const customRequestFilter = function(type, request, context) {
    // Required utilities provided by Shaka Player
    const StringUtils = shaka.util.StringUtils;
    const Uint8ArrayUtils = shaka.util.Uint8ArrayUtils;

    // Only manipulate license requests
    if (type == shaka.net.NetworkingEngine.RequestType.LICENSE) {
      // Create the wrapped request structure
      const wrapped = {};

      // Encode the raw license request in base64
      // The server used in this example expects this field and encoding for the raw request.
      wrapped.rawLicenseRequestBase64 = Uint8ArrayUtils.toBase64(new Uint8Array(request.body));

      // Add needed information to communicate to the license server
      // This is an example, you will need to adapt this part based on your license server requirements
      wrapped.payload = btoa(String.fromCharCode.apply(null, new Uint8Array(request.body)));
      wrapped.drmType = 'WV';
      wrapped.contentId = '1';
      wrapped.providerId = '123456789';
      wrapped.packageId = '1';
      wrapped.token = 'dummy';

      // Encode the wrapped request as JSON string and convert the JSON string back into an ArrayBuffer to replace the request body
      const wrappedJson = JSON.stringify(wrapped);
      request.body = StringUtils.toUTF8(wrappedJson);
    }
  };

  const src = {
    dash: 'https://storage.googleapis.com/shaka-demo-assets/sintel-widevine/dash.mpd'
  };

  const settings = {
    licenseKey: 'your-license-key',
    src: src,
    // passing DRM settings
    shakaDrm: {
      servers: {
        'com.widevine.alpha': licenseServer
      }
    },
    shakaCustomRequestFilter: customRequestFilter,
    contentMetadata: {
      poster: [
        'https://your-poster-url.jpg' 
      ]
    }
  };
  
  const elementID = 'rmp';
  const rmp = new RadiantMP(elementID);
  rmp.init(settings);
</script>
Wrapping license requests and responses

If the license server has to communicate complex information back to the player, the solution is very similar to wrapping license requests as shown above. The license server will "wrap" the license server-side and the player will "unwrap" it client-side. Since we are using Shaka Player for Widevine/PlayReady DRM handling, we need to pass a custom network response filter to the player. This is done with the shakaCustomRequestFilter setting.

Player code example for a Widevine license server (wrapped request and response):

<!-- Include Radiant Media Player - here we use the optimised build for Shaka player -->
<script src="https://cdn.radiantmediatechs.com/rmp/9.15.19/js/rmp-shaka.min.js"></script>
<!-- Player container element -->
<div id="rmp"></div>
<!-- Set up player configuration options -->
<script>
  const licenseServer = 'https://cwip-shaka-proxy.appspot.com/wrapped_request_and_response';

  const customRequestFilter = function(type, request, context) {
    // Required utilities provided by Shaka Player
    const StringUtils = shaka.util.StringUtils;
    const Uint8ArrayUtils = shaka.util.Uint8ArrayUtils;

    // Only manipulate license requests
    if (type == shaka.net.NetworkingEngine.RequestType.LICENSE) {
      // Create the wrapped request structure
      const wrapped = {};

      // Encode the raw license request in base64
      // The license server used in this example expects a rawLicenseRequestBase64 field and this encoding for the raw request
      // You will need to adapt this part based on your license server requirements
      wrapped.rawLicenseRequestBase64 = Uint8ArrayUtils.toBase64(new Uint8Array(request.body));

      // Add needed information to communicate to the license server
      // This is an example, you will need to adapt this part based on your license server requirements
      wrapped.payload = btoa(String.fromCharCode.apply(null, new Uint8Array(request.body)));
      wrapped.drmType = 'WV';
      wrapped.contentId = '1';
      wrapped.providerId = '123456789';
      wrapped.packageId = '1';
      wrapped.token = 'dummy';

      // Encode the wrapped request as JSON string and convert the JSON string back into an ArrayBuffer to replace the request body
      const wrappedJson = JSON.stringify(wrapped);
      request.body = StringUtils.toUTF8(wrappedJson);
    }
  };

  const customResponseFilter = function(type, response, context) {
    // Required utilities provided by Shaka Player
    const StringUtils = shaka.util.StringUtils;
    const Uint8ArrayUtils = shaka.util.Uint8ArrayUtils;

    // Only manipulate license requests
    if (type == shaka.net.NetworkingEngine.RequestType.LICENSE) {
      // This is the wrapped license response - a JSON string - parse it into an object
      const wrappedJsonString = StringUtils.fromUTF8(response.data);
      const wrapped = JSON.parse(wrappedJsonString);

      // This is a base64-encoded version of the raw license (specific to this example)
      // You will need to adapt this part based on your license server requirements
      const rawLicenseBase64 = wrapped.rawLicenseBase64;
      // Decode base64 string into a Uint8Array and replace the response data - raw license will be fed to the Widevine CDM then
      response.data = Uint8ArrayUtils.fromBase64(rawLicenseBase64);

      // Read additional fields from the license server
      // In practice, you could send any license metadata the client might need
      // Here we log what the server sent to the JavaScript console for inspection
      console.log(wrapped);
    }
  };

  const src = {
    dash: 'https://storage.googleapis.com/shaka-demo-assets/sintel-widevine/dash.mpd'
  };

  const settings = {
    licenseKey: 'your-license-key',
    src: src,
    // passing DRM settings
    shakaDrm: {
      servers: {
        'com.widevine.alpha': licenseServer
      }
    },
    shakaCustomRequestFilter: customRequestFilter,
    shakaCustomResponseFilter: customResponseFilter,
    contentMetadata: {
      poster: [
        'https://your-poster-url.jpg' 
      ]
    }
  };

  const elementID = 'rmp';
  const rmp = new RadiantMP(elementID);
  rmp.init(settings);
</script>

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

When using a combined Widevine/PlayReady DRM approach with MPEG-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 and iOS Safari you may also consider using Apple FairPlay DRM.

Player code example:

<!-- Include Radiant Media Player - here we use the optimised build for Shaka player -->
<script src="https://cdn.radiantmediatechs.com/rmp/9.15.19/js/rmp-shaka.min.js"></script>
<!-- Player container element -->
<div id="rmp"></div>
<!-- Set up player configuration options -->
<script>
const src = {
  dash: 'https://media.axprod.net/TestVectors/v7-MultiDRM-SingleKey/Manifest.mpd',
  // here is our AES-128 HLS fallback
  hls: 'https://www.radiantmediaplayer.com/media/rmp-segment/bbb-abr-aes/playlist.m3u8'
};
const settings = {
  licenseKey: 'your-license-key',
  src: src,
  width: 640,
  height: 360,
  contentMetadata: {
    poster: [
      'https://your-poster-url.jpg'
    ]
  },
  dashFirst: true,
  hlsEngine: 'hlsjs',
  // passing DRM settings
  shakaDrm: {
    servers: {
      'com.widevine.alpha': 'https://drm-widevine-licensing.axtest.net/AcquireLicense',
      'com.microsoft.playready': 'https://drm-playready-licensing.axtest.net/AcquireLicense'
    }
  },
  shakaRequestConfiguration: {
    license: {
      headers: {
        'X-AxDRM-Message': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2ZXJzaW9uIjoxLCJjb21fa2V5X2lkIjoiYjMzNjRlYjUtNTFmNi00YWUzLThjOTgtMzNjZWQ1ZTMxYzc4IiwibWVzc2FnZSI6eyJ0eXBlIjoiZW50aXRsZW1lbnRfbWVzc2FnZSIsImtleXMiOlt7ImlkIjoiOWViNDA1MGQtZTQ0Yi00ODAyLTkzMmUtMjdkNzUwODNlMjY2IiwiZW5jcnlwdGVkX2tleSI6ImxLM09qSExZVzI0Y3Iya3RSNzRmbnc9PSJ9XX19.4lWwW46k-oWcah8oN18LPj5OLS5ZU-_AQv7fe0JhNjA' 
      }
    }
  }
};
const rmp = new RadiantMP('rmp');
rmp.init(settings);
</script>

Offline DRM and persistent license support

The player automatically downloads and stores persistent licenses when available. Persistent licenses allow for offline playback of DRM protected content without the need for an Internet connection to access content.

Persistent licenses are supported in:

  • Chrome 64+, Samsung Internet 12+ for Android 6+
  • Chrome 64+ for macOS 10.12+
  • Chrome 64+, Opera 64+, MS Edge 79+ for Windows 10+
  • Chrome 64+ for Chromebooks (ChromeOS)

Persistent licenses are NOT supported in the following environments:

  • Safari (all platforms)
  • Firefox (all platforms)
  • Mobile apps for Android or iOS (Ionic, Flutter, Apache Cordova, WebView)

Note that you will need to use MPEG-DASH streaming to support persistent licenses (PlayReady or Widevine DRM).

For platforms where storage of persistent licenses is not available you will get offline storage of protected content on all DRM-enabled environments, at the cost of needing a network connection at playback time to retrieve licenses.

Changing player source with DRM

If you are using the setSrc API method to change player source with DRM content you could likely want to update the player with new DRM information. This can be done by using the following API methods:

getShakaCustomRequestFilter()

Returns Function the current custom request filter for Shaka player used by Radiant Media Player.

setShakaCustomRequestFilter(shakaCustomRequestFilter)

Takes shakaCustomRequestFilter Function as an input to update the current custom request filter for Shaka player used by Radiant Media Player. This should be used just before using setSrc API method.

getShakaRequestConfiguration()

Returns Object the current request configuration for Shaka player used by Radiant Media Player.

setShakaRequestConfiguration(shakaRequestConfiguration)

Takes shakaRequestConfiguration Object as an input to update the current request configuration for Shaka player used by Radiant Media Player. This should be used just before using setSrc API method.

getShakaDrm()

Returns Object the current DRM configuration for Shaka player used by Radiant Media Player.

setShakaDrm(shakaDrm)

Takes shakaDrm Object as an input to update the current DRM configuration for Shaka player used by Radiant Media Player. This should be used just before using setSrc API method.

Usage example:

<!-- Include Radiant Media Player - here we use the optimised build for Shaka player -->
<script src="https://cdn.radiantmediatechs.com/rmp/9.15.19/js/rmp-shaka.min.js"></script>
<!-- Player container element -->
<div id="rmp"></div>
<!-- Set up player configuration options -->
<script>
  const src = {
    dash: 'https://storage.googleapis.com/shaka-demo-assets/angel-one-widevine/dash.mpd'
  };
  const settings = {
    licenseKey: 'your-license-key',
    src: src,
    width: 640,
    height: 360,
    autoplay: true,
    // passing DRM settings
    shakaDrm: {
      servers: {
        'com.widevine.alpha': 'https://cwip-shaka-proxy.appspot.com/no_auth'
      }
    }
  };
  const rmp = new RadiantMP('rmp');
  rmp.init(settings);
          
  // this setTimeout function just emulate a case where setSrc is called with new DRM information 
  setTimeout(() => {
    console.log(rmp.getShakaDrm());
    rmp.setShakaRequestConfiguration({
      license: {
        headers: {
          'X-AxDRM-Message': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2ZXJzaW9uIjoxLCJjb21fa2V5X2lkIjoiYjMzNjRlYjUtNTFmNi00YWUzLThjOTgtMzNjZWQ1ZTMxYzc4IiwibWVzc2FnZSI6eyJ0eXBlIjoiZW50aXRsZW1lbnRfbWVzc2FnZSIsImtleXMiOlt7ImlkIjoiOWViNDA1MGQtZTQ0Yi00ODAyLTkzMmUtMjdkNzUwODNlMjY2IiwiZW5jcnlwdGVkX2tleSI6ImxLM09qSExZVzI0Y3Iya3RSNzRmbnc9PSJ9XX19.4lWwW46k-oWcah8oN18LPj5OLS5ZU-_AQv7fe0JhNjA'
        }
      }
    });
    rmp.setShakaDrm({
      servers: {
        'com.widevine.alpha': 'https://drm-widevine-licensing.axtest.net/AcquireLicense',
                  }
      }
    );
    rmp.setSrc({
      dash: 'https://media.axprod.net/TestVectors/v7-MultiDRM-SingleKey/Manifest.mpd'
    });
  }, 15000);
</script>
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 3.0 License.

©2015-2024 Radiant Media Player. All Rights Reserved.