DRM

Playing digital rights management (DRM)-protected content requires DRM configuration, and the details differ by DRM solution. PRESTOplay supports several DRM solutions out of the box through preconfigured DRM environments, and you can also register a custom environment for full control over license acquisition.

Note

Your website must be served over HTTPS to play DRM-protected content. HTTPS is not required when testing on localhost.

See also Persistent DRM licenses for offline playback of DRM-protected content.

DRM with DRMtoday

The SDK includes a preconfigured DRMtoday environment. To use it, pass DRM configuration under the drm key in the Player.open call. Set the environment name to DRMtoday. A DRMtoday_STAGING environment is also available for testing.

player.open({
  source: 'https://example.com/Manifest.mpd',
  drm: {
    env: 'DRMtoday',
    customData: {
      userId: 'purchase',
      sessionId: 'p0',
      merchant: 'six',
    }
  }
});

Specific properties of the DRMtoday environment, set under drm.customData:

Property

Required

Description

userId

Yes

The userId parameter sent to DRMtoday.

sessionId

Yes

The sessionId parameter sent to DRMtoday.

merchant

Yes

The merchant parameter.

authToken

No

The DRMtoday authentication token used for the license request when upfront authentication is used.

assetId

No

The asset ID of the content the license is requested for. Not required in all setups, but useful in some.

variantId

No

The variant ID of the content the license is requested for. Not required in all setups, but useful in some.

widevineVideoRobustness

No

Widevine video robustness levels. Default: [HW_SECURE_ALL, HW_SECURE_DECODE, HW_SECURE_CRYPTO, SW_SECURE_DECODE, SW_SECURE_CRYPTO]. See drm.WidevineRobustnessLevel.

widevineAudioRobustness

No

Widevine audio robustness levels. Default: [SW_SECURE_DECODE, SW_SECURE_CRYPTO]. See drm.WidevineRobustnessLevel.

widevineDistinctiveIdentifierRequired

No

Whether a persistent distinctive identifier is required. Default: false.

widevinePersistentStateRequired

No

Whether the ability to persist state is required. Default: false.

playReadyVideoRobustness

No

PlayReady video robustness levels. Default: [3000, 2000, 150]. See drm.PlayreadyRobustnessLevel.

playReadyAudioRobustness

No

PlayReady audio robustness levels. Default: [2000, 150]. See drm.PlayreadyRobustnessLevel.

serverCertificate

No

The Widevine server certificate. DRMtoday selects the right certificate by default; use this to select one explicitly. See drm.DrmToday.WidevineCertificates.

DRM with DRMtoday Onboard

OnBoard is the offline architecture for DRMtoday. It lets you install a DRMtoday server on a private network — for example, on board a bus, plane, train, or ship.

Enable OnBoard by defining an environment name and the URL of your local DRMtoday OnBoard server. The SDK registers a new environment automatically using the specified name and URL. We suggest the name DRMtodayOnBoard to avoid a collision with other predefined environments. You can also pass other custom data, such as a user ID or session ID.

Specific properties of the DRMtoday OnBoard environment, set under drm.customData:

Property

Required

Description

baseUrl

Yes

The base URL of the DRMtoday Onboard server.

widevineUrl

No

Appended to the base URL to form the Widevine URL. Default: widevine.

playreadyUrl

No

Appended to the base URL to form the PlayReady URL. Default: playready.

fairplayUrl

No

Appended to the base URL to form the FairPlay URL. Default: fairplay.

widevineVideoRobustness

No

Widevine video robustness levels. Default: [SW_SECURE_DECODE, undefined]. See drm.WidevineRobustnessLevel.

widevineAudioRobustness

No

Widevine audio robustness levels. Default: [SW_SECURE_CRYPTO, undefined]. See drm.WidevineRobustnessLevel.

widevineDistinctiveIdentifierRequired

No

Whether a persistent distinctive identifier is required. Default: false.

widevinePersistentStateRequired

No

Whether the ability to persist state is required. Default: false.

playReadyVideoRobustness

No

PlayReady video robustness levels. Default: undefined. See drm.PlayreadyRobustnessLevel.

playReadyAudioRobustness

No

PlayReady audio robustness levels. Default: undefined. See drm.PlayreadyRobustnessLevel.

serverCertificate

No

The Widevine server certificate. If unset, the SDK uses its default certificate. Set to null to fetch the certificate from the Widevine server, a string to use drm.DrmToday.WidevineCertificates, or a Uint8Array to use it directly as the certificate.

