Exemplo n.º 1
0
class RTPPlay(Plugin):
    _m3u8_re = re.compile(
        r"""
        hls:\s*(?:(["'])(?P<string>[^"']+)\1
        |
        decodeURIComponent\((?P<obfuscated>\[.*?])\.join\()
    """, re.VERBOSE)

    _schema_hls = validate.Schema(
        validate.transform(_m3u8_re.search),
        validate.any(
            None,
            validate.all(validate.get("string"), validate.text,
                         validate.any(validate.length(0), validate.url())),
            validate.all(validate.get("obfuscated"), validate.text,
                         validate.parse_json(),
                         validate.transform(lambda arr: unquote("".join(arr))),
                         validate.url()),
            validate.all(
                validate.get("obfuscated_b64"), validate.text,
                validate.parse_json(),
                validate.transform(lambda arr: unquote("".join(arr))),
                validate.transform(lambda b64: b64decode(b64).decode("utf-8")),
                validate.url())))

    def _get_streams(self):
        self.session.http.headers.update({
            "User-Agent": useragents.CHROME,
            "Referer": self.url
        })
        hls_url = self.session.http.get(self.url, schema=self._schema_hls)
        if not hls_url:
            return
        return HLSStream.parse_variant_playlist(self.session, hls_url)
Exemplo n.º 2
0
    def _get_streams(self):
        url = self.session.http.get(
            "https://stream.1tv.ru/api/playlist/1tvch_as_array.json",
            data={"r": random.randint(1, 100000)},
            schema=validate.Schema(
                validate.parse_json(),
                {"hls": [validate.url()]},
                validate.get("hls"),
                validate.get(0),
            ))

        if not url:
            return

        if "georestrictions" in url:
            log.error("Stream is geo-restricted")
            return

        hls_session = self.session.http.get(
            "https://stream.1tv.ru/get_hls_session",
            schema=validate.Schema(
                validate.parse_json(),
                {"s": validate.transform(unquote)},
            ))
        url = update_qsd(url, qsd=hls_session, safe="/:")

        yield from HLSStream.parse_variant_playlist(self.session, url, name_fmt="{pixels}_{bitrate}").items()
Exemplo n.º 3
0
    def _get_live_streams(self):
        video_id = self.session.http.get(
            self.url,
            schema=validate.Schema(
                validate.parse_html(),
                validate.xml_xpath_string(
                    ".//div[@data-google-src]/@data-video-id")))

        if video_id:
            return self.session.streams(
                f"https://www.youtube.com/watch?v={video_id}")

        info_url = self.session.http.get(
            self.API_URL.format(subdomain=self.match.group("subdomain")),
            schema=validate.Schema(
                validate.parse_json(), {"url": validate.url()},
                validate.get("url"),
                validate.transform(
                    lambda url: update_scheme("https://", url))))
        hls_url = self.session.http.get(info_url,
                                        schema=validate.Schema(
                                            validate.parse_json(), {
                                                "status": "ok",
                                                "protocol": "hls",
                                                "primary": validate.url()
                                            }, validate.get("primary")))

        return HLSStream.parse_variant_playlist(self.session, hls_url)
Exemplo n.º 4
0
    def _hello(self):
        log.debug('_hello ...')
        app_token = self.session.http.get(
            '{0}/token.json'.format(self.base_url),
            schema=validate.Schema(validate.parse_json(), {
                'success': bool,
                'session_token': validate.text,
            }, validate.get('session_token')))
        if self._uuid:
            __uuid = self._uuid
        else:
            __uuid = str(uuid.uuid4())
            self._session_attributes.set('uuid',
                                         __uuid,
                                         expires=self.TIME_SESSION)

        params = {
            'app_version': '3.2120.1',
            'client_app_token': app_token,
            'format': 'json',
            'lang': 'en',
            'uuid': __uuid,
        }
        res = self.session.http.post(
            '{0}/zapi/v3/session/hello'.format(self.base_url),
            headers=self.headers,
            data=params,
            schema=validate.Schema(
                validate.parse_json(),
                validate.any({'active': bool}, {'success': bool})))
        if res.get('active') or res.get('success'):
            log.debug('Hello was successful.')
        else:
            log.debug('Hello failed.')
