Skip to main content
Skip table of contents

Callback mode

To support multi-DRM through SSP, the React Native player handles licence management internally within the code. In some setups, to play an encrypted content item, you might want to manage content licences through your own mechanisms to generate a licence and share it with the React Native player. You can achieve this by creating your implementation for licence retrieval in the form of a JS promise and providing it to the React Native Player.

Callback mode is currently only available for Web Browsers and browser-based platforms such as Connected TVs.

Multi-Session

The player ensures that a licence request callback is called for each new KeyId found in playback if the OTVSDK is configured using the multiSession  flag as true. In callback mode, this configuration enables the key rotation feature to retrieve the licence through license request callbacks for each key change in the stream (along with the pre-delivered licences). This configuration is utilised only once during the first mount of the OTVPlayer in the Apps lifecycle when initialising the SDK, and further changes to this will not be tracked.

Click here to see how to set the multiSession flag in code.
JS
//Set the multiSession flag as true in OTVSDK.
  const isMounted = useRef(false);
  if (isMounted.current === false) {
    OTVSDK.multiSession = true;
    isMounted.current = true
  }

  return (
       ...
       <OTVPlayer
        ref={otvplayerInstance}
        source={content.source}
        progressUpdateInterval={1}
        autoplay={true}
        muted={muted}
        volume={volume}
        onLoad={(event: OnLoadParam) => {
          setMessage("onLoad received");
        }}

        ...

        onLicenseRequest={getWidevineLicense}

        ...

       />

      ...
  );

Example code

The following describes how to prepare your implementation of a callback promise and provide it to the player. Examples for each DRM system are provided, essentially having the same functionality. 

  • CallbackModeFairPlay.tsx

  • CallbackModePlayReady.tsx

  • CallbackModeTVKey.tsx

  • CallbackModeWidevine.tsx

  • CallbackModeMultiSession.tsx

These examples provide the typical implementation of callback mode for an SSP license server.

The React Native player provides a callback property: onLicenseRequest(keySystem:String, source:Object, requestPayload:ArrayBurrer, licenseRequestType:String). If the application sets this, it will be called whenever the player wants the application to provide any of the following:

  • Licence data

  • Certificate data

  • Renewed licence data

The App should return a promise from this callback. Once the promise is fulfilled, the data provided should be an ArrayBuffer of the reply from the licence server.

  • If the promise is rejected, playback will fail and an onError event will be triggered.

  • The player will discard the last promise if a channel/content change is requested before fulfilling or rejecting a promise.

Apps should ensure not to accept/reject promises made for the previous content (if a new request was made).

Please refer to the API documentation regarding the parameters passed in the callback.

Using the CallbackModeWidevine example as a reference, define and implement the licence-fetching promise returned by the getWidevineLicense() method of type OnLicenseRequest :

Click here to see the example code.
JS
  const getWidevineLicense: OnLicenseRequest = (keySystem, shakaSource, requestPayload, messageType) => {
    const { licenseURL, token, certificateURL } = content.license;
    let headers = {
      Accept: "application/octet-stream",
      "Content-Type": "application/octet-stream"
    };
    let reqUrl = messageType === 'certificate-request' ? certificateURL : licenseURL;
    return new Promise(function resolver(resolve, reject) {

      let xhr = new XMLHttpRequest();
      xhr.open("POST", reqUrl, true);
      xhr.responseType = "arraybuffer";
      for (let key in headers) {
        if (headers.hasOwnProperty(key)) {
          xhr.setRequestHeader(key, headers[key]);
        }
      }

      xhr.onload = function onload() {
        if (xhr.status === 200) {
          try {
            resolve(new Uint8Array(xhr.response));
          } catch (err) {
            reject("Invalid widevine License:" + err);
          }
        } else {
          reject("Failed to receive license, HTTP status:" + xhr.status);
        }
      };

      xhr.onerror = function onerror(err) {
        reject("Error on license request");
      };
      const tokenKey = "nv-authorizations";
      xhr.setRequestHeader(tokenKey, token);
      xhr.send(requestPayload);
    });
  };

The promise returned by this method returns a byte array (Uint8Array) of the response from the SSP licence server if successful ( resolve ), or an error string if the request failed ( reject ). The getWidevineLicense function is then passed as the onLicenseRequest callback property during the OTVPlayer object's construction.

Mixed mode

Mixed mode is now supported, so OTVPlayer no longer needs to be unmounted and remounted to change between callback and non-callback mode:

  • A content item can be played in callback mode by passing the onLicenseRequest property, and then change to non-callback mode to play another content item by not passing onLicenseRequest.

  • Alternatively, a content item can be played in non-callback mode by not passing onLicenseRequest and then change to callback mode by passing the onLicenseRequest.

Click here to see the example code.
JS
  return (
       ...
       <OTVPlayer
        ref={otvplayerInstance}
        source={content.source}
        progressUpdateInterval={1}
        autoplay={true}
        muted={muted}
        volume={volume}
        onLoad={(event: OnLoadParam) => {
          setMessage("onLoad received");
        }}

        ...

        onLicenseRequest={getWidevineLicense}

        ...

       />

      ...
  );
JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.