Import the DRMtoday Onboard component:

import "@castlabs/prestoplay/cl.onboard";

Minimal example:

const player = new clpp.Player(...);

player.open({
  source: 'https://example.com/Manifest.mpd',
  drm: {
    env: 'DRMtodayOnboard',
    customData: {
      baseUrl: 'offlineDRMTodayServerUrl',
    }
  }
});

More complex example:

const player = new clpp.Player(...);

player.open({
  source: 'https://example.com/Manifest.mpd',
  drm: {
    env: 'DRMtodayOnboard',
    customData: {
      baseUrl: 'offlineDRMTodayServerUrl',
      widevineUrl: 'widevine',
      playreadyUrl: 'playready',
      fairplayUrl: 'fairplay',
      serverCertificate: null, // Forces fetching the certificate from the Widevine server
    }
  }
});

DRM with header-based DRM environment

Integrate a custom DRM service with the configurable header-based DRM environment, available from the core module. Pass backend URLs and custom request headers, such as the authentication header:

player.open({
  drm: {
    env: 'HeaderDrm',
    customData: {
      widevineLicenseUrl: '...',
      widevineVideoRobustness: [
        clpp.drm.WidevineRobustnessLevel.SW_SECURE_DECODE,
        undefined
      ],
      widevineAudioRobustness: [
        clpp.drm.WidevineRobustnessLevel.SW_SECURE_CRYPTO,
        undefined
      ],
      playReadyLicenseUrl: '...',
      playReadyVideoRobustness: [
        clpp.drm.PlayreadyRobustnessLevel.SL3000
      ],
      playReadyAudioRobustness: [
        clpp.drm.PlayreadyRobustnessLevel.SL2000
      ],
      fairPlayLicenseUrl: '...',
      fairPlayCertificateUrl: '...',
      fairPlayContentIdStrategy:
        clpp.drm.HeaderDrm.ContentIdStrategy.FULL_SKD,
      serverCertificate: new Uint8Array(...),
      headers: {
        'my-auth-header': '...'
      }
    }
  }
});

Specific properties of the header-based DRM environment, set under drm.customData:

Property

Required

Description

widevineLicenseUrl

Yes

The Widevine license URL.

playReadyLicenseUrl

Yes

The PlayReady license URL.

fairPlayLicenseUrl

Yes

The FairPlay license URL.

fairPlayCertificateUrl

Yes

The FairPlay certificate URL.

fairPlayContentIdStrategy

No

The FairPlay content ID extraction strategy. Default: FULL_SKD.

headers

No

A dictionary of custom request headers.

widevineVideoRobustness

No

Widevine video robustness levels. Default: [SW_SECURE_DECODE, undefined]. See drm.WidevineRobustnessLevel.

widevineAudioRobustness

No

Widevine audio robustness levels. Default: [SW_SECURE_CRYPTO, undefined]. See drm.WidevineRobustnessLevel.

widevineDistinctiveIdentifierRequired

No

Whether a persistent distinctive identifier is required. Default: false.

widevinePersistentStateRequired

No

Whether the ability to persist state is required. Default: false.

playReadyVideoRobustness

No

PlayReady video robustness levels. Default: [SL3000]. See drm.PlayreadyRobustnessLevel.

playReadyAudioRobustness

No

PlayReady audio robustness levels. Default: [SL2000]. See drm.PlayreadyRobustnessLevel.

serverCertificate

No

No server certificate is selected by default. Provide the Widevine server certificate ahead of time as a Uint8Array.

DRM with Verimatrix VCAS Ultra environment

Import the component:

import "@castlabs/prestoplay/cl.verimatrix";

Open the stream with configuration:

const player = new clpp.Player(...);

player.open({
  source: 'https://your.server/encrypted-asset.mpd',
  drm: {
    env: 'VerimatrixVCAS',
    customData: {
      deviceId: "myDeviceID",
      widevineLicenseUrl: 'https://widevine.keyserver:port/',
      playReadyLicenseUrl: 'https://playready.keyserver:port/',
      fairPlayLicenseUrl: 'https://fairplay.keyserver:port/',
      fairPlayCertificateUrl: 'https://fairplay.cert/fairplay.cer'
    }
  }
});

Specific VerimatrixVcasConfiguration properties of the Verimatrix VCAS Ultra DRM environment, set under drm.customData:

Property

Required

Description

deviceId

Yes

The device’s Verimatrix unique identifier (VUID).

authenticator

No