Exemplo n.º 5
0
class OlympicChannel(Plugin):
    _token_api_path = "/tokenGenerator?url={url}&domain={netloc}&_ts={time}"
    _api_schema = validate.Schema(
        validate.parse_json(),
        [{
            validate.optional("src"): validate.url(),
            validate.optional("srcType"): "HLS",
        }],
        validate.transform(lambda v: v[0].get("src")),
    )
    _data_url_re = re.compile(r'data-content-url="([^"]+)"')
    _data_content_re = re.compile(
        r'data-d3vp-plugin="THEOplayer"\s*data-content="([^"]+)"')
    _data_content_schema = validate.Schema(
        validate.any(
            validate.all(
                validate.transform(_data_url_re.search),
                validate.any(None, validate.get(1)),
            ),
            validate.all(
                validate.transform(_data_content_re.search),
                validate.any(None, validate.get(1)),
            ),
        ),
        validate.any(None, validate.transform(html_unescape)),
    )
    _stream_schema = validate.Schema(
        validate.parse_json(),
        validate.url(),
    )

    def _get_streams(self):
        api_url = self.session.http.get(self.url,
                                        schema=self._data_content_schema)
        if api_url and (api_url.startswith("/") or api_url.startswith("http")):
            api_url = urljoin(self.url, api_url)
            stream_url = self.session.http.get(api_url,
                                               schema=self._api_schema,
                                               headers={"Referer": self.url})
        elif api_url and api_url.startswith("[{"):
            stream_url = self._api_schema.validate(api_url)
        else:
            if api_url is not None:
                log.error(
                    "_data_content_schema returns invalid data: {0}".format(
                        api_url))
            return

        parsed = urlparse(stream_url)
        api_url = urljoin(
            self.url,
            self._token_api_path.format(url=stream_url,
                                        netloc="{0}://{1}".format(
                                            parsed.scheme, parsed.netloc),
                                        time=int(time())))
        stream_url = self.session.http.get(api_url,
                                           schema=self._stream_schema,
                                           headers={"Referer": self.url})
        return HLSStream.parse_variant_playlist(self.session, stream_url)
Exemplo n.º 6
0
class AtresPlayer(Plugin):
    state_re = re.compile(r"""window.__PRELOADED_STATE__\s*=\s*({.*?});""",
                          re.DOTALL)
    channel_id_schema = validate.Schema(
        validate.transform(state_re.search),
        validate.any(
            None,
            validate.all(
                validate.get(1),
                validate.parse_json(),
                validate.transform(search_dict, key="href"),
            )))
    player_api_schema = validate.Schema(
        validate.any(
            None,
            validate.all(
                validate.parse_json(),
                validate.transform(search_dict, key="urlVideo"),
            )))
    stream_schema = validate.Schema(
        validate.parse_json(), {
            "sources": [
                validate.all({
                    "src": validate.url(),
                    validate.optional("type"): validate.text
                })
            ]
        }, validate.get("sources"))

    def __init__(self, url):
        # must be HTTPS
        super().__init__(update_scheme("https://", url))

    def _get_streams(self):
        api_urls = self.session.http.get(self.url,
                                         schema=self.channel_id_schema)
        _api_url = list(api_urls)[0]
        log.debug("API URL: {0}".format(_api_url))
        player_api_url = self.session.http.get(_api_url,
                                               schema=self.player_api_schema)
        for api_url in player_api_url:
            log.debug("Player API URL: {0}".format(api_url))
            for source in self.session.http.get(api_url,
                                                schema=self.stream_schema):
                log.debug("Stream source: {0} ({1})".format(
                    source['src'], source.get("type", "n/a")))

                if "type" not in source or source[
                        "type"] == "application/vnd.apple.mpegurl":
                    streams = HLSStream.parse_variant_playlist(
                        self.session, source["src"])
                    if not streams:
                        yield "live", HLSStream(self.session, source["src"])
                    else:
                        yield from streams.items()
                elif source["type"] == "application/dash+xml":
                    yield from DASHStream.parse_manifest(
                        self.session, source["src"]).items()
Exemplo n.º 7
0
    def _get_streams(self):
        re_room_id = re.compile(
            r"share_url:\"https:[^?]+?\?room_id=(?P<room_id>\d+)\"")
        room_id = self.session.http.get(
            self.url,
            schema=validate.Schema(
                validate.parse_html(),
                validate.xml_xpath_string(
                    ".//script[contains(text(),'share_url:\"https:')][1]/text()"
                ),
                validate.any(
                    None,
                    validate.all(validate.transform(re_room_id.search),
                                 validate.any(None,
                                              validate.get("room_id"))))))
        if not room_id:
            return

        live_status, self.title = self.session.http.get(
            "https://www.showroom-live.com/api/live/live_info",
            params={"room_id": room_id},
            schema=validate.Schema(
                validate.parse_json(), {
                    "live_status": int,
                    "room_name": str,
                }, validate.union_get(
                    "live_status",
                    "room_name",
                )))
        if live_status != self.LIVE_STATUS:
            log.info("This stream is currently offline")
            return

        url = self.session.http.get(
            "https://www.showroom-live.com/api/live/streaming_url",
            params={
                "room_id": room_id,
                "abr_available": 1,
            },
            schema=validate.Schema(
                validate.parse_json(), {
                    "streaming_url_list": [{
                        "type": str,
                        "url": validate.url(),
                    }]
                }, validate.get("streaming_url_list"),
                validate.filter(lambda p: p["type"] == "hls_all"),
                validate.get((0, "url"))),
        )

        res = self.session.http.get(url, acceptable_status=(200, 403, 404))
        if res.headers["Content-Type"] != "application/x-mpegURL":
            log.error("This stream is restricted")
            return

        return HLSStream.parse_variant_playlist(self.session, url)
