示例#1
0
    def create_decryptor(self, key, sequence):
        if key.method != "AES-128":
            raise StreamError("Unable to decrypt cipher {0}", key.method)

        if not self.key_uri_override and not key.uri:
            raise StreamError("Missing URI to decryption key")

        if self.key_uri_override:
            p = urlparse(key.uri)
            key_uri = LazyFormatter.format(
                self.key_uri_override,
                url=key.uri,
                scheme=p.scheme,
                netloc=p.netloc,
                path=p.path,
                query=p.query,
            )
        else:
            key_uri = key.uri

        if self.key_uri != key_uri:
            res = self.session.http.get(key_uri, exception=StreamError,
                                        retries=self.retries,
                                        **self.reader.request_params)
            res.encoding = "binary/octet-stream"
            self.key_data = res.content
            self.key_uri = key_uri

        iv = key.iv or num_to_iv(sequence)

        # Pad IV if needed
        iv = b"\x00" * (16 - len(iv)) + iv

        return AES.new(self.key_data, AES.MODE_CBC, iv)
    def test_format_lazy_title_default(self):
        plugin = self._get_fake_plugin()
        plugin.get_title.return_value = None
        res = LazyFormatter.format("{title}",
                                   title=lambda: plugin.get_title() or "default_title")

        self.assertEqual("default_title", res)

        plugin.get_title.assert_called()
        plugin.get_author.assert_not_called()
        plugin.get_game.assert_not_called()
示例#3
0
    def test_format_lazy_title_default(self):
        plugin = self._get_fake_plugin()
        plugin.get_title.return_value = None
        res = LazyFormatter.format(
            "{title}", title=lambda: plugin.get_title() or "default_title")

        self.assertEqual("default_title", res)

        plugin.get_title.assert_called()
        plugin.get_author.assert_not_called()
        plugin.get_game.assert_not_called()
示例#4
0
def create_title(plugin=None):
    if args.title and plugin:
        title = LazyFormatter.format(
            maybe_encode(args.title),
            title=lambda: plugin.get_title() or DEFAULT_STREAM_METADATA["title"],
            author=lambda: plugin.get_author() or DEFAULT_STREAM_METADATA["author"],
            category=lambda: plugin.get_category() or DEFAULT_STREAM_METADATA["category"],
            game=lambda: plugin.get_category() or DEFAULT_STREAM_METADATA["game"]
        )
    else:
        title = args.url
    return title
示例#5
0
def create_title(plugin=None):
    if args.title and plugin:
        title = LazyFormatter.format(
            maybe_encode(args.title),
            title=lambda: plugin.get_title() or DEFAULT_STREAM_METADATA["title"],
            author=lambda: plugin.get_author() or DEFAULT_STREAM_METADATA["author"],
            category=lambda: plugin.get_category() or DEFAULT_STREAM_METADATA["category"],
            game=lambda: plugin.get_category() or DEFAULT_STREAM_METADATA["game"]
        )
    else:
        title = args.url
    return title
    def test_format_lazy_title_author_game(self):
        plugin = self._get_fake_plugin()

        res = LazyFormatter.format("{title} - {author} - {game}",
                                   title=plugin.get_title,
                                   author=plugin.get_author,
                                   game=plugin.get_game)

        self.assertEqual("title - author - game", res)

        plugin.get_title.assert_called()
        plugin.get_author.assert_called()
        plugin.get_game.assert_called()
示例#7
0
    def test_format_lazy_title_author_game(self):
        plugin = self._get_fake_plugin()

        res = LazyFormatter.format("{title} - {author} - {game}",
                                   title=plugin.get_title,
                                   author=plugin.get_author,
                                   game=plugin.get_game)

        self.assertEqual("title - author - game", res)

        plugin.get_title.assert_called()
        plugin.get_author.assert_called()
        plugin.get_game.assert_called()
示例#8
0
    def test_format_lazy_title(self):
        plugin = self._get_fake_plugin()

        res = LazyFormatter.format("{title}",
                                   title=plugin.get_title,
                                   author=plugin.get_author,
                                   game=plugin.get_game,
                                   url=plugin.url)

        self.assertEqual("title", res)

        plugin.get_title.assert_called()
        plugin.get_author.assert_not_called()
        plugin.get_game.assert_not_called()
 def test_format_fmt_prop(self):
     self.assertEqual("test",
                      LazyFormatter.format("{fmt}", fmt="test"))
    def test_format_lazy_title_not_callable(self):
        res = LazyFormatter.format("{title}",
                                   title="title")

        self.assertEqual("title", res)
