ViaEvent DRM integration

Overview

Bradmax player supports custom handler so your app can obtain DRM with custom headers, format/encoding, transport. Necessary data will be provided to your app from player, with it you can obtain DRM license from your DRM server. Then you send back DRM license to player via player API. Setting "provider": “viaEvent” in DRM config will be required.

Configuration

For correct playback player needs:

  1. Configure drm.provider = 'viaEvent'
  2. Attach event listener for proper events DrmLicenseProviderEvent.* (see below). Player trigger it when needs DRM license for decrypting content.
  3. Prepare obtaining license on your app side (on player request from event)
  4. Send back license via JS api jsapi.drm.provide*(keyMessage, license, error) (see below)

DRM configuration object

You need to prepare drm configuration object and set it for each media source object . Each media source points to single HLS, MPEG-DASH, MSSmoothStreaming stream. drm object specification:

Field nameTypeDescription
providerstringKey defining provider. Should be “viaEvent”.

Events

Events dedicated for customisation process of DRM license obtain.

VideoEvent name (string)TypeDescription
DrmLicenseProviderEvent.extRequestWidevineLicensestringPlayer requests application for obtaining new DRM license for Wideviene system.
DrmLicenseProviderEvent.extRequestPlayreadyLicensestringPlayer requests application for obtaining new DRM license for PlayReady system.
DrmLicenseProviderEvent.extRequestFairplayCertificatestringPlayer requests application for DRM server certificate for FairPlay system.
DrmLicenseProviderEvent.extRequestFairplayLicensestringPlayer requests application for obtaining new DRM license for FairPlay system.

API

JavaScript API methods for sending back obtained license:

Method nameInput typeOutput typeDescription
drm.provideWidevineLicense(keyMessage,license,error)ArrayBuffer, ArrayBuffer, ArrayBuffervoidMethod for sending Widevine license obtained by app to player. All fields are JS ArrayBuffer type. Error is optional. If present/defined, then error will be triggered.
drm.providePlayreadyLicense(keyMessage,license,error)ArrayBuffer, ArrayBuffer, ArrayBuffervoidMethod for sending PlayReady license obtained by app to player. All fields are JS ArrayBuffer type. Error is optional. If present/defined, then error will be triggered.
drm.provideFairplayCertificate(certificate,error)ArrayBuffer, ArrayBuffervoidMethod for sending FairPlay server certificate obtained by app to player. All fields are JS ArrayBuffer type. Error is optional. If present/defined, then error will be triggered.
drm.provideFairplayLicense(keyMessage,license,error)ArrayBuffer, ArrayBuffer, ArrayBuffervoidMethod for sending FairPlay license obtained by app to player. All fields are JS ArrayBuffer type. Error is optional. If present/defined, then error will be triggered.

Example for Widevine

<html>
    <body>
        <div style="width: 890px; height: 500px; background: black;" id="PLAYER_DOM_ID"></div>
        <script type="text/javascript">
            var media = {
                    dataProvider: [{
                        title: "Big Buck Bunny DRM",
                        duration: 596.0,
                        source: [
                            {
                                url: "https://wvm.ezdrm.com/demo/stream.mpd",
                                drm: { "provider": "viaEvent" }, // This configures DRM provider for obtaining license from APP using events and player API.
                            }
                        ]
                    }]
            };
            var element = document.getElementById("PLAYER_DOM_ID");
            var player = window.bradmax.player.create(element, media);
            var jsapi = player.modules.JavascriptApi;

            function onWidevineDrmNeeded(event) {
                const keyMessage = event.data.keyMessage;
                console.log('New DRM license requested from player. KeyMessage for obtaining license:', {keyMessage:keyMessage, event:event, media:event.data.media, mediaSource:event.data.mediaSource});

                var licReq = new XMLHttpRequest();
                licReq.open("POST", 'https://widevine-dash.ezdrm.com/proxy?pX=BF9CEB', true);
                //licReq.setRequestHeader('authToken', '123123');
                // Setting "arraybuffer" response type for supporting any binary response.
                licReq.responseType = "arraybuffer";
                licReq.onload = function () {
                   if (licReq.status === 200) {
                       const license = licReq.response;
                       jsapi.drm.provideWidevineLicense(keyMessage, license);
                   } else {
                       // In case of error pass response from sever (array buffer) as last argument.
                       const errorMessage = licReq.response;
                       jsapi.drm.provideWidevineLicense(keyMessage, null, errorMessage);
                   }
                };
                // Use same handler for error.
                licReq.onerror = licReq.onload;
                licReq.send(keyMessage);
            });

            // Notice: In case of auth error no popup error is shown in player. For such cases APP closes the player and redirect
            // user to login view or shows dedicated view about system error.
            function onAuthAccessError(event) {
                console.error("Authentication / Access Denied error occurred.", event);
            }

            // Attach listeners on so player can ask APP using player for license. APP will provide license
            // to player via player API.
            jsapi.add("DrmLicenseProviderEvent.extRequestWidevineLicense", onWidevineDrmNeeded);
            jsapi.add("VideoEvent.drmAuthenticationError", onAuthAccessError);
        </script>
    </body>