Exemplo n.º 8
0
 def test_parse_json(self):
     assert validate(parse_json(),
                     '{"a": ["b", true, false, null, 1, 2.3]}') == {
                         "a": ["b", True, False, None, 1, 2.3]
                     }
     with self.assertRaises(ValueError) as cm:
         validate(parse_json(), "invalid")
     assert str(
         cm.exception
     ) == "Unable to parse JSON: Expecting value: line 1 column 1 (char 0) ('invalid')"
Exemplo n.º 9
0
    def get_vod(self, vod_id):
        vod_data = self.session.http.get(
            f"https://aloula.faulio.com/api/v1/video/{vod_id}",
            acceptable_status=(200, 401),
            schema=validate.Schema(
                validate.parse_json(),
                validate.any(
                    validate.all(
                        {
                            "blocks": [{
                                "id": str,
                                "program_title": str,
                                "title": str,
                                "season_number": int,
                                "episode": int,
                            }]
                        },
                        validate.get(("blocks", 0)),
                    ),
                    {
                        "cms_error": str,
                        "message": str
                    },
                ),
            ),
        )

        log.trace(f"{vod_data!r}")
        if "cms_error" in vod_data and vod_data["cms_error"] == "auth":
            log.error(
                "This stream requires a login; specify appropriate Authorization and profile HTTP headers"
            )
            return
        if "cms_error" in vod_data:
            log.error(
                f"API error: {vod_data['cms_error']} ({vod_data['message']})")
            return
        self.id = vod_data["id"]
        self.author = vod_data["program_title"]
        self.title = vod_data["title"]
        self.category = f"S{vod_data['season_number']}E{vod_data['episode']}"

        hls_url = self.session.http.get(
            f"https://aloula.faulio.com/api/v1/video/{vod_id}/player",
            schema=validate.Schema(
                validate.parse_json(),
                {"settings": {
                    "protocols": {
                        "hls": validate.url()
                    }
                }},
                validate.get(("settings", "protocols", "hls")),
            ),
        )
        return HLSStream.parse_variant_playlist(self.session, hls_url)
Exemplo n.º 10
0
    def _get_streams(self):
        params = self.session.http.get(
            self.url,
            schema=validate.Schema(
                validate.transform(self._re_player_manager.search),
                validate.any(
                    None,
                    validate.all(
                        validate.get("json"), validate.parse_json(), {
                            "contentId": validate.any(str, int),
                            validate.optional("streamId"): str,
                            validate.optional("idec"): str,
                            validate.optional("token"): str
                        }))))
        if not params:
            log.error("Could not find player manager data")
            return

        params.update({
            "video": (unquote(params.pop("token")) if params.get("token")
                      is not None else params.pop("streamId")),
            "noflash":
            "yes",
            "embedded":
            "0",
        })

        url_parsed = urlparse(self.url)
        skip_vods = url_parsed.netloc.endswith(
            "m4sport.hu") and url_parsed.path.startswith("/elo")

        self.session.http.headers.update({"Referer": self.url})
        playlists = self.session.http.get(
            self.PLAYER_URL,
            params=params,
            schema=validate.Schema(
                validate.transform(self._re_player_json.search),
                validate.any(
                    None,
                    validate.all(
                        validate.get("json"), validate.parse_json(),
                        {"playlist": [{
                            "file": validate.url(),
                            "type": str
                        }]}, validate.get("playlist"),
                        validate.filter(lambda p: p["type"] == "hls"),
                        validate.filter(
                            lambda p: not skip_vods or "vod" not in p["file"]),
                        validate.map(
                            lambda p: update_scheme("https://", p["file"]))))))

        for url in playlists or []:
            yield from HLSStream.parse_variant_playlist(self.session,
                                                        url).items()
