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)
Beispiel #3
0
    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)
Beispiel #4
0
    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