示例#11
0
    def create_request_params(self, sequence):
        # felix add update headers cookies
        request_params = dict(self.reader.request_params)
        headers = request_params.pop("headers", {})
        cookies = request_params.pop("cookies", {})
        if self.token_uri_override:
            p = urlparse(self.token_uri_override)
            key_uri = LazyFormatter.format(
                self.token_uri_override,
                url=self.token_uri_override,
                scheme=p.scheme,
                netloc=p.netloc,
                path=p.path,
                query=p.query,
            )
            try:
                token = self.session.cache.get(key_uri)
                if not token:
                    res = self.session.http.get(
                        key_uri,
                        exception=StreamError,
                        retries=self.playlist_reload_retries,
                        **self.reader.request_params)
                    token = self.session.http.json(res)
                    self.session.cache.set(
                        key_uri,
                        token,
                        expires=self.session.options.get('hls-token-period'))
                    log.debug(
                        f"create_request_params save to cache {key_uri} {token}"
                    )
                else:
                    log.debug(
                        f"create_request_params load from cache {key_uri} {token}"
                    )
            except BaseException as e:
                log.warning(e)
                token = {}
            log.debug(f"create_request_params token {token}")

            token_headers = token.pop("headers", {})
            token_cookies = token.pop("cookies", {})
            headers.update(token_headers)
            cookies.update(token_cookies)

        if sequence.segment.byterange:
            bytes_start = self.byterange_offsets[sequence.segment.uri]
            if sequence.segment.byterange.offset is not None:
                bytes_start = sequence.segment.byterange.offset

            bytes_len = max(sequence.segment.byterange.range - 1, 0)
            bytes_end = bytes_start + bytes_len
            headers["Range"] = "bytes={0}-{1}".format(bytes_start, bytes_end)
            self.byterange_offsets[sequence.segment.uri] = bytes_end + 1

        request_params["headers"] = headers
        if cookies:
            cookiejar = cookiejar_from_dict(cookies)
            request_params["cookies"] = cookiejar

        return request_params
示例#12
0
    def reload_playlist(self):
        if self.closed:
            return

        self.reader.buffer.wait_free()
        log.debug("Reloading playlist")
        # felix add update headers cookies
        '''
        add option to self.session.options.options
        then update self.session.http.headers before access self.stream.url
        eg:
        headers.update(session.headers)
        '''
        request_params = dict(self.reader.request_params)
        headers = request_params.pop("headers", {})
        cookies = request_params.pop("cookies", {})
        if self.token_uri_override:
            p = urlparse(self.token_uri_override)
            key_uri = LazyFormatter.format(
                self.token_uri_override,
                url=self.token_uri_override,
                scheme=p.scheme,
                netloc=p.netloc,
                path=p.path,
                query=p.query,
            )
            try:
                token = self.session.cache.get(key_uri)
                if not token:
                    res = self.session.http.get(
                        key_uri,
                        exception=StreamError,
                        retries=self.playlist_reload_retries,
                        **self.reader.request_params)
                    token = self.session.http.json(res)
                    self.session.cache.set(
                        key_uri,
                        token,
                        expires=self.session.options.get('hls-token-period'))
                    log.debug(
                        f"reload_playlist save to cache {key_uri} {token}")
                else:
                    log.debug(
                        f"reload_playlist load from cache {key_uri} {token}")
            except BaseException as e:
                log.warning(e)
                token = {}
            log.debug(f"reload_playlist {token}")

            token_headers = token.pop("headers", {})
            token_cookies = token.pop("cookies", {})
            headers.update(token_headers)
            cookies.update(token_cookies)
            request_params["headers"] = headers
            if cookies:
                cookiejar = cookiejar_from_dict(cookies)
                request_params["cookies"] = cookiejar

        res = self.session.http.get(self.stream.url,
                                    exception=StreamError,
                                    retries=self.playlist_reload_retries,
                                    **request_params)
        try:
            playlist = self._reload_playlist(res.text, res.url)
        except ValueError as err:
            raise StreamError(err)

        if playlist.is_master:
            raise StreamError("Attempted to play a variant playlist, use "
                              "'hls://{0}' instead".format(self.stream.url))

        if playlist.iframes_only:
            raise StreamError(
                "Streams containing I-frames only is not playable")

        media_sequence = playlist.media_sequence or 0
        sequences = [
            Sequence(media_sequence + i, s)
            for i, s in enumerate(playlist.segments)
        ]

        self.playlist_reload_time = self._playlist_reload_time(
            playlist, sequences)

        if sequences:
            self.process_sequences(playlist, sequences)
示例#13
0
 def test_format_fmt_prop(self):
     self.assertEqual("test", LazyFormatter.format("{fmt}", fmt="test"))
示例#14
0
    def test_format_lazy_title_not_callable(self):
        res = LazyFormatter.format("{title}", title="title")

        self.assertEqual("title", res)