Exemplo n.º 11
0
    def _get_streams(self):
        self.session.http.headers.update(
            {"Referer": "https://tviplayer.iol.pt/"})
        data = self.session.http.get(
            self.url,
            schema=validate.Schema(
                validate.parse_html(),
                validate.xml_xpath_string(
                    ".//script[contains(text(),'.m3u8')]/text()"),
                validate.text, validate.transform(self._re_jsonData.search),
                validate.any(
                    None,
                    validate.all(
                        validate.get("json"), validate.parse_json(), {
                            "id":
                            validate.text,
                            "liveType":
                            validate.text,
                            "videoType":
                            validate.text,
                            "videoUrl":
                            validate.url(path=validate.endswith(".m3u8")),
                            validate.optional("channel"):
                            validate.text,
                        }))))
        if not data:
            return
        log.debug("{0!r}".format(data))

        if data["liveType"].upper() == "DIRETO" and data["videoType"].upper(
        ) == "LIVE":
            geo_path = "live"
        else:
            geo_path = "vod"
        data_geo = self.session.http.get(
            "https://services.iol.pt/direitos/rights/{0}?id={1}".format(
                geo_path, data['id']),
            acceptable_status=(200, 403),
            schema=validate.Schema(
                validate.parse_json(), {
                    "code": validate.text,
                    "error": validate.any(None, validate.text),
                    "detail": validate.text,
                }))
        log.debug("{0!r}".format(data_geo))
        if data_geo["detail"] != "ok":
            log.error("{0}".format(data_geo['detail']))
            return

        wmsAuthSign = self.session.http.get(
            "https://services.iol.pt/matrix?userId=",
            schema=validate.Schema(validate.text))
        hls_url = update_qsd(data["videoUrl"], {"wmsAuthSign": wmsAuthSign})
        return HLSStream.parse_variant_playlist(self.session, hls_url)
Exemplo n.º 12
0
    def _get_streams(self):
        try:
            data_url = self.session.http.get(
                self.url,
                schema=validate.Schema(
                    validate.parse_html(),
                    validate.xml_find(".//*[@data-ctrl-player]"),
                    validate.get("data-ctrl-player"),
                    validate.transform(lambda s: s.replace("'", "\"")),
                    validate.parse_json(), {"url": validate.text},
                    validate.get("url")))
        except PluginError:
            return

        data_url = urljoin(self._URL_DATA_BASE, data_url)
        log.debug("Player URL: '{0}'", data_url)

        self.title, media = self.session.http.get(
            data_url,
            schema=validate.Schema(
                validate.parse_json(name="MEDIAINFO"), {
                    "mc": {
                        validate.optional("_title"):
                        validate.text,
                        "_mediaArray": [
                            validate.all(
                                {
                                    "_mediaStreamArray": [
                                        validate.all(
                                            {
                                                "_quality":
                                                validate.any(
                                                    validate.text, int),
                                                "_stream": [validate.url()],
                                            },
                                            validate.union_get(
                                                "_quality", ("_stream", 0)))
                                    ]
                                }, validate.get("_mediaStreamArray"),
                                validate.transform(dict))
                        ]
                    }
                }, validate.get("mc"),
                validate.union_get("_title", ("_mediaArray", 0))))

        if media.get("auto"):
            for s in HLSStream.parse_variant_playlist(
                    self.session, media.get("auto")).items():
                yield s
        else:
            for quality, stream in media.items():
                yield self._QUALITY_MAP.get(quality, quality), HTTPStream(
                    self.session, stream)
Exemplo n.º 13
0
    def _get_streams(self):
        channel = self.match.group("channel")
        channels = [
            # ((channels), (path, channel))
            (("5-tv", "tv-5", "5tv"), ("tv5", "tv-5")),
            (("chetv", "ctc-che", "che_ext"), ("ctc", "ctc-che")),
            (("ctc"), ("ctc", "ctc")),
            (("ctclove", "ctc-love", "ctc_love_ext"), ("ctc", "ctc-love")),
            (("domashniy", "ctc-dom", "domashniy_ext"), ("ctc", "ctc-dom")),
            (("iz"), ("iz", "iz")),
            (("mir"), ("mtrkmir", "mir")),
            (("muztv"), ("muztv", "muztv")),
            (("ren", "ren-tv", "rentv"), ("nmg", "ren-tv")),
            (("russia1"), ("vgtrk", "russia1")),
            (("russia24"), ("vgtrk", "russia24")),
            (("russiak", "kultura"), ("vgtrk", "russiak")),
            (("spas"), ("spas", "spas")),
            (("tvc"), ("tvc", "tvc")),
            (("tvzvezda", "zvezda"), ("zvezda", "zvezda")),
            (("u", "u_ott"), ("utv", "u_ott")),
        ]
        for c in channels:
            if channel in c[0]:
                path, channel = c[1]
                break
        else:
            log.error(f"Unsupported channel: {channel}")
            return

        res_token = self.session.http.get(
            "https://media.mediavitrina.ru/get_token",
            schema=validate.Schema(
                validate.parse_json(),
                {"result": {"token": str}},
                validate.get("result"),
            ))
        url = self.session.http.get(
            update_qsd(f"https://media.mediavitrina.ru/api/v2/{path}/playlist/{channel}_as_array.json", qsd=res_token),
            schema=validate.Schema(
                validate.parse_json(),
                {"hls": [validate.url()]},
                validate.get("hls"),
                validate.get(0),
            ))

        if not url:
            return

        if "georestrictions" in url:
            log.error("Stream is geo-restricted")
            return

        yield from HLSStream.parse_variant_playlist(self.session, url, name_fmt="{pixels}_{bitrate}").items()