Optional third-party authentication to the Subscriber Management System (SMS).

licenseRequestVuidLocation

No

Method for passing deviceId and authenticator (if defined) to the license server. Default: QUERY_STRING. See verimatrix.Vcas.LicenseRequestVuidLocation.

httpHeaderNames

No

Custom HTTP header names for passing deviceId and authenticator to the license server. Used only when licenseRequestVuidLocation is HTTP_HEADER. See verimatrix.Vcas.LicenseRequestHttpHeader.

widevineLicenseUrl

Yes

The Widevine license server URL.

playReadyLicenseUrl

Yes

The PlayReady license server URL.

fairPlayLicenseUrl

Yes

The FairPlay license server URL.

fairPlayCertificateUrl

Yes

The FairPlay certificate URL.

fairPlayAssetIdStrategy

No

The FairPlay asset ID acquisition strategy. Default: KEYID. See verimatrix.Vcas.FairPlayAssetIdStrategy.

fairPlaySiteId

No

The unique identifier of the site the subscriber is associated with. Used only together with fairPlayAssetIdStrategy set to CONTENTID_SITEID.

Use the demo player configuration form to generate and test a configuration for Verimatrix VCAS Ultra DRM: select Verimatrix VCAS Ultra as the DRM environment and fill in the form with your data.

For more details, see VerimatrixVcasConfiguration and verimatrix.Vcas.

DRM with custom DRM environment

Create a custom DRM environment when you need full control over the license acquisition process.

Create a drm.DrmEnvironment instance, configure it for the DRM systems you need, and register it globally with drm.registerDrmEnvironment. For the possible DRM system configurations, see drm.DrmEnvironment#setDrmSystem.

A custom DRM environment can look like this:

const environment = new clpp.drm.DrmEnvironment('myDrm');
environment.setDrmSystem(clpp.drm.KeySystem.WIDEVINE, {
  licenseUrl: '...',
});
environment.setDrmSystem(clpp.drm.KeySystem.FAIRPLAY, {...});
environment.setDrmSystem(clpp.drm.KeySystem.PLAYREADY, {...});

clpp.drm.registerDrmEnvironment(environment);

To use a custom DRM environment, pass its name in the Player.open call:

const player = new clpp.Player(...);
player.open({
  source: 'https://example.com/Manifest.mpd',
  drm: {
    env: 'myDrm', // the custom DRM environment name
    customData: {
      // optional data the custom DRM environment might need
    }
  }
});

CDM configuration

Depending on the device and platform, a content decryption module (CDM) might require specific configuration to work. The distinctiveIdentifierRequired and persistentStateRequired flags must be true on some platforms and false on others.

Use the CDM probe page to check which CDMs and CDM configurations your browser supports.

With a custom DRM environment, configure these flags as follows:

const environment = new clpp.drm.DrmEnvironment('myDrm');
environment.setDrmSystem(clpp.drm.KeySystem.WIDEVINE, {
  licenseUrl: '...',
  distinctiveIdentifierRequired: true,
  persistentStateRequired: true,
});

clpp.drm.registerDrmEnvironment(environment);

You can also pass them as Widevine custom data:

player.open({
  source: 'https://example.com/Manifest.mpd',
  drm: {
    env: 'DRMtoday',
    customData: {
      userId: 'purchase',
      widevineDistinctiveIdentifierRequired: true,
      widevinePersistentStateRequired: true,
    }
  }
});

Customizing license requests

If your license server needs more than a built-in DRM environment offers, such as a token fetched at request time, a custom request body, a wrapped license response, or a custom FairPlay content ID, add modifiers to a custom DRM environment. See Customizing license requests.

Multiple DRM environments

When using multiple DRM solutions, give each DRM environment a unique name. Reusing a name can cause unspecified behavior, especially when multiple player instances are active at the same time.

Encrypted Media Extensions API

PRESTOplay uses the Encrypted Media Extensions (EME) API to decrypt content. Some platforms provide different versions or implementations of this API, and the SDK automatically selects the most suitable one.

Override this selection with the drm.emeApi configuration option, passing a value from drm.eme.EmeFactory.Apis:

const player = new clpp.Player('video', {
  drm: {
    emeApi: clpp.drm.eme.EmeFactory.Apis.APPLE,
  },
});

DRM providers and FairPlay

To use FairPlay with the MSE player on Safari alongside the default standard EME, your DRM provider must support it. DRMtoday provides full support for this scenario out-of-the-box.

Previous topic: Errors