def get_license_key(key_url, key_type="R", key_headers=None, key_value=None, json_filter=""): """ Generates a propery license key value # A{SSM} -> not implemented # R{SSM} -> raw format # B{SSM} -> base64 format URL encoded (b{ssmm} will not URL encode) # D{SSM} -> decimal format The generic format for a LicenseKey is: |<url>|<headers>|<key with placeholders>|<optional json filter> The Widevine Decryption Key Identifier (KID) can be inserted via the placeholder {KID} :param str key_url: The URL where the license key can be obtained. :param str|None key_type: The key type (A, R, B or D). :param dict[str,str] key_headers: A dictionary that contains the HTTP headers to pass. :param str key_value: The value that is beging passed on as the key value. :param str json_filter: If specified selects that json element to extract the key response. :return: A formated license string that can be passed to the adaptive input add-on. :rtype: str """ return Adaptive.get_license_key(key_url, key_type=key_type, key_headers=key_headers, key_value=key_value, json_filter=json_filter)
def set_input_stream_addon_input(strm, proxy=None, headers=None, license_key=None, license_type="com.widevine.alpha", max_bit_rate=None, persist_storage=False, service_certificate=None, manifest_update=None): """ Parsers standard M3U8 lists and returns a list of tuples with streams and bitrates that can be used by other methods. :param strm: (MediaStream) the MediaStream to update :param proxy: (Proxy) The proxy to use for opening :param dict headers: Possible HTTP Headers :param str license_key: The value of the license key request :param str license_type: The type of license key request used (see below) :param int max_bit_rate: The maximum bitrate to use (optional) :param bool persist_storage: Should we store certificates? And request server certificates? :param str service_certificate: Use the specified server certificate Can be used like this: part = item.create_new_empty_media_part() stream = part.append_media_stream(m3u8url, 0) M3u8.set_input_stream_addon_input(stream, self.proxy, self.headers) item.complete = True if maxBitRate is not set, the bitrate will be configured via the normal generic Retrospect or channel settings. """ if license_key is not None: # Local import to make sure the overhead is low import inputstreamhelper from logger import Logger is_helper = inputstreamhelper.Helper('mpd', drm=license_type) if is_helper.check_inputstream(): Logger.info( "Widevine library was already installed or installed succesfully." ) else: Logger.error( "Widevine was not installed or failed to install.") return Adaptive.set_input_stream_addon_input( strm, proxy, headers, manifest_type="mpd", license_key=license_key, license_type=license_type, max_bit_rate=max_bit_rate, persist_storage=persist_storage, service_certificate=service_certificate, manifest_update=manifest_update)
def set_input_stream_addon_input(strm, proxy=None, headers=None, license_key=None, license_type=None, max_bit_rate=None, persist_storage=False, service_certificate=None, manifest_update=None): """ Parsers standard M3U8 lists and returns a list of tuples with streams and bitrates that can be used by other methods. :param strm: (MediaStream) the MediaStream to update :param proxy: (Proxy) The proxy to use for opening :param dict headers: Possible HTTP Headers :param str license_key: The value of the license key request :param str license_type: The type of license key request used (see below) :param int max_bit_rate: The maximum bitrate to use (optional) :param bool persist_storage: Should we store certificates? And request server certificates? :param str service_certificate: Use the specified server certificate Can be used like this: part = item.create_new_empty_media_part() stream = part.append_media_stream(m3u8url, 0) M3u8.set_input_stream_addon_input(stream, self.proxy, self.headers) item.complete = True if maxBitRate is not set, the bitrate will be configured via the normal generic Retrospect or channel settings. """ return Adaptive.set_input_stream_addon_input( strm, proxy, headers, manifest_type="hls", license_key=license_key, license_type=license_type, max_bit_rate=max_bit_rate, persist_storage=persist_storage, service_certificate=service_certificate, manifest_update=manifest_update)
def get_kodi_play_list_data(self, bitrate, proxy=None): """ Returns the playlist items for this MediaItem :param int bitrate: The bitrate of the streams that should be in the playlist. Given in kbps. :param ProxyInfo|None proxy: The proxy to set :return: A list of ListItems that should be added to a playlist with their selected stream url :rtype: list[tuple[xbmcgui.ListItem, str]] """ Logger.info("Creating playlist items for Bitrate: %s kbps\n%s", bitrate, self) if not bool(bitrate): raise ValueError("Bitrate not specified") play_list_data = [] for part in self.MediaItemParts: if len(part.MediaStreams) == 0: Logger.warning("Ignoring empty MediaPart: %s", part) continue kodi_item = self.get_kodi_item() stream = part.get_media_stream_for_bitrate(bitrate) Logger.info("Selected Stream: %s", stream) if stream.Adaptive: Adaptive.set_max_bitrate(stream, max_bit_rate=bitrate) # Set the actual stream path kodi_item.setProperty("path", stream.Url) # properties of the Part for prop in part.Properties + stream.Properties: Logger.trace("Adding property: %s", prop) kodi_item.setProperty(prop[0], prop[1]) # TODO: Apparently if we use the InputStream Adaptive, using the setSubtitles() causes sync issues. if part.Subtitle and False: Logger.debug("Adding subtitle to ListItem: %s", part.Subtitle) kodi_item.setSubtitles([ part.Subtitle, ]) # Set any custom Header header_params = dict() # set proxy information if present self.__set_kodi_proxy_info(kodi_item, stream, stream.Url, header_params, proxy) # Now add the actual HTTP headers for k in part.HttpHeaders: header_params[k] = HtmlEntityHelper.url_encode( part.HttpHeaders[k]) stream_url = stream.Url if header_params: kodi_query_string = reduce( lambda x, y: "%s&%s=%s" % (x, y, header_params[y]), header_params.keys(), "") kodi_query_string = kodi_query_string.lstrip("&") Logger.debug("Adding Kodi Stream parameters: %s\n%s", header_params, kodi_query_string) stream_url = "%s|%s" % (stream.Url, kodi_query_string) play_list_data.append((kodi_item, stream_url)) return play_list_data