Exemplo n.º 14
0
    def __init__(self, url: str):
        super().__init__(url)
        self._json_data_re = re.compile(r'teliaPlayer\((\{.*?\})\);',
                                        re.DOTALL)

        self.main_page_schema = validate.Schema(
            validate.parse_html(),
            validate.xml_xpath_string(
                ".//iframe[contains(@src, 'ltv.lsm.lv/embed')][1]/@src"),
            validate.url())

        self.embed_code_schema = validate.Schema(
            validate.parse_html(),
            validate.xml_xpath_string(".//live[1]/@*[name()=':embed-data']"),
            str,
            validate.parse_json(),
            {"source": {
                "embed_code": str
            }},
            validate.get(("source", "embed_code")),
            validate.parse_html(),
            validate.xml_xpath_string(".//iframe[@src][1]/@src"),
        )

        self.player_apicall_schema = validate.Schema(
            validate.transform(self._json_data_re.search),
            validate.any(
                None,
                validate.all(
                    validate.get(1),
                    validate.transform(lambda s: s.replace("'", '"')),
                    validate.transform(
                        lambda s: re.sub(r",\s*\}", "}", s, flags=re.DOTALL)),
                    validate.parse_json(), {"channel": str},
                    validate.get("channel"))))

        self.sources_schema = validate.Schema(
            validate.parse_json(), {
                "source": {
                    "sources":
                    validate.all([{
                        "type": str,
                        "src": validate.url()
                    }],
                                 validate.filter(lambda src: src["type"] ==
                                                 "application/x-mpegURL"),
                                 validate.map(lambda src: src.get("src"))),
                }
            }, validate.get(("source", "sources")))
Exemplo n.º 15
0
    def _get_streams(self):
        data = self.session.http.get(
            self.url,
            schema=validate.Schema(
                validate.parse_html(),
                validate.xml_xpath_string(
                    ".//script[@id='js-live-data'][@data-json]/@data-json"),
                validate.any(
                    None,
                    validate.all(
                        validate.parse_json(),
                        {
                            "is_live": int,
                            "room_id": int,
                            validate.optional("room"): {
                                "content_region_permission": int,
                                "is_free": int
                            }
                        },
                    ))))
        if not data:  # URL without livestream
            return

        log.debug(f"{data!r}")
        if data["is_live"] != 1:
            log.info("This stream is currently offline")
            return

        url = self.session.http.get(
            "https://www.showroom-live.com/api/live/streaming_url",
            params={
                "room_id": data["room_id"],
                "abr_available": 1
            },
            schema=validate.Schema(
                validate.parse_json(), {
                    "streaming_url_list": [{
                        "type": str,
                        "url": validate.url(),
                    }]
                }, validate.get("streaming_url_list"),
                validate.filter(lambda p: p["type"] == "hls_all"),
                validate.get((0, "url"))),
        )
        res = self.session.http.get(url, acceptable_status=(200, 403, 404))
        if res.headers["Content-Type"] != "application/x-mpegURL":
            log.error("This stream is restricted")
            return
        return ShowroomHLSStream.parse_variant_playlist(self.session, url)
Exemplo n.º 16
0
    def _get_streams(self):
        player_js = self.session.http.get(
            self.url,
            schema=validate.Schema(
                validate.transform(self._re_player.search),
                validate.any(
                    None,
                    validate.Schema(
                        validate.get(1),
                        validate.transform(
                            lambda url: update_scheme("https:", url))))))
        if not player_js:
            return

        log.debug(f"Found player js {player_js}")
        data = self.session.http.get(
            player_js,
            schema=validate.Schema(
                validate.transform(self._re_json.match), validate.get(1),
                validate.parse_json(), validate.get("mediaResource"),
                validate.get("dflt"), {
                    validate.optional("audioURL"): validate.url(),
                    validate.optional("videoURL"): validate.url()
                }))

        if data.get("videoURL"):
            yield from HLSStream.parse_variant_playlist(
                self.session, update_scheme("https:",
                                            data.get("videoURL"))).items()
        if data.get("audioURL"):
            yield "audio", HTTPStream(
                self.session, update_scheme("https:", data.get("audioURL")))
