Skip to content

Integration DRM (NEW)

Stefano Gottardo edited this page Sep 26, 2024 · 25 revisions

To play DRM-protected content is required, in addition to the standard properties described on Integration page, configure the DRM(s) to be used.

Let's start by saying that a manifest (e.g. DASH, HLS, ...) can support one or more DRM's, but a device (operative system) may support only some DRM's, moreover this add-on has some limitations based on the operative system used, see also matrix scheme of supported DRM's on the wiki main page.

The choice of the DRM will have to be handled by the add-on or playlist that starts the playback, by taking into account the variables mentioned earlier. However an implementation to handle DRM choice automatically is planned in the development roadmap.

Widevine CDM note: For all operative systems other than Android is required the installation of Widevine library, not included with this add-on. To handle the library installation automatically we suggest to use InputStream Helper add-on.

How to configure DRM's

To configure the DRM's you can use one of these three methods:

🟠old properties - Deprecated advanced method [from Kodi v18 to v22] [click to expand]

Available from Kodi 18 to Kodi 22

This is the old advanced method that makes use of multiple properties. Has been deprecated on Kodi v22.

Recommendations: We suggest to use this old method with older versions of Kodi until to v21.
Starting with Kodi v22 we suggest the use of the new "drm" property interface. If instead you don't need of an advanced method, you can use directly the "drm_legacy" property starting from Kodi v21.

Open this x page to learn how to use the old properties.

The support of this old method will be removed in future versions of Kodi.


🟠inputstream.adaptive.drm_legacy - Simple method to configure a single DRM [Kodi v21+] [click to expand]

Available from v.21.5.0 / Kodi 21