</html>

Example for Fairplay

<html>
    <body>
        <div style="width: 890px; height: 500px; background: black;" id="PLAYER_DOM_ID"></div>
        <script type="text/javascript">
            var media = {
                    dataProvider: [{
                        title: "Drop DRM video",
                        duration: 36.0,
                        source: [
                            {
                                url: "https://fps.ezdrm.com/demo/video/ezdrm.m3u8",
                                drm: { "provider": "viaEvent" }, // This configures DRM provider for obtaining license from APP using events and player API.
                            }
                        ]
                    }]
            };
            var element = document.getElementById("PLAYER_DOM_ID");
            var player = window.bradmax.player.create(element, media);
            var jsapi = player.modules.JavascriptApi;

            function onFairplayCertNeeded(event) {
                console.log('New FariPlay DRM certificate requested from player.', {event:event});

                var certReq = new XMLHttpRequest();
                certReq.open("GET", 'https://fps.ezdrm.com/demo/video/fps.cer', true);
                // Setting "arraybuffer" response type for supporting any binary response.
                certReq.responseType = "arraybuffer";
                certReq.onload = function () {
                    if (certReq.status === 200) {
                        const cert = certReq.response;

                        // Provide certificate via player API.
                        // Certificate has to be passed as JavaScript ArrayBuffer.
                        jsapi.drm.provideFairplayCertificate(cert);
                    } else {
                        // In case of error pass response from sever (array buffer) as last argument.
                        // Provide certificate via player API.
                        const errorMessage = licReq.response;
                        jsapi.drm.provideFairplayLicense(null, errorMessage);
                    }
                };
                // Use same handler for error.
                certReq.onerror = certReq.onload;
                certReq.send();
            }

            function onFairplayDrmNeeded(event) {
                const keyMessage = event.data.keyMessage;
                const keySession = event.data.keySession;
                console.log('New Fairplay DRM license requested from player. KeyMessage for obtaining license:', {keyMessage:keyMessage, keySession:keySession, event:event, media:event.data.media, mediaSource:event.data.mediaSource});

                var licReq = new XMLHttpRequest();
                licReq.open("POST", 'https://fps.ezdrm.com/api/licenses/09cc0377-6dd4-40cb-b09d-b582236e70fe', true);
                // Set custom headers, body encoding if needed.
                // licReq.setRequestHeader('authToken', '123123');
                // Setting "arraybuffer" response type for supporting any binary response.
                licReq.responseType = "arraybuffer";
                licReq.onload = function () {
                   if (licReq.status === 200) {
                       const license = licReq.response;

                       // Providing license via API. keyMessage is important - it works like unique ID for license request.
                       // License has to be passed as JavaScript ArrayBuffer.
                       jsapi.drm.provideFairplayLicense(keyMessage, license);
                   } else {

                       // In case of error pass response from sever (array buffer) as last argument.
                       // keyMessage is important - it works like unique ID for license request.
                       const errorMessage = licReq.response;
                       jsapi.drm.provideFairplayLicense(keyMessage, null, errorMessage);
                   }
                };
                // Use same handler for error.
                licReq.onerror = licReq.onload;
                licReq.send(keyMessage);
            }

            // Notice: In case of auth error no popup error is shown in player. For such cases APP closes the player and redirect
            // user to login view or shows dedicated view about system error.
            function onAuthAccessError(event) {
                console.error("Authentication / Access Denied error occurred.", event);
            }

            // Attach listeners on so player can ask APP using player for license. APP will provide license
            // to player via player API.
            jsapi.add("DrmLicenseProviderEvent.extRequestFairplayCertificate", onFairplayCertNeeded);
            jsapi.add("DrmLicenseProviderEvent.extRequestFairplayLicense", onFairplayDrmNeeded);
            jsapi.add("VideoEvent.drmAuthenticationError", onAuthAccessError);
        </script>
    </body>
</html>