HDCP resolution limit - xbmc/inputstream.adaptive GitHub Wiki

HDCP is managed by the DRM (CDM) in relation to the hardware in use. When it does not meet certain criteria the DRM key status will have “output-restricted” status, to signal that the stream cant be played.

Unfortunately, currently ISA cannot properly handle the restricted state in a good way to have an automatic fallback to a playable video quality, therefore this may result in inability to play the stream or in a black screen.

Since we do not have a suitable solution yet, the idea is to avoid trying to play non-playable streams, to do this, streams can be removed with one of these workarounds:

Force limit manifest resolutions

Requirement: Kodi 22 and above

By using inputstream.adaptive.config, you can use resolution_limit parameter to force limit the video resolutions available. See Integration wiki page for more details.

License response with custom header

Requirement: Widevine DRM only

You can use the custom HTTP header X-Limit-Video in the HTTP license response to limit the video resolutions.

To add this header in the HTTP license response, you will have to implement a proxy in your add-on to intercept the ISAdaptive HTTP license request, then your addon will make the request to get the license data and will have to edit the response on the fly to add the header (an example in page How to provide custom manifest and license).

The header name: X-Limit-Video
The value format: you can choose between two format types:

  • As integer number: max=(multiplication of width x height)
    example: X-Limit-Video: max=921600 (stands for 1280x720 limit)
  • As string (required Kodi >= v22): max=width x height
    example: X-Limit-Video: max=1280x720

JSON license response with HDCP data

Requirement: Widevine DRM only

Some providers may provide HDCP data in their JSON license response, two data values are supported, the resolution limit value and the HDCP version. They can be used either individually or simultaneously.

Note to Kodi <= v21: The Ignore HDCP status setting if enabled, will disable this feature.

Note to Kodi >= v22: To enable this feature you need to set inputstream.adaptive.config property with check_hdcp value.

Resolution limit JSON path

To set the resolution limit from JSON data, you need to set the JSON path where read the data by using inputstream.adaptive.drm property. The parameters to be used are path_hdcp_ver and optionally path_hdcp_ver_traverse, both are child parameters of license parameter, see Integration-DRM for more details, about wrapper/unwrapper.

Here a short example, assuming the video service return the following JSON:

{
  "video_id": "...",
  "widevine_license": { "data": "...",
                        "max_res": "1280x720"
  }
}

On this example the value set is as string "1280x720", but are supported wide formats as:

  • string: "1280x720" (width x height)
  • string or number: "921600" (result of multiplication of width x height, 921600 stands for "1280x720")

The path can be set as absolute or by name, if absolute, the path will be "widevine_license/max_res", so this is how the configuration should be done:

drm_configs = {
    # This is Widevine DRM Key System
    "com.widevine.alpha": {
        "license": {
            ... (other params),
            "unwrapper_params": { "path_data": "widevine_license/data",
                                  "path_hdcp_res": "widevine_license/max_res" }
        }
    }
}
list_item.setProperty('inputstream.adaptive.drm', json.dumps(drm_configs))

by name, the path will be "max_res", a search will be performed on all the keys in the JSON until the specified one is found, this is useful if the path is variable. This is how the configuration should be done:

drm_configs = {
    # This is Widevine DRM Key System
    "com.widevine.alpha": {
        "license": {
            ... (other params),
            "unwrapper_params": { "path_data": "widevine_license/data",
                                  "path_hdcp_res": "max_res" }
                                  "path_hdcp_res_traverse": True }
        }
    }
}
list_item.setProperty('inputstream.adaptive.drm', json.dumps(drm_configs))

HDCP version JSON path (support limited to DASH MPD manifest only)

When using the HDCP version in JSON license, it is mandatory that also the MPD manifest provide the HDCP version on each Representation tag, this will allow matching between the HDCP versions of the manifest and the license one, thus limiting unsupported resolutions. If the manifest does not provide the HDCP values, the license value will be unused.

How to use it:

  1. Ensure that the MPD manifest provide the HDCP version values to each Representation tag. The version should be written as concatenated number into the "hdcp" attribute of Representation tag. For example HDCP 1.4 the value will be "14", for HDCP 2.0 will be "20", as following example:
<MPD ...>
  <Period ...>
    <AdaptationSet ...>
      <Representation hdcp="14" ...> ...
      <Representation hdcp="22" ...> ...
      ...
  1. Set the license DRM configuration, the configuration can be set by using inputstream.adaptive.drm property. The parameters to be used are path_hdcp_ver and optionally path_hdcp_ver_traverse, both are child parameters of license parameter, see Integration-DRM for more details, about wrapper/unwrapper.

Here a short example, assuming the video service return the following JSON:

{
  "video_id": "...",
  "widevine_license": { "data": "...",
                        "hdcp": "HDCP_V2.2"
  }
}

On this JSON example the hdcp value is a string of "HDCP_V2.2" but are supported more formats as:

  • string: any string that contains numeric values e.g. "HDCP_V1", "HDCP_V2.2", "HDCP_V2_2", ...
  • number: any number e.g. 1.4, 2.1 or equivalent integer 14, 21

The path can be set as absolute or by name, if absolute, the path will be "widevine_license/hdcp", so this is how the configuration should be done:

drm_configs = {
    # This is Widevine DRM Key System
    "com.widevine.alpha": {
        "license": {
            ... (other params),
            "unwrapper_params": { "path_data": "widevine_license/data",
                                  "path_hdcp_ver": "widevine_license/hdcp" }
        }
    }
}
list_item.setProperty('inputstream.adaptive.drm', json.dumps(drm_configs))

by name, the path will be "hdcp", a search will be performed on all the keys in the JSON until the specified one is found, this is useful if the path is variable. This is how the configuration should be done:

drm_configs = {
    # This is Widevine DRM Key System
    "com.widevine.alpha": {
        "license": {
            ... (other params),
            "unwrapper_params": { "path_data": "widevine_license/data",
                                  "path_hdcp_ver": "hdcp",
                                  "path_hdcp_ver_traverse": True }
        }
    }
}
list_item.setProperty('inputstream.adaptive.drm', json.dumps(drm_configs))
⚠️ **GitHub.com Fallback** ⚠️