Exemplo n.º 17
0
    def _get_streams(self):
        email = self.get_option('email')
        password = self.get_option('password')

        if self.options.get('purge_credentials'):
            self.reset_session()
            log.info('All credentials were successfully removed.')
        elif (self._authed and not self._session_control):
            # check every two hours, if the session is actually valid
            log.debug('Session control for {0}'.format(self.domain))
            active = self.session.http.get(
                f'{self.base_url}/zapi/v3/session',
                schema=validate.Schema(validate.parse_json(),
                                       {'active': bool}, validate.get('active'))
            )
            if active:
                self._session_attributes.set(
                    'session_control', True, expires=self.TIME_CONTROL)
                log.debug('User is logged in')
            else:
                log.debug('User is not logged in')
                self._authed = False

        if not self._authed and (not email and not password):
            log.error(
                'A login for Zattoo is required, use --zattoo-email EMAIL'
                ' --zattoo-password PASSWORD to set them')
            return

        if not self._authed:
            self._hello()
            self._login(email, password)

        if self._authed:
            return self._watch()
Exemplo n.º 18
0
    def _login(self, email, password):
        log.debug('_login ...')
        data = self.session.http.post(
            f'{self.base_url}/zapi/v3/account/login',
            headers=self.headers,
            data={
                'login': email,
                'password': password,
                'remember': 'true',
                'format': 'json',
            },
            acceptable_status=(200, 400),
            schema=validate.Schema(validate.parse_json(), validate.any(
                {'active': bool, 'power_guide_hash': str},
                {'success': bool},
            )),
        )

        if data.get('active'):
            log.debug('Login was successful.')
        else:
            log.debug('Login failed.')
            return

        self._authed = data['active']
        self.save_cookies(default_expires=self.TIME_SESSION)
        self._session_attributes.set('power_guide_hash',
                                     data['power_guide_hash'],
                                     expires=self.TIME_SESSION)
        self._session_attributes.set(
            'session_control', True, expires=self.TIME_CONTROL)
Exemplo n.º 19
0
    def _get_vod(self, root):
        schema_vod = validate.Schema(
            validate.xml_xpath_string(
                ".//script[@type='application/ld+json'][contains(text(),'VideoObject')][1]/text()"
            ), str,
            validate.transform(
                lambda jsonlike: re.sub(r"[\r\n]+", "", jsonlike)),
            validate.parse_json(),
            validate.any(
                validate.all(
                    {"@graph": [dict]}, validate.get("@graph"),
                    validate.filter(lambda obj: obj["@type"] == "VideoObject"),
                    validate.get(0)), dict), {"contentUrl": validate.url()},
            validate.get("contentUrl"),
            validate.transform(
                lambda content_url: update_scheme("https://", content_url)))
        try:
            vod = schema_vod.validate(root)
        except PluginError:
            return

        if urlparse(vod).path.endswith(".m3u8"):
            return HLSStream.parse_variant_playlist(self.session, vod)

        return {"vod": HTTPStream(self.session, vod)}
Exemplo n.º 20
0
    def get_live(self, live_slug):
        live_data = self.session.http.get(
            "https://aloula.faulio.com/api/v1/channels",
            schema=validate.Schema(
                validate.parse_json(),
                [{
                    "id": int,
                    "url": str,
                    "title": str,
                    "has_live": bool,
                    "has_vod": bool,
                    "streams": {
                        "hls": validate.url(),
                    },
                }],
                validate.filter(lambda k: k["url"] == live_slug),
            ),
        )
        if not live_data:
            return
        live_data = live_data[0]
        log.trace(f"{live_data!r}")

        if not live_data["has_live"]:
            log.error("Stream is not live")
            return

        self.id = live_data["id"]
        self.author = "SBA"
        self.title = live_data["title"]
        self.category = "Live"
        return HLSStream.parse_variant_playlist(self.session,
                                                live_data["streams"]["hls"])
Exemplo n.º 21
0
class VTVgo(Plugin):
    AJAX_URL = 'https://vtvgo.vn/ajax-get-stream'

    _params_re = re.compile(
        r'''var\s+(?P<key>(?:type_)?id|time|token)\s*=\s*["']?(?P<value>[^"']+)["']?;'''
    )

    _schema_params = validate.Schema(
        validate.transform(lambda html: next(tag.text for tag in itertags(
            html, "script") if "setplayer(" in tag.text)),
        validate.transform(_params_re.findall), [("id", int), ("type_id", str),
                                                 ("time", str),
                                                 ("token", str)])
    _schema_stream_url = validate.Schema(validate.parse_json(),
                                         {"stream_url": [validate.url()]},
                                         validate.get("stream_url"),
                                         validate.get(0))

    def _get_streams(self):
        self.session.http.headers.update({
            'Origin': 'https://vtvgo.vn',
            'Referer': self.url,
            'X-Requested-With': 'XMLHttpRequest',
        })
        params = self.session.http.get(self.url, schema=self._schema_params)

        log.trace('{0!r}'.format(params))
        hls_url = self.session.http.post(self.AJAX_URL,
                                         data=dict(params),
                                         schema=self._schema_stream_url)

        return HLSStream.parse_variant_playlist(self.session, hls_url)