The simple way to configure a DRM can be used for cases where the provider does not require advanced configurations such as wrappers, certificate, etc... it can configure a single DRM, that will have the higher priority (over others DRM's, if any on the manifest).

The expected value is a string, which can be extended with 2 more optional pipes | as required:
[DRM KeySystem] | [License server URL or KeyId's] | [License server headers]

Template fields:

  • [DRM Key System]
    The Key System of the DRM to configure, the supported Key System strings are shown in the table above.

  • [License server URL or KeyId's]
    Widevine DRM: its mandatory to specify the URL of the license server.
    ClearKey DRM: if the manifest does not embed the license server url, mandatory is specify the license server URL, or KID/KeyId's pairs for the decryption string must be composed as follow: kid1:key1,kid2:key2,kid3:key3,... where the values are in HEX format.

  • [License server headers]
    Allow you to add custom HTTP headers for the license HTTP request. With some providers it may be necessary to avoid a server rejection of the HTTP request.
    We suggest to URL encode the headers values. The headers string must follow the scheme: param1=value1&param2=value2

Example for Widevine:

# Flat string example
listitem.setProperty('inputstream.adaptive.drm_legacy', 'com.widevine.alpha|https://license.server.com/licenserequest|User-Agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F106.0.0.0+Safari%2F537.36')

# Constructed string example (recommended)
license_headers = {
    'Content-Type': 'application/octet-stream',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/109.0',
}
from urllib.parse import urlencode
drm_config = {  # Keeping items in order
    'DRM KeySystem': 'com.widevine.alpha'
    'License server url': 'https://license.server.com/licenserequest',
    'License headers': urlencode(license_headers)
}
listitem.setProperty('inputstream.adaptive.drm_legacy', '|'.join(drm_config.values()))

Example for PlayReady:

listitem.setProperty('inputstream.adaptive.drm_legacy', 'com.microsoft.playready')

Example for ClearKey:

# KeyId's provided by manifest:
listitem.setProperty('inputstream.adaptive.drm_legacy', 'org.w3.clearkey')
# KeyId's provided by property:
listitem.setProperty('inputstream.adaptive.drm_legacy', 'org.w3.clearkey|000102030405060708090a0b0c0d0e0f:00112233445566778899aabbccddeeff')
# License URL provided by property: (supported from v21.5.3)
listitem.setProperty('inputstream.adaptive.drm_legacy', 'org.w3.clearkey|https://www.licenseserver.com/AcquireLicense/')


🟠inputstream.adaptive.drm - Advanced method to configure one or more DRM's [Kodi v22+] [click to expand]

Available from v.22.x.x / Kodi 22

WIP NOTICE: This new property is under development and does not yet support multiple DRM configurations, just a single one.

The advanced method allows you to configure multiple DRM's at same time with more complex parameters. The choice of DRM for stream playback will be selected according to the DRM's supported by the manifest and the DRM's supported by the device in use. This can be adjusted by using priorities.

The expected value is a json converted as string. The base scheme is structured by a dictionary, where the key is a Key System string, and the value is a dictionary with most of the time optionals parameters, as in the following example:

# Brief example for python, full examples on relative chapter
drm_configs = {
    # This is Widevine DRM Key System
    "com.widevine.alpha": {
        "license": {
            "server_url": "https://theserverurl.com"
        }
    }
}
list_item.setProperty('inputstream.adaptive.drm', json.dumps(drm_configs))

You can specify a DRM Key System (see supported list above), or "none" value. The "none" value is reserved for special cases such as HLS encryption (e.g. AES-128) which can be used in order to configure these specific use cases (see chapter examples).

Mandatory parameters for DRM's

The following DRM's require some mandatory parameters:

  • Widevine DRM: mandatory is the license/server_url parameter.
  • ClearKey DRM: if the manifest does not embed the license server url, mandatory is the license/server_url or license/keyids parameter.

Configuration parameters

To configure a DRM you can use following parameters, each parameter is optional unless otherwise specified, or required by your service provider.

🔵 priority - The DRM priority over others DRM's


Allows this DRM to be given a higher priority than the others (if multiple). This can be useful when a manifest support more DRM's and the operating system in use supports all of them. So for example if a specific DRM provides higher resolutions, you can prioritize that DRM over the others.

The value can start from 1 to "n" where lower number have the higher priority. Invalid values are: 0 or a same value used on multiple DRM's.

DATA TYPE: int
EXAMPLE: "priority": 1

🔵 license - To configure the license request


The configuration for the license request is strictly dependent on the streaming services requirements so we cannot provide guidelines for every use case, so we just provide generalities.

DATA TYPE: dict

The license dictionary support these parameters:

🟢 server_certificate - To set a license server certificate


Specifies a server certificate to be used to encrypt messages to the license server. Must be encoded as Base64.

DATA TYPE: str
EXAMPLE: "server_certificate": "base64 data"

🟢 server_url - To set a license server URL


Specifies the license server URL where make the license HTTP request. This parameter can also be used to override the license server url provided by the manifest data.

For Widevine DRM: In the URL is possible optionally inject the DRM challenge (key request) by using following placeholders:

  • {CHA-B64U} To inject to the URL the DRM Challenge as base64, URL encoded
  • {CHA-MD5} To inject to the URL the DRM Challenge hashed as MD5

DATA TYPE: str
EXAMPLE: "server_url": "http://the-server-url.com/challenge/{CHA-B64U}"

🟢 use_http_get_request - Force HTTP GET for the license request


By enabling this parameter will force an HTTP GET request to request the license (by default the request is done with an HTTP POST request).

DATA TYPE: bool
EXAMPLE: "use_http_get_request": True

🟢 req_headers - To set the HTTP headers for the license request


Allows to add the HTTP headers to the license HTTP request, values of headers must be URL encoded (see also chapter "examples").

DATA TYPE: str
EXAMPLE: "req_headers": "param1=valueUrlEncoded1&param2=valueUrlEncoded2"

🟢 req_params - To set parameters to the license URL


Allows to append to the license URL, some URL parameters.

DATA TYPE: str
EXAMPLE: "req_params": "/one/two/three-path"

🟢 req_data - To customize the data for the license request


Allows to provide custom data for the license request. The data must be base 64 encoded.

It is usually used when a license requet/response makes use of wrappers, so the data structure is customized with other types of formats by the service provider, such as JSON, BASE64, etc... (see wrapper/unwrapper parameters).

You can construct the format of the required data structure as a string and use the following placeholders to inject specific data into the constructed string:

  • {CHA-RAW} Challenge (key request) data as is, raw bytes
  • {CHA-B64} Challenge (key request) data base64 encoded
  • {CHA-B64U} Challenge (key request) data base64 and URL encoded
  • {CHA-DEC} Challenge (key request) data decimal converted (each char converted as integer concatenated by comma)
  • {SID-RAW} Session ID as is, raw text
  • {SID-B64} Session ID base64 encoded
  • {SID-B64U} Session ID base64 and URL encoded
  • {KID-UUID} KeyID as UUID format
  • {KID-HEX} KeyID as HEX format
  • {PSSH-B64} Initialization PSSH data base64 encoded
  • {PSSH-B64U} Initialization PSSH data base64 and URL encoded

DATA TYPE: str
EXAMPLE: Example of provider customized license request data as JSON with injected challenge data and session ID

lic_req_data = json.dumps({"movie_id": "123456", "challenge_base64": "{CHA-B64}", "SID": "{SID-B64}"})

drm_configs = {
    "...": {
        "license": {
            "req_data": base64.b64encode(lic_req_data),
            ...
        }
    }
}
🟢 wrapper / unwrapper / unwrapper_params - Widevine only. To wrap/unwrap the license data


Widevine only.

Some services use custom data for license server request/response, where the data are wrapped in other types of formats, such as Base64, JSON, XML, etc... but Widevine by default works only with raw binary data, so its needed to prepare the license data wrapped in a suitable way accepted by the server to make the license request, and after extract the raw data from the wrapped data of the server license response.

There are two ways to manage a custom license:

  1. Use built-in wrappers/unwrappers
  2. Via proxy server. An add-on must implement a proxy server to translate the license request response (as explained on How-to-provide-custom-manifest-and-license)

The built-in method is the simplest, but may be not suitable if the custom license is too much complex.

wrapper parameter flags:

  • base64 To encode as base 64
  • urlenc To encode as URL

Multiple flags are accepted and must be splitted by , char, the sequence order declares the way in which to wrap the data.

unwrapper parameter flags:

  • auto Try auto-detect the wrapping types (single-use only)
  • base64 To decode as base 64
  • json To parse JSON data, required unwrapper_params
  • xml To parse XML data, required unwrapper_params

Multiple flags are accepted and must be splitted by , char, the sequence order declares the way in which to unwrap the data.

unwrapper_params parameters:

  • "path_data": Can be used to specify an absolute JSON or XML path to get the license data.
  • "path_data_traverse": bool, If True the search with path_data will be performed by traversing all the dict's to find a specified key instead of an absolute path.
  • "path_hdcp": Can be used to specify the absolute JSON path to get the HDCP resolution limit.
  • "path_hdcp_traverse": bool, If True the search with path_hdcp will be performed by traversing all the dict's to find a specified key instead of an absolute path.

We cannot provide examples for every use case, here we provide an example that can also be adapted for other use cases as they are similar.

Example to configure built-in wrappers/unwrappers for JSON/BASE64 wrapped license:

  1. The service require that the license request is encoded as BASE64, the encoded data must be in JSON format. The Json is a dictionary challenge_base64 that contains the challenge (widevine key request) raw data encoded as base 64.
  2. The license server give a response BASE64 encoded, where contains a JSON with nested dictionaries. The first dictionary is licenseresponse that contains a nested data dictionary, having the license raw data encoded as base 64.
lic_req_data = json.dumps({"challenge_base64": "{CHA-B64}"}) # Prepared Json string, {CHA-B64} used to jniect the challenge as base64

drm_configs = {
    "com.widevine.alpha": {
        "license": {
            "server_url": "https://theserverurl.com",
            "req_data": base64.b64encode(lic_req_data), # Encoded as base64, because its a requirement of the "req_data" parameter.
            "wrapper": "base64", # Encode "req_data" data as base 64, before make the request
            "unwrapper": "base64,json,base64", # From the response -> (1) decode as base 64 -> (2) parse JSON path -> (3) decode base 64 the value
            "unwrapper_params": {"path_data": "licenseresponse/data"}
        }
    }
}

# Expected license response data that will be unwrapped by the configuration:
response_data = "eyJsaWNlbnNlcmVzcG9uc2UiOiB7ImRhdGEiOiAiZEdocGN5QnBjeUJ5WVhjZ1pHRjBZUT09In19Cg=="

To check if you are sending/receive the data correctly, you can enable the ISA expert setting to save the license data and so inspect the saved files. In short, the ".request" file should reflect the format required by your service provider, while ".response" file should show that it contains only the license data (raw) bytes.

🟢 keyids - ClearKey DRM only. Map of KID/Key pairs


Allows to specify a map of unencrypted KID/Key pairs to decrypt stream CENC content, can be useful for diagnosing problems and testing integrations.

Both KID/Key values must be in hex format.

DATA TYPE: dict
EXAMPLE: "keyids": { "KID_1": "KEY_1", "KID_2": "KEY_2" }


🔵 init_data - To set custom initialization data


Allow to provide a custom initialization data (PSSH box) to initialize the CDM.

The use case usually is for MPEG-DASH manifests that dont provide a ContentProtection tag with schemeIdUri attribute to identify a content protection scheme for a specific DRM. Therefore to ignore the missing manifest protection schemes you can provide the initialization data.

The value must be encoded as base64.

DATA TYPE: str
EXAMPLE: "init_data": "base64 data"

🔵 pre_init_data - Widevine only, for custom licensed manifests


Widevine DRM only.

This is required for services that make use of licensed manifests (custom manifests). Compared to the standard manifests (e.g. DASH) this encloses also the license data. To request these custom manifests usually you need to provide the DRM session id and the challenge (widevine key request). To obtain these two data, this parameter allows you to pre-initialize the DRM by opening a DRM session. To open a DRM session you need to provide a PSSH and KID, both values must be base 64 encoded and splitted by a pipe char |.

After that, you need to implement a proxy in your add-on to intercept the ISAdaptive HTTP manifest/license requests, as in the example How to provide custom manifest and license, will allow your addon to manage and convert the manifest/license data. When you will get the HTTP manifest response, you will also need to transfer the license data into the ISA license HTTP request.

With the HTTP manifest request, two custom HTTP headers will be provided:

  • challengeB64 Provide the challenge (key request) encoded as base 64, and URL encoded.
  • sessionId Provide the DRM session id.

WARNING: Do not enable pre_init_data parameter without a proxy server in your add-on, otherwise the license data will not be managed.
WARNING: This feature is currently intended for non-Android systems. Can works also on Android system, but to keep in mind that it is not possible to maintain the same DRM session, this mismatch will result in the license data may not working.

DATA TYPE: str
EXAMPLE: "pre_init_data": "PSSH encoded base 64|KID encoded base 64"

🔵 persistent_storage - Enables the CDM persistent state


Set to `True` to enable the CDM persistent state. This allow to store locally the session data or other type of state. To be enabled only if the streaming service requires it.

DATA TYPE: bool
EXAMPLE: "persistent_storage": True

🔵 secure_decoder - To enable/disable secure decoder


Set to `True` or `False` to "force" enable or disable the secure decoder, every time this is set will override the user settings set on the ISA add-on settings window.

NOTE: If you dont want override the ISA add-on user settings, remember to remove secure_decoder parameter and so add it only when needed.

Disable the secure decoder could be helpful for some android devices where playback may result in a black screen, usually due to faulty Widevine L1 certifications.

DATA TYPE: bool
EXAMPLE: "secure_decoder": True

🔵 optional_key_req_params - To set specific initialization CDM parameters


This parameter is closely related to the type of CDM used, allows you to configure CDM initialization parameters usually used for the key request.

PlayReady DRM: custom_data Allow to set data to the PRCustomData CDM parameter to make the key request.

DATA TYPE: dict
EXAMPLE: "optional_key_req_params": {"custom_data": "the data"}



🟠inputstream.adaptive.drm - Examples [click to expand]

DASH + WIDEVINE: Play encrypted video stream from add-on

listitem = xbmcgui.ListItem(path='https://www.videoservice.com/manifest.mpd', offscreen=True)

# These two lines are needed to prevent the HTTP HEAD request from Kodi core, used to determine the mimetype
listitem.setMimeType('application/dash+xml')
listitem.setContentLookup(False)

listitem.setProperty('inputstream', 'inputstream.adaptive')

license_headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/109.0',
    'Content-Type': 'application/octet-stream'
}

# Example configuration with drm_legacy property
listitem.setProperty('inputstream.adaptive.drm_legacy', 'com.widevine.alpha|https://www.licenseserver.com/acquirelicense|' + urlencode(license_headers))

# Example configuration with drm property
drm_cfg = {"com.widevine.alpha":
    {"license":
        {"server_url": "https://www.licenseserver.com/acquirelicense",
         "req_headers": urlencode(license_headers)}
    }
}
listitem.setProperty('inputstream.adaptive.drm', json.dumps(drm_cfg))

xbmcplugin.setResolvedUrl(pluginhandle, True, listitem=listitem)

DASH + WIDEVINE: Play encrypted video stream from playlist file STRM / M3U8

#KODIPROP:inputstream=inputstream.adaptive
# Example configuration with drm_legacy property
#KODIPROP:inputstream.adaptive.drm_legacy=com.widevine.alpha|https://www.licenseserver.com/acquirelicense|User-Agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F106.0.0.0+Safari%2F537.36
# Example configuration with drm property
#KODIPROP:inputstream.adaptive.drm={"com.widevine.alpha":{"license": {"server_url": "https://www.licenseserver.com/acquirelicense","req_headers": "User-Agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F106.0.0.0+Safari%2F537.36"}}}
#KODIPROP:mimetype=application/dash+xml
https://www.videoservice.com/manifest.mpd

SMOOTHSTREAMING + PLAYREADY: Play encrypted video stream from add-on

listitem = xbmcgui.ListItem(path='https://www.videoservice.com/tearsofsteel_4k.ism/manifest', offscreen=True)

# These two lines are needed to prevent the HTTP HEAD request from Kodi core, used to determine the mimetype
listitem.setMimeType('application/vnd.ms-sstr+xml')
listitem.setContentLookup(False)

listitem.setProperty('inputstream', 'inputstream.adaptive')
# Example configuration with drm_legacy property
listitem.setProperty('inputstream.adaptive.drm_legacy', 'com.microsoft.playready')
# Example configuration with drm property
listitem.setProperty('inputstream.adaptive.drm', '{"com.microsoft.playready": {}}')

xbmcplugin.setResolvedUrl(pluginhandle, True, listitem=listitem)

HLS + AES-128: Play encrypted video stream from add-on

listitem = xbmcgui.ListItem(path='https://www.videoservice.com/master_manifest.m3u8', offscreen=True)

# These two lines are needed to prevent the HTTP HEAD request from Kodi core, used to determine the mimetype
listitem.setMimeType('application/vnd.apple.mpegurl')
listitem.setContentLookup(False)

listitem.setProperty('inputstream', 'inputstream.adaptive')
# Usually there is no need to set inputstream.adaptive.drm or inputstream.adaptive.drm_legacy
# but, if you need to add custom headers or parameters to the HLS HTTP key request's
# you can use the following configuration (the Key System is, none):
encrypt_cfg = {"none":{"license": {"req_headers": "User-Agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F106.0.0.0+Safari%2F537.36", "req_params": "/example/param"}}}
listitem.setProperty('inputstream.adaptive.drm', json.dumps(encrypt_cfg))

xbmcplugin.setResolvedUrl(pluginhandle, True, listitem=listitem)

DASH + CLEARKEY: Play encrypted video stream from add-on by providing clear key's

listitem = xbmcgui.ListItem(path='https://www.videoservice.com/manifest.mpd', offscreen=True)

# These two lines are needed to prevent the HTTP HEAD request from Kodi core, used to determine the mimetype
listitem.setMimeType('application/dash+xml')
listitem.setContentLookup(False)

listitem.setProperty('inputstream', 'inputstream.adaptive')

drm_cfg = {"org.w3.clearkey":
    {"license":
        {"keyids": { "KID_1": "KEY_1", "KID_2": "KEY_2" }}
    }
}
listitem.setProperty('inputstream.adaptive.drm', json.dumps(drm_cfg))

xbmcplugin.setResolvedUrl(pluginhandle, True, listitem=listitem)

DRM Key System's

List of supported DRM Key Systems, required to set a DRM configuration.

DRM Name Key System
Widevine com.widevine.alpha
PlayReady (android only) com.microsoft.playready
Wiseplay (android only) com.huawei.wiseplay
ClearKey (from v.21.5.0 / Kodi 21) org.w3.clearkey
Special case, for encryptions without DRM (Kodi 22+) none

The special case none can be used to set some parameters to other encryption cases for example HLS AES-128.

Other

🟤 License URL too long - How to solve PVR binary API bug (Only for Kodi v20-v21) [click to expand]

On all Kodi versions until v21, there is a know Kodi PVR API interface bug, that truncate ISAdaptive properties values to max 1024 chars, then if the server license URL is too long will trucate the data set on the InputStream properties (e.g. inputstream.adaptive.license_key), and the video playback will fails.

The PVR API bug has been fixed on Kodi v22.

To workaround this bug, has been added these two properties (that can be used only on Kodi 20/21) to split the URL on two parts of 1024 chars:

  • inputstream.adaptive.license_url [deprecated on Kodi 22]
  • inputstream.adaptive.license_url_append [deprecated on Kodi 22]

How to do:

  1. Leave empty the field used to set the license URL (e.g. on inputstream.adaptive.license_key the [license server URL] template field)
  2. Take care to split the license server url in two parts of 1024 chars, then use license_url to specify the first 1024 chars, and license_url_append to add the last part of remaining url chars.

NOTE: On Kodi v20, has been introduced from ISA v20.3.15

🟤 How to configure SmoothStreaming PlayReady manifest to use Widevine [click to expand]

Some video services can use SmoothStreaming manifests protected with PlayReady DRM, and may also provide a Widevine server license URL. Then it is possible try to force use Widevine DRM to play the contents protected with PlayReady DRM. This is useful because currently the use of PlayReady is limited on android only, and some android devices may not support PlayReady.

To force Widevine you need just to specify "com.widevine.alpha" (instead of "com.microsoft.playready") and set the license server URL, as follow:

listitem = xbmcgui.ListItem(path='https://www.videoservice.com/tearsofsteel_4k.ism/manifest', offscreen=True)

# These two lines are needed to prevent the HTTP HEAD request from Kodi core, used to determine the mimetype
listitem.setMimeType('application/vnd.ms-sstr+xml')
listitem.setContentLookup(False)

listitem.setProperty('inputstream', 'inputstream.adaptive')
listitem.setProperty('inputstream.adaptive.manifest_type', 'ism') # Deprecated on Kodi 21, removed on Kodi 22
if Kodi < v21:
  listitem.setProperty('inputstream.adaptive.license_type', 'com.widevine.alpha')
  listitem.setProperty('inputstream.adaptive.license_key', 'https://widevinelicenseserverurl')
if Kodi >= v21:
  listitem.setProperty('inputstream.adaptive.drm_legacy', 'com.widevine.alpha|https://widevinelicenseserverurl')
xbmcplugin.setResolvedUrl(pluginhandle, True, listitem=listitem)

If the video service require custom data to the Widevine PSSH:

You can pass your custom data by using inputstream.adaptive.license_data property, the data must be encoded as base64.

Two placeholders can be optionally used to inject data in to the custom data:

  • {KID} to inject the KID as bytes
  • {UUID} to inject the KID as UUID string

The placeholders if used must be encoded as base64 together with the raw data, and not separately.

Technically speaking the custom data will be added to content_id field of WidevinePsshData structure of Widevine PSSH. The WidevinePsshData generated will be add to a standard generated PSSH box.

🟤 ClearKey DRM remarks and limitations [click to expand]

  • This DRM was implemented later time in Kodi v21 and can be configured from Kodi v21 by using the inputstream.adaptive.drm_legacy property, and from Kodi v22 also by using the inputstream.adaptive.drm property. This choice was made because the deprecated "advanced method" (that make use of multiple properties) will be removed in near future. So we want to encourage the use of the new methods to limit future changes needed.
  • It can be used to test streams protected with other types of DRM's, by providing the appropriate kid / key's pairs.
  • Only "cenc" encryption protection is supported, so no "cbcs" encryption.
  • With the current implementation when the license request by URL is a requirement, requests will be made for each individual KID at a time, it is expected that the server will answer with only the requested JWK set and not multiple (will be ignored).
  • Compatibility with Microsoft SmoothStreaming manifest is currently not implemented.
Clone this wiki locally