-
Notifications
You must be signed in to change notification settings - Fork 245
Integration
To play multi bitrate streams from an add-on you need to set a few ListItem properties in order to tell Kodi
- that inputstream.adaptive should be selected for demuxing the stream
- how to handle the decryption (if the stream is DRM protected)
Here we provide examples for python add-ons but can also be adapted for binary add-ons.
Play unencrypted video stream
listitem = xbmcgui.ListItem(path='https://www.videoservice.com/manifest.mpd')
listitem.setMimeType('application/xml+dash')
listitem.setContentLookup(False)
listitem.setProperty('inputstream', 'inputstream.adaptive')
listitem.setProperty('inputstream.adaptive.manifest_type', 'mpd') # Deprecated on Kodi 21
xbmcplugin.setResolvedUrl(pluginhandle, True, listitem=listitem)
Play DRM encrypted video stream
listitem = xbmcgui.ListItem(path='https://www.videoservice.com/manifest.mpd')
listitem.setMimeType('application/xml+dash')
listitem.setContentLookup(False)
listitem.setProperty('inputstream', 'inputstream.adaptive')
listitem.setProperty('inputstream.adaptive.manifest_type', 'mpd') # Deprecated on Kodi 21
listitem.setProperty('inputstream.adaptive.license_type', 'com.widevine.alpha')
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',
'Origin': 'https://www.somesite.com'
}
from urllib.parse import urlencode
license_config = { # for Python < v3.7 you should use OrderedDict to keep order
'license_server_url': 'https://license.server.com/licenserequest',
'headers': urlencode(license_headers),
'post_data': 'R{SSM}',
'response_data': 'R'
}
listitem.setProperty('inputstream.adaptive.license_key', '|'.join(license_config.values()))
xbmcplugin.setResolvedUrl(pluginhandle, True, listitem=listitem)
- inputstreamaddon / inputstream [mandatory]
- inputstream.adaptive.manifest_type [mandatory until Kodi 20, deprecated on Kodi 21]
- inputstream.adaptive.license_type [mandatory for DRM encrypted media]
- inputstream.adaptive.license_key [mandatory for some DRM encrypted media]
-
inputstream.adaptive.license_url [for PVR binary addons only]
-
inputstream.adaptive.license_url_append [for PVR binary addons only]
- inputstream.adaptive.license_data
-
inputstream.adaptive.manifest_params
-
inputstream.adaptive.manifest_headers
- inputstream.adaptive.manifest_update_parameter [deprecated on Kodi 21]
-
inputstream.adaptive.manifest_upd_params
-
inputstream.adaptive.stream_params
- inputstream.adaptive.stream_headers [see Kodi 20 deprecation, changes on Kodi 21]
- inputstream.adaptive.server_certificate
- inputstream.adaptive.license_flags
- inputstream.adaptive.play_timeshift_buffer
-
inputstream.adaptive.live_delay
- inputstream.adaptive.max_bandwidth [deprecated on Kodi 20, removed on Kodi 21]
- inputstream.adaptive.original_audio_language
-
inputstream.adaptive.pre_init_data
-
inputstream.adaptive.stream_selection_type
[mandatory]
This property must be set to tell kodi to use inputstream.adaptive add-on to handle the stream
For Kodi 19.x and above:
listitem.setProperty('inputstream', 'inputstream.adaptive')
For Kodi 18.x:
listitem.setProperty('inputstreamaddon', 'inputstream.adaptive')
[mandatory, until to Kodi v20]
Specify the manifest type of the media stream.
Possible values are:
-
mpd
for MPEG-DASH -
hls
for HLS - HTTP Live Streaming -
ism
for Microsoft Smooth Streaming Media
listitem.setProperty('inputstream.adaptive.manifest_type', 'mpd')
WARNING: THIS PROPERTY HAS BEEN DEPRECATED ON Kodi v21, because the manifest type is now auto-detected. If you have experienced problems by removing this property by using proxy to manipulate manifests, more likely you miss to add the appropriate header in proxy manifest HTTP response, read "How to provide custom manifest and license" page for more details.
[mandatory for DRM encrypted media]
Specify which DRM system should be used, possible values are:
- For Google Widevine:
com.widevine.alpha
*note 1 - For Microsoft PlayReady:
com.microsoft.playready
(available on Android only) - For Huawei WisePlay:
com.huawei.wiseplay
(available on Android only)
*note 1: On all other systems different from 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.
listitem.setProperty('inputstream.adaptive.license_type', 'com.widevine.alpha')
[mandatory for some DRM encrypted media]
Specify the license_key to configure how InputStream Adaptive handle the DRM license for the decryption. Following guidelines can only be used for Widevine / WisePlay DRM's, The PlayReady DRM do not support this parameter, because license-URL is part of the PlayReady WRM header.
The license_key parameter is composed by a string template with 4 fields separated by pipe |
chars:
[license server URL] | [Headers] | [Post-Data] | [Response-Data]
(without spaces)
NOTE: For HLS AES encrypted, the key URL is supported in the HLS playlist, and for this use case the license_key parameter works this way, taking into account only the first two template fields:
[parameters to append to the key URL] | [Key URL Headers] ||
(without spaces)
license_headers = {
'header-name': 'header-value',
'Content-Type': 'application/octet-stream',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/109.0',
'Origin': 'https://www.somesite.com'
}
from urllib.parse import urlencode
license_config = { # for Python < v3.7 you should use OrderedDict to keep order
'license_server_url': 'https://license.server.com/licenserequest',
'headers': urlencode(license_headers),
'post_data': 'R{SSM}',
'response_data': 'R'
}
listitem.setProperty('inputstream.adaptive.license_key', '|'.join(license_config.values()))
# if you prefer you can set the configuration directly as a single string,
# just be careful to encode the fields in the appropriate way
listitem.setProperty('inputstream.adaptive.license_key', 'https:\\www.licserver.com\data\example\{HASH}||b{SSM}b{SID}|B')
[license server URL]
The license server URL where make the license HTTP request. In the URL is possible optionally inject the DRM Challenge by using following placeholders:
-
B{SSM}
Inject to the URL the DRM Challenge as base64, URL encoded -
{HASH}
Inject to the URL the DRM Challenge hashed as MD5
[Headers]
Allow you to add the HTTP headers for the license HTTP request, the paramters will be URL encoded automatically.
The headers must be follow this scheme: param1=value1¶m2=value2
[Post-Data]
You can use this field to make an HTTP post request with data. Optionally this field can be set with URL encoded text. To enable the post request you have add the placeholder:
- [R/b/B/D]
{SSM}
placeholder to transport the DRM Challenge After that you can add also other optional data as: - [R/b/B]
{SID}
placeholder to transport the DRM Session ID - [R/H]
{KID}
placeholder to transport the DRM Key ID - [b/B]
{PSSH}
placeholder to transport the initial PSSH (Android only)
Only 1 prefix parameter allowed, summary:
R
- The data will be kept as is raw
b
- The data will be base64 encoded
B
- The data will be base64 encoded and URL encoded
D
- The data will be decimal converted (each char converted as integer concatenated by comma)
H
- The data will be hexadecimal converted (each character converted as hexadecimal and concatenated)
[Response-Data]
Specify how handle the data of HTTP license response:
- Not specified, or,
R
if the response payload is in binary raw format -
B
if the response payload is encoded as base64 -
J
[license tokens] if the response payload is in JSON format. You must specify the license tokens names to allow inputstream.adaptive searches for the license key and optionally the HDCP limit. The tokens must be separated by;
. The first token must be for the key license, the second one, optional, for the HDCP limit. The HDCP limit is the result of resolution width multiplied for its height. For example to limit until to 720p: 1280x720 the result will be 921600. -
JB
[license tokens] same meaning of J[license tokens] but the value contained in the JSON path is encoded as base64. -
BJ
[license tokens] same meaning of J[license tokens] but the JSON is encoded as base64 and the value contained in the JSON path is raw. -
HB
if the response payload is after two return chars\r\n\r\n
in binary raw format.
The template field will be filled as:
- Widevine:
[license server URL] | Content-Type=application/octet-stream | R{SSM} | R
- PlayReady:
[license server URL] | Content-Type=text/xml&SOAPAction=http://schemas.microsoft.com/DRM/2007/03/protocols/AcquireLicense | R{SSM} | R
- WisePlay:
[license server URL] | Content-Type=application/json | R{SSM} | R
Allow to specify the PSSH initialization license data.
Can be used when a MPEG-DASH manifest do not specify the ContentProtection
tag with schemeIdUri
attribute to identify a content protection scheme for a specific DRM. The data provided must be encoded as base64.
The placeholder {KID}
can be used to specify where to inject the default KID into the initialization data, it must also be base64 encoded with the data.
WARNING: Due to its limited and specific use case, moreover for a difficult future maintenances, the placeholder {KID}
HAS BEEN REMOVED FROM Kodi v21. We discourage its use even on older versions of Kodi, as the KID obtained is specifically limited only to some DASH PlayReady ContentProtection tags.
listitem.setProperty('inputstream.adaptive.license_data', 'base64data')
WARNING: Currently there are undocumented mixed features of this property that some old add-on may use, these will be reviewed and changed in the future versions, so may break your addon. But genarally speaking the main purpose to set the initialization PSSH data will be kept.
Specifies the HTTP parameters to be used to download the manifests.
For protocols like HLS, the parameters will be applied to all manifest urls childrens.
listitem.setProperty('inputstream.adaptive.stream_params', 'paramname=value¶mname2=value2')
[for PVR binary addons only]
The license_url
and license_url_append
properties are an exclusive workaround for PVR binary addons, the reason behind this is that Kodi PVR API has a bug that truncate ISAdaptive properties values to max 1024 chars, then when inputstream.adaptive.license_key
exceeds the limit the video playback will fails.
The solution is:
- Leave empty the
inputstream.adaptive.license_key
[license server URL] template field - Take care to split the license server url in two parts of 1024 chars, then use
license_url
to specify the first 1024 chars, andlicense_url_append
to add the last part of remaining url chars.
NOTE: On Kodi v20 has been introduced from version 20.3.15
[for PVR binary addons only]
Used to add the license url remaining chars that exceeds 1024 chars limit, read inputstream.adaptive.license_url
.
NOTE: On Kodi v20 has been introduced from version 20.3.15
Specifies the HTTP headers to be used to download manifests.
For protocols like HLS, the headers will be applied to all manifest urls childrens.
listitem.setProperty('inputstream.adaptive.manifest_headers', 'headername=value&User-Agent=the_user_agent&cookie=the_cookies')
NOTE: if you set "cookie" header, the value containing the cookies should be URL encoded.
WARNING: THIS PROPERTY HAS BEEN DEPRECATED ON Kodi v21, please use manifest_upd_params
instead.
This property force enable manifest updates for LIVE contents after each segment played, but usually it should be enabled automatically. In some cases could be used to solve HTTP error 404 when download the segments due to missing updates.
WARNING: Do not enable it with VOD type manifest.
Set full
as value.
WARNING: THE "full" BEHAVIOUR PARAM HAS BEEN REMOVED ON Kodi v21 because now enabled by default, so when the MPD.Type
is dynamic (live content).
For MPEG-DASH manifest, you can enable and also customize the URL parameters for the manifest HTTP request.
Just set as value the URL paramenters to be add, URL encoded. In order to work you must add also the placeholder $START_NUMBER$
to set the next segment start number in the URL parameter.
Example: ?foo=bar&baz=qux&start_seq=$START_NUMBER$
listitem.setProperty('inputstream.adaptive.manifest_update_parameter', 'full')
This property allows parameters to be added to the URL used to request manifest updates in LIVE content. Currently supported for DASH manifest only.
Placeholder $START_NUMBER$
: if required by video service, it can be used to specify the next segment start number in a URL parameter.
listitem.setProperty('inputstream.adaptive.manifest_upd_params', '?foo=bar&baz=qux&start_seq=$START_NUMBER$')
Specifies the HTTP parameters to be used to download streams (audio/video/subtitles).
listitem.setProperty('inputstream.adaptive.stream_params', 'paramname=value¶mname2=value2')
On Kodi v19 or below:
Specifies the HTTP headers to be used to download manifests and streams (audio/video/subtitles).
On Kodi v20:
Specifies the HTTP headers to be used to download manifests and streams (audio/video/subtitles).
NOTE: Use this property to set headers to the manifests is a deprecated behaviour, use inputstream.adaptive.manifest_headers
instead.
From Kodi v21 or above:
Specifies the HTTP headers to be used to download streams (audio/video/subtitles) only.
listitem.setProperty('inputstream.adaptive.stream_headers', 'headername=value&User-Agent=the_user_agent&cookie=the_cookies')
NOTE: if you set "cookie" header, the value containing the cookies should be URL encoded.
Specifies a server certificate to be used to encrypt messages to the license server. Should be encoded as Base64.
listitem.setProperty('inputstream.adaptive.server_certificate', 'certificate_data')
Can be used to force some behaviours.
Possible values are:
-
'persistent_storage'
: To force the server certificate (available only on OS's other than Android) -
'force_secure_decoder'
: To force secure decoder
More than one flag can be set, you can separate by comma.
listitem.setProperty('inputstream.adaptive.license_flags', 'persistent_storage')
Allow to start playing a LIVE stream from the beginning of the buffer instead of its end, useful for example for sports channels.
Possible values are: true
/ false
(default)
listitem.setProperty('inputstream.adaptive.play_timeshift_buffer', 'true')
Intended for LIVE contents, set a delay from the live edge, this may be used to mitigate problems caused by a player that requests segments that do not exist yet (getting http 404 errors or causing audio buzzing). A reasonable value may be 2 to 4 times the segment duration, but not smaller than 16 seconds.
Be aware that some manifest types already include the configuration of this property (e.g. DASH with suggestedPresentationDelay
), so set this property will override the manifest value (if any).
Possible values are: a number greater or equal than 16
(default), lower values are so ignored.
listitem.setProperty('inputstream.adaptive.live_delay', '16')
Allows to set the maximum stream bandwidth. The value is defined in bit/s.
This property can override the user setting Maximum bandwidth, but only if the value is less than the user setting.
listitem.setProperty('inputstream.adaptive.max_bandwidth', '100000000000')
WARNING: THIS PROPERTY HAS BEEN DEPRECATED ON Kodi v20 and is replaced by another one, see page Stream selection types properties for more details.
WARNING: THIS PROPERTY HAS BEEN REMOVED FROM Kodi v21.
Allow to set the Kodi flag "original audio language", to the audio streams that match the specified language code.
Should be set the language code with ISO 639-1 standard (Kodi support this standard only).
NOTE: If the manifest set the original language to the streams, this not override the manifest properties.
listitem.setProperty('inputstream.adaptive.original_audio_language', 'it')
Some VOD services works with licensed manifests. Compared to the standard manifests, this one also encloses the license data in the manifest.
Usually the request for these types of manifests are customised by the service, so a proxy managed by your add-on will have to act as an intermediary between ISAdaptive and your VOD service, in order to allow your add-on to generate an appropriate manifest request with the DRM data and then make it instead of ISAdaptive.
Enabling this feature you must provide a PSSH and KID. Both values must be provided encoded as Base 64.
listitem.setProperty('inputstream.adaptive.pre_init_data', 'PSSH encoded base 64|KID encoded base 64')
This will pre-initialize the DRM by opening a DRM session and will provide these data in the ISAdaptive HTTP manifest request:
-
challengeB64
- The Challenge (Key Request) value encoded as base 64, and URL encoded. -
sessionId
- The Session ID value in clear.
You can intercept the ISAdaptive manifest/license HTTP requests by implementing a proxy server in your add-on, as in the example How to provide custom manifest and license, will allow you to create the appropriate manifest data and manage the HTTP request through your add-on. When you will get the HTTP manifest response, you will also need to transfer the license data into the ISAdaptive license HTTP request.
WARNINGS:
- Do not enable this feature without a proxy server in an add-on, otherwise the DRM data will not be managed.
- 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.
Allow an add-on to overridden the InputStream Adaptive "stream selection type" setting. Can be used to have customised behaviour on the selection of the audio/video quality of the streams.
Caution: This will make the "stream selection type" setting in the InputStream Adaptive setting window ineffective, so consider allowing the user choice to change this setting in your add-on.
- See page Setting: Stream selection type to know the meaning of each available type.
- See page Stream selection types properties to know in detail the configurable properties of each type.
User Documentation
Developer Documentation
- Integration
- Integration DRM
- Integration DRM (old)
- Stream selection types properties
- How to test a stream
- Test samples python addon
- How to provide custom manifest and license
- Supported containers and codecs
- Verified Media Path (VMP)
- Set resolution limits for DRM streams
- Custom DASH manifest tags
- Audio Subtitles track properties
- Dev. FAQ
- Widevine ARM64 support
- Add‐on WIP status
Development