Exemplo n.º 22
0
class CNEWS(Plugin):
    _json_data_re = re.compile(r'jQuery\.extend\(Drupal\.settings, ({.*})\);')
    _dailymotion_url = 'https://www.dailymotion.com/embed/video/{}'

    _data_schema = validate.Schema(
        validate.transform(_json_data_re.search),
        validate.any(
            None,
            validate.all(
                validate.get(1),
                validate.parse_json(),
                {
                    validate.optional('dm_player_live_dailymotion'): {
                        validate.optional('video_id'): str,
                    },
                    validate.optional('dm_player_node_dailymotion'): {
                        validate.optional('video_id'): str,
                    },
                },
            )),
    )

    def _get_streams(self):
        data = self.session.http.get(self.url, schema=self._data_schema)
        if 'dm_player_node_dailymotion' in data:
            return self.session.streams(
                self._dailymotion_url.format(
                    data['dm_player_node_dailymotion']['video_id']))
        elif 'dm_player_live_dailymotion' in data:
            return self.session.streams(
                self._dailymotion_url.format(
                    data['dm_player_live_dailymotion']['video_id']))
Exemplo n.º 23
0
 def _get_vod_streams(self, video_id):
     data = self.session.http.get(
         "https://cloudac.mildom.com/nonolive/videocontent/playback/getPlaybackDetail",
         params={
             "__platform": "web",
             "v_id": video_id,
         },
         schema=validate.Schema(
             validate.parse_json(), {
                 "code": int,
                 validate.optional("message"): str,
                 validate.optional("body"): {
                     "playback": {
                         "video_link": [{
                             "name": str,
                             "url": validate.url()
                         }],
                     },
                 },
             }))
     log.trace(f"{data!r}")
     if data["code"] != 0:
         log.debug(data.get("message", "Mildom API returned an error"))
         return
     for stream in data["body"]["playback"]["video_link"]:
         yield stream["name"], HLSStream(self.session, stream["url"])
Exemplo n.º 24
0
class RaiPlay(Plugin):
    _re_data = re.compile(r"data-video-json\s*=\s*\"([^\"]+)\"")
    _schema_data = validate.Schema(
        validate.transform(_re_data.search),
        validate.any(None, validate.get(1))
    )
    _schema_json = validate.Schema(
        validate.parse_json(),
        validate.get("video"),
        validate.get("content_url"),
        validate.url()
    )

    def _get_streams(self):
        json_url = self.session.http.get(self.url, schema=self._schema_data)
        if not json_url:
            return

        json_url = urlunparse(urlparse(self.url)._replace(path=json_url))
        log.debug("Found JSON URL: {0}".format(json_url))

        stream_url = self.session.http.get(json_url, schema=self._schema_json)
        log.debug("Found stream URL: {0}".format(stream_url))

        res = self.session.http.request("HEAD", stream_url)
        # status code will be 200 even if geo-blocked, so check the returned content-type
        if not res or not res.headers or res.headers["Content-Type"] == "video/mp4":
            log.error("Geo-restricted content")
            return

        for stream in HLSStream.parse_variant_playlist(self.session, stream_url).items():
            yield stream
Exemplo n.º 25
0
    def get_wss_api_url(self):
        try:
            data = self.session.http.get(
                self.url,
                schema=validate.Schema(
                    validate.parse_html(),
                    validate.xml_find(
                        ".//script[@id='embedded-data'][@data-props]"),
                    validate.get("data-props"), validate.parse_json(), {
                        "site": {
                            "relive": {
                                "webSocketUrl": validate.url(scheme="wss")
                            },
                            validate.optional("frontendId"): int
                        }
                    }, validate.get("site"),
                    validate.union_get(("relive", "webSocketUrl"),
                                       "frontendId")))
        except PluginError:
            return

        wss_api_url, frontend_id = data
        if frontend_id is not None:
            wss_api_url = update_qsd(wss_api_url, {"frontend_id": frontend_id})

        return wss_api_url
