Playing DRMToday / Castlabs protected content with the Web Player SDK

Overview

If you are not sure what DRM is, you want have an overview and get started, please have a look at our DRM Setup Guide.

Nearly every license provider, such as Irdeto or EZDRM, requires a few special information being sent to the DRM license server, or responds with a proprietary format. Instead of integrating a few license providers into the core of our player, we decided to provide necessary configuration options via the player configuration.

Widevine

Spec Conform option (recommended)

The recommended approach is to append ?specConform=true to the Widevine License server URL, for example https://lic.staging.drmtoday.com/license-proxy-widevine/cenc/?specConform=true

const source = {
  dash: 'DASH_MANIFEST_URL',
  drm: {
    widevine: {
      LA_URL: 'WIDEVINE_LICENSE_SERVER_URL?specConform=true',
      headers: { 'x-dt-custom-data': 'BASE64_ENCODED_CUSTOMDATA' },
    }
  }
}

Proprietary option

DRMtoday/Castlabs also have a custom implementation, which wraps the Widevine license. To use that, a config like the below is needed:

const source = {
  dash: 'DASH_MANIFEST_URL',
  drm: {
    widevine: {
      LA_URL: 'WIDEVINE_LICENSE_SERVER_URL',
      headers: { 'x-dt-custom-data': 'BASE64_ENCODED_CUSTOMDATA' },
      prepareLicense: licenseObj => {
        const license = {license: licenseObj.license};

        try {
          const drmTodayObj = JSON.parse(String.fromCharCode.apply(null, licenseObj.license));
          if (drmTodayObj && drmTodayObj.status && drmTodayObj.license) {
            if (drmTodayObj.status === 'OK') {
              const str = window.atob(drmTodayObj.license);
              const bufView = new Uint8Array(new ArrayBuffer(str.length));
              for (let i = 0; i < str.length; i++) {
                bufView[i] = str.charCodeAt(i);
              }
              license.license = bufView;
            } else {
              throw 'DRMtoday license not okay';
            }
          } else {
            throw 'no valid DRMtoday license';
          }
        } catch (e) {
          throw 'no valid DRMtoday license';
        }
        return license;
      }
    }
  }
}

Please replace the following placeholders in the code:

  • DASH_MANIFEST_URL: The URL to the DASH manifest (MPD) file.
  • WIDEVINE_LICENSE_SERVER_URL: The URL to DRMtoday's Widevine license server.
  • BASE64_ENCODED_CUSTOMDATA: The base64 encoded custom data that DRMtoday expects in license requests.

PlayReady

const source = {
  dash: 'DASH_MANIFEST_URL',
  drm: {
    playready: {
      LA_URL: 'PLAYREADY_LICENSE_SERVER_URL',
      headers: {
        'x-dt-custom-data': 'BASE64_ENCODED_CUSTOMDATA'
      },
    }
  }
}

Please replace the following placeholders in the code:

  • DASH_MANIFEST_URL: The URL to the DASH manifest (MPD) file.
  • PLAYREADY_LICENSE_SERVER_URL: The URL to DRMtoday's Playready license server.
  • BASE64_ENCODED_CUSTOMDATA: The base64 encoded custom data that DRMtoday expects in license requests.

FairPlay

const source = {
  hls: 'HLS_MANIFEST_URL',
  drm: {
    fairplay: {
      LA_URL: 'FAIRPLAY_LICENSE_SERVER_URL',
      certificateURL: 'FAIRPLAY_CERTIFICATE_SERVER_URL',
      headers: { 'x-dt-custom-data': 'BASE64_ENCODED_CUSTOMDATA' },
      prepareMessage : event => `spc=${encodeURIComponent(event.messageBase64Encoded)}`,
      prepareContentId: contentId => {
        const pattern='skd://drmtoday';
        const idx = contentId.indexOf(pattern);
        let parameters = '';
        
        if (idx > -1) {
          parameters = contentId.substring(idx + pattern.length);
          parameters = parameters.replace(/assetid/gi, 'assetId');
          parameters = parameters.replace(/variantid/gi, 'variantId');
        }
        return parameters
      },
      useUint16InitData: true,
    }
  }
}

Please replace the following placeholders in the code:

  • HLS_MANIFEST_URL: The URL to the HLS Multivariant Playlist (M3U8) file.
  • FAIRPLAY_LICENSE_SERVER_URL: The URL to DRMtoday's Fairplay license server.
  • FAIRPLAY_CERTIFICATE_SERVER_URL: The URL to retrieve the Fairplay certificate.
  • BASE64_ENCODED_CUSTOMDATA: The base64 encoded custom data that DRMtoday expects in license requests.

Complete example for Widevine, PlayReady, Access and FairPlay

const source = {
  dash: 'DASH_MANIFEST_URL',
  hls: 'HLS_MANIFEST_URL',
  drm: {
    widevine: {
      LA_URL: 'WIDEVINE_LICENSE_SERVER_URL',
      headers: { 'x-dt-custom-data': 'BASE64_ENCODED_CUSTOMDATA' },
      prepareLicense: licenseObj => {
        const license = {license: licenseObj.license};

        try {
          const drmTodayObj = JSON.parse(String.fromCharCode.apply(null, licenseObj.license));
          if (drmTodayObj && drmTodayObj.status && drmTodayObj.license) {
            if (drmTodayObj.status === 'OK') {
              const str = window.atob(drmTodayObj.license);
              const bufView = new Uint8Array(new ArrayBuffer(str.length));
              for (let i = 0; i < str.length; i++) {
                bufView[i] = str.charCodeAt(i);
              }
              license.license = bufView;
            } else {
              throw 'DRMtoday license not okay';
            }
          } else {
            throw 'no valid DRMtoday license';
          }
        } catch (e) {
          throw 'no valid DRMtoday license';
        }
        return license;
      }
    },
    playready: {
      LA_URL: 'PLAYREADY_LICENSE_SERVER_URL',
      headers: {
        'x-dt-custom-data': 'BASE64_ENCODED_CUSTOMDATA'
      },
    },
    fairplay: {
      LA_URL: 'FAIRPLAY_LICENSE_SERVER_URL',
      certificateURL: 'FAIRPLAY_CERTIFICATE_SERVER_URL',
      headers: { 'x-dt-custom-data': 'BASE64_ENCODED_CUSTOMDATA' },
      prepareMessage : event => `spc=${encodeURIComponent(event.messageBase64Encoded)}`,
      prepareContentId: contentId => {
        const pattern='skd://drmtoday';
        const idx = contentId.indexOf(pattern);
        let parameters = '';
        
        if (idx > -1) {
          parameters = contentId.substring(idx + pattern.length);
          parameters = parameters.replace(/assetid/gi, 'assetId');
          parameters = parameters.replace(/variantid/gi, 'variantId');
        }
        return parameters
      },
      useUint16InitData: true,
    }
  }
}

Please replace the following placeholders in the code:

  • DASH_MANIFEST_URL: The URL to the DASH manifest (MPD) file.
  • HLS_MANIFEST_URL: The URL to the HLS Multivariant Playlist (M3U8) file.
  • WIDEVINE_LICENSE_SERVER_URL: The URL to DRMtoday's Widevine license server.
  • PLAYREADY_LICENSE_SERVER_URL: The URL to DRMtoday's Playready license server.
  • FAIRPLAY_LICENSE_SERVER_URL: The URL to DRMtoday's Fairplay license server.
  • FAIRPLAY_CERTIFICATE_SERVER_URL: The URL to retrieve the Fairplay certificate.
  • BASE64_ENCODED_CUSTOMDATA: The base64 encoded custom data that DRMtoday expects in license requests.