Exemplo n.º 26
0
    def encrypt_password(self, email, password):
        """
        Get the RSA key for the user and encrypt the users password
        :param email: steam account
        :param password: password for account
        :return: encrypted password
        """
        rsadata = self.session.http.get(
            self._get_rsa_key_url,
            params=dict(username=email,
                        donotcache=str(int(time.time() * 1000))),
            schema=validate.Schema(
                validate.parse_json(), {
                    "publickey_exp":
                    validate.all(str,
                                 validate.transform(lambda x: int(x, 16))),
                    "publickey_mod":
                    validate.all(str,
                                 validate.transform(lambda x: int(x, 16))),
                    "success":
                    True,
                    "timestamp":
                    str,
                    "token_gid":
                    str
                }))

        rsa = RSA.construct(
            (rsadata["publickey_mod"], rsadata["publickey_exp"]))
        cipher = PKCS1_v1_5.new(rsa)
        return base64.b64encode(cipher.encrypt(
            password.encode("utf8"))), rsadata["timestamp"]
Exemplo n.º 27
0
    def _get_streams_delfi(self, src):
        try:
            data = self.session.http.get(src, schema=validate.Schema(
                validate.parse_html(),
                validate.xml_xpath_string(".//script[contains(text(),'embedJs.setAttribute(')][1]/text()"),
                validate.any(None, validate.all(
                    validate.text,
                    validate.transform(re.compile(r"embedJs\.setAttribute\('src',\s*'(.+?)'").search),
                    validate.any(None, validate.all(
                        validate.get(1),
                        validate.transform(lambda url: parse_qsd(urlparse(url).fragment)),
                        {"stream": validate.text},
                        validate.get("stream"),
                        validate.parse_json(),
                        {"versions": [{
                            "hls": validate.text
                        }]},
                        validate.get("versions")
                    ))
                ))
            ))
        except PluginError:
            log.error("Failed to get streams from iframe")
            return

        for stream in data:
            src = update_scheme("https://", stream["hls"], force=False)
            for s in HLSStream.parse_variant_playlist(self.session, src).items():
                yield s
Exemplo n.º 28
0
    def _get_streams_api(self, video_id):
        log.debug("Found video ID: {0}".format(video_id))

        tld = self.match.group("tld")
        try:
            data = self.session.http.get(
                self._api.get(tld, "lt"),
                params=dict(video_id=video_id),
                schema=validate.Schema(
                    validate.parse_json(),
                    {
                        "success": True,
                        "data": {
                            "versions": {
                                validate.text: validate.all(
                                    [{
                                        "type": validate.text,
                                        "src": validate.text,
                                    }],
                                    validate.filter(lambda item: item["type"] == "application/x-mpegurl")
                                )
                            }
                        }
                    },
                    validate.get(("data", "versions"))
                )
            )
        except PluginError:
            log.error("Failed to get streams from API")
            return

        for stream in itertools.chain(*data.values()):
            src = update_scheme("https://", stream["src"], force=False)
            for s in HLSStream.parse_variant_playlist(self.session, src).items():
                yield s
Exemplo n.º 29
0
    def _get_vod_streams(self, data):
        schema_vod_list = validate.Schema(
            validate.any(
                validate.all({"video": {
                    "videoStory": dict
                }}, validate.get(("video", "videoStory"))),
                validate.all({"quicktakeVideo": {
                    "videoStory": dict
                }}, validate.get(("quicktakeVideo", "videoStory")))),
            {"video": {
                "bmmrId": str
            }}, validate.get(("video", "bmmrId")))
        schema_url = validate.all({"url": validate.url()}, validate.get("url"))

        try:
            video_id = schema_vod_list.validate(data)
        except PluginError:
            log.error("Could not find videoId")
            return

        log.debug(f"Found videoId: {video_id}")
        vod_url = self.VOD_API_URL.format(video_id)
        secureStreams, streams, self.title = self.session.http.get(
            vod_url,
            schema=validate.Schema(
                validate.parse_json(), {
                    validate.optional("secureStreams"): [schema_url],
                    validate.optional("streams"): [schema_url],
                    "title": str
                }, validate.union_get("secureStreams", "streams", "title")))

        return secureStreams or streams
Exemplo n.º 30
0
class Streamable(Plugin):
    meta_re = re.compile(r'''var\s*videoObject\s*=\s*({.*});''')
    config_schema = validate.Schema(
        validate.transform(meta_re.search),
        validate.any(None,
                     validate.all(
                         validate.get(1),
                         validate.parse_json(),
                         {
                             "files": {validate.text: {"url": validate.url(),
                                                       "width": int,
                                                       "height": int,
                                                       "bitrate": int}}
                         })
                     )
    )

    def _get_streams(self):
        data = self.session.http.get(self.url, schema=self.config_schema)

        for info in data["files"].values():
            stream_url = update_scheme("https://", info["url"])
            # pick the smaller of the two dimensions, for landscape v. portrait videos
            res = min(info["width"], info["height"])
            yield "{0}p".format(res), HTTPStream(self.session, stream_url)