コード例 #1
0
ファイル: zattoo.py プロジェクト: Billy2011/streamlink-27
    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.')
コード例 #2
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(validate.text, validate.transform(lambda x: int(x, 16))),
                    "publickey_mod": validate.all(validate.text, validate.transform(lambda x: int(x, 16))),
                    "success": True,
                    "timestamp": validate.text,
                    "token_gid": validate.text
                }
            )
        )

        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"]
コード例 #3
0
ファイル: twitch.py プロジェクト: Billy2011/streamlink-27
    def _get_hls_streams(self, url, restricted_bitrates, **extra_params):
        time_offset = self.params.get("t", 0)
        if time_offset:
            try:
                time_offset = hours_minutes_seconds(time_offset)
            except ValueError:
                time_offset = 0

        try:
            streams = TwitchHLSStream.parse_variant_playlist(
                self.session, url, start_offset=time_offset, **extra_params)
        except IOError as err:
            err = str(err)
            if "404 Client Error" in err or "Failed to parse playlist" in err:
                return
            else:
                raise PluginError(err)

        for name in restricted_bitrates:
            if name not in streams:
                log.warning(
                    "The quality '{0}' is not available since it requires a subscription."
                    .format(name))

        return streams
コード例 #4
0
ファイル: test_hls.py プロジェクト: Billy2011/streamlink-27
 def test_variant_playlist(self):
     streams = self.subject("hls/test_master.m3u8")
     self.assertEqual(
         [str(key) for key in streams.keys()],
         [u"720p", u"720p_alt", u"480p", u"360p", u"160p", u"1080p (source)", u"90k"],
         "Finds all streams in master playlist",
     )
     self.assertTrue(all([isinstance(stream, HLSStream) for stream in streams.values()]), "Returns HLSStream instances")
コード例 #5
0
ファイル: twitch.py プロジェクト: Billy2011/streamlink-27
 def parse_tag_ext_x_daterange(self, value):
     super(TwitchM3U8Parser, self).parse_tag_ext_x_daterange(value)
     daterange = self.m3u8.dateranges[-1]
     is_ad = (daterange.classname == "twitch-stitched-ad"
              or str(daterange.id or "").startswith("stitched-ad-") or any(
                  attr_key.startswith("X-TV-TWITCH-AD-")
                  for attr_key in daterange.x.keys()))
     if is_ad:
         self.m3u8.dateranges_ads.append(daterange)
コード例 #6
0
    def _get_streams(self):
        root = self.session.http.get(self.url, schema=validate.Schema(
            validate.parse_html()
        ))

        video_id = root.xpath("string(.//div[@data-provider='dvideo'][@data-id][1]/@data-id)")
        if video_id:
            return self._get_streams_api(str(video_id))

        yt_id = root.xpath("string(.//script[contains(@src,'/yt.js')][@data-video]/@data-video)")
        if yt_id:
            return self.session.streams("https://www.youtube.com/watch?v={0}".format(yt_id))

        yt_iframe = root.xpath("string(.//iframe[starts-with(@src,'https://www.youtube.com/')][1]/@src)")
        if yt_iframe:
            return self.session.streams(str(yt_iframe))

        delfi = root.xpath("string(.//iframe[@name='delfi-stream'][@src][1]/@src)")
        if delfi:
            return self._get_streams_delfi(str(delfi))
コード例 #7
0
    def __init__(self, *args, **kwargs):
        SegmentedStreamWorker.__init__(self, *args, **kwargs)
        self.stream = self.reader.stream

        self.playlist_changed = False
        self.playlist_end = None
        self.playlist_sequence = -1
        self.playlist_sequences = []
        self.playlist_reload_time = 15
        self.playlist_reload_time_override = self.session.options.get(
            "hls-playlist-reload-time")
        self.playlist_reload_retries = self.session.options.get(
            "hls-playlist-reload-attempts")
        self.live_edge = self.session.options.get("hls-live-edge")
        self.duration_offset_start = int(self.stream.start_offset + (
            self.session.options.get("hls-start-offset") or 0))
        self.duration_limit = self.stream.duration or (
            int(self.session.options.get("hls-duration"))
            if self.session.options.get("hls-duration") else None)
        self.hls_live_restart = self.stream.force_restart or self.session.options.get(
            "hls-live-restart")

        if str(self.playlist_reload_time_override).isnumeric() and float(
                self.playlist_reload_time_override) >= 2:
            self.playlist_reload_time_override = float(
                self.playlist_reload_time_override)
        elif self.playlist_reload_time_override not in [
                "segment", "live-edge"
        ]:
            self.playlist_reload_time_override = 0

        self.reload_playlist()

        if self.playlist_end is None:
            if self.duration_offset_start > 0:
                log.debug(
                    "Time offsets negative for live streams, skipping back {0} seconds",
                    self.duration_offset_start)
            # live playlist, force offset durations back to None
            self.duration_offset_start = -self.duration_offset_start

        if self.duration_offset_start != 0:
            self.playlist_sequence = self.duration_to_sequence(
                self.duration_offset_start, self.playlist_sequences)

        if self.playlist_sequences:
            log.debug("First Sequence: {0}; Last Sequence: {1}",
                      self.playlist_sequences[0].num,
                      self.playlist_sequences[-1].num)
            log.debug(
                "Start offset: {0}; Duration: {1}; Start Sequence: {2}; End Sequence: {3}",
                self.duration_offset_start, self.duration_limit,
                self.playlist_sequence, self.playlist_end)
コード例 #8
0
ファイル: formatter.py プロジェクト: Billy2011/streamlink-27
    def _format(self, string, mapper, defaults):
        # type: (str, Callable[[str], str], Dict[str, str]) -> str
        result = []

        for literal_text, field_name, format_spec, conversion in _stringformatter.parse(
                string):
            if literal_text:
                result.append(literal_text)

            if field_name is None:
                continue

            value = self._get_value(field_name, format_spec, defaults)
            result.append(mapper(str(value)))

        return "".join(result)
コード例 #9
0
    def _supports_param(self, param, timeout=5.0):
        try:
            rtmpdump = self.spawn(dict(help=True), timeout=timeout, stderr=subprocess.PIPE)
        except StreamError as err:
            raise StreamError("Error while checking rtmpdump compatibility: {0}".format(err.message))

        for line in rtmpdump.stderr.readlines():
            m = re.match(r"^--(\w+)", str(line, "ascii"))

            if not m:
                continue

            if m.group(1) == param:
                return True

        return False
コード例 #10
0
ファイル: rtmpdump.py プロジェクト: sheldon0531/streamlink
    def _supports_param(self, param, timeout=5.0):
        try:
            rtmpdump = self.spawn(dict(help=True), timeout=timeout, stderr=subprocess.PIPE)
        except StreamError as err:
            raise StreamError("Error while checking rtmpdump compatibility: {0}".format(err.message))

        for line in rtmpdump.stderr.readlines():
            m = re.match(r"^--(\w+)", str(line, "ascii"))

            if not m:
                continue

            if m.group(1) == param:
                return True

        return False
コード例 #11
0
    def generate(self):
        if not self.stream.swf:
            raise StreamError("A SWF URL is required to create session token")

        res = self.stream.session.http.get(self.stream.swf,
                                           exception=StreamError)
        data = swfdecompress(res.content)

        md5 = hashlib.md5()
        md5.update(data)

        data = bytes(self.stream.sessionid, "ascii") + md5.digest()
        sig = hmac.new(b"foo", data, hashlib.sha1)
        b64 = base64.encodestring(sig.digest())
        token = str(b64, "ascii").replace("\n", "")

        return token
コード例 #12
0
    def handshake(self, fd):
        try:
            self.flv = FLV(fd)
        except FLVError as err:
            raise StreamError(str(err))

        self.buffer.write(self.flv.header.serialize())
        log.debug("Attempting to handshake")

        for i, tag in enumerate(self.flv):
            if i == 10:
                raise StreamError(
                    "No OnEdge metadata in FLV after 10 tags, probably not a AkamaiHD stream"
                )

            self.process_tag(tag, exception=StreamError)

            if self.completed_handshake:
                log.debug("Handshake successful")
                break
コード例 #13
0
ファイル: rtmpdump.py プロジェクト: sheldon0531/streamlink
    def _update_redirect(self, stderr):
        tcurl, redirect = None, None
        stderr = str(stderr, "utf8")

        m = re.search(r"DEBUG: Property: <Name:\s+redirect,\s+STRING:\s+(\w+://.+?)>", stderr)
        if m:
            redirect = m.group(1)

        if redirect:
            log.debug("Found redirect tcUrl: {0}", redirect)

            if "rtmp" in self.parameters:
                tcurl, playpath = rtmpparse(self.parameters["rtmp"])
                if playpath:
                    rtmp = "{redirect}/{playpath}".format(redirect=redirect, playpath=playpath)
                else:
                    rtmp = redirect
                self.parameters["rtmp"] = rtmp

            if "tcUrl" in self.parameters:
                self.parameters["tcUrl"] = redirect
コード例 #14
0
    def _update_redirect(self, stderr):
        tcurl, redirect = None, None
        stderr = str(stderr, "utf8")

        m = re.search(r"DEBUG: Property: <Name:\s+redirect,\s+STRING:\s+(\w+://.+?)>", stderr)
        if m:
            redirect = m.group(1)

        if redirect:
            log.debug("Found redirect tcUrl: {0}", redirect)

            if "rtmp" in self.parameters:
                tcurl, playpath = rtmpparse(self.parameters["rtmp"])
                if playpath:
                    rtmp = "{redirect}/{playpath}".format(redirect=redirect, playpath=playpath)
                else:
                    rtmp = redirect
                self.parameters["rtmp"] = rtmp

            if "tcUrl" in self.parameters:
                self.parameters["tcUrl"] = redirect
コード例 #15
0
    def _get_streams(self):
        is_live = self.match.group("is_live")
        parsed_html = self.session.http.get(self.url, schema=validate.Schema(validate.parse_html()))

        if is_live:
            uvid = self._get_live_uvid(parsed_html)
            if not uvid or not uvid.isdecimal():
                return
            token_data = self._get_tokenizer("live", uvid)
            self.id = uvid
            self.author = "Blaze"
            self.title = "Live TV"
            self.category = "Live"
        else:
            data = self._get_vod_uvid(parsed_html)
            if not data["id"] or not data["id"].isdecimal():
                return
            token_data = self._get_tokenizer("replay", data["id"])
            self.id = data["id"]
            self.author = data["series_title"]
            self.title = data["title"]
            self.category = "S{0}E{1}".format(data['season'], data['episode'])

        log.trace("token_data={0!r}".format(token_data))

        hls_url = self.session.http.get(
            token_data["url"],
            headers={
                "Token": token_data["token"],
                "Token-Expiry": str(token_data["expiry"]),
                "Uvid": token_data["uvid"],
            },
            schema=validate.Schema(
                validate.parse_json(),
                {"Streams": {"Adaptive": validate.url()}},
                validate.get(("Streams", "Adaptive")),
            ),
        )
        return HLSStream.parse_variant_playlist(self.session, hls_url)
コード例 #16
0
    def open(self):
        self.guid = cache_bust_string(12)
        self.islive = None
        self.sessionid = None
        self.flv = None

        self.buffer = Buffer()
        self.completed_handshake = False

        url = self.StreamURLFormat.format(host=self.host,
                                          streamname=self.streamname)
        params = self._create_params(seek=self.seek)

        log.debug("Opening host={} streamname={}", self.host, self.streamname)

        try:
            res = self.session.http.get(url, stream=True, params=params)
            self.fd = StreamIOIterWrapper(res.iter_content(8192))
        except Exception as err:
            raise StreamError(str(err))

        self.handshake(self.fd)

        return self
コード例 #17
0
    def _get_api_data(self, type, slug, filter=None):
        log.debug("slug={0}".format(slug))
        app_version = self.session.http.get(
            self.url,
            schema=validate.Schema(
                validate.parse_html(),
                validate.xml_xpath_string(
                    ".//head/meta[@name='appVersion']/@content"),
                validate.any(None, validate.text),
            ),
        )
        if not app_version:
            return

        log.debug("app_version={0}".format(app_version))

        return self.session.http.get(
            "https://boot.pluto.tv/v4/start",
            params={
                "appName": "web",
                "appVersion": app_version,
                "deviceVersion": "94.0.0",
                "deviceModel": "web",
                "deviceMake": "firefox",
                "deviceType": "web",
                "clientID": str(uuid4()),
                "clientModelNumber": "1.0",
                type: slug,
            },
            schema=validate.Schema(
                validate.parse_json(),
                {
                    "servers": {
                        "stitcher": validate.url(),
                    },
                    validate.optional("EPG"): [{
                        "name": validate.text,
                        "id": validate.text,
                        "slug": validate.text,
                        "stitched": {
                            "path": validate.text,
                        },
                    }],
                    validate.optional("VOD"): [{
                        "name":
                        validate.text,
                        "id":
                        validate.text,
                        "slug":
                        validate.text,
                        "genre":
                        validate.text,
                        "stitched": {
                            "path": validate.text,
                        },
                        validate.optional("seasons"): [{
                            "episodes":
                            validate.all(
                                [{
                                    "name": validate.text,
                                    "_id": validate.text,
                                    "slug": validate.text,
                                    "stitched": {
                                        "path": validate.text,
                                    },
                                }],
                                validate.filter(
                                    lambda k: filter and k["slug"] == filter),
                            ),
                        }],
                    }],
                    "sessionToken":
                    validate.text,
                    "stitcherParams":
                    validate.text,
                },
            ),
        )
コード例 #18
0
ファイル: plugin.py プロジェクト: Billy2011/streamlink-27
 def get_id(self):
     # type: () -> Optional[str]
     return None if self.id is None else str(self.id).strip()
コード例 #19
0
ファイル: plugin.py プロジェクト: Billy2011/streamlink-27
 def get_title(self):
     # type: () -> Optional[str]
     return None if self.title is None else str(self.title).strip()
コード例 #20
0
ファイル: plugin.py プロジェクト: Billy2011/streamlink-27
 def get_author(self):
     # type: () -> Optional[str]
     return None if self.author is None else str(self.author).strip()
コード例 #21
0
ファイル: plugin.py プロジェクト: Billy2011/streamlink-27
 def get_category(self):
     # type: () -> Optional[str]
     return None if self.category is None else str(self.category).strip()
コード例 #22
0
ファイル: streann.py プロジェクト: Billy2011/streamlink-27
 def time(self):
     res = self.session.http.get(self.get_time_url)
     data = self.session.http.json(res)
     return str(data.get("serverTime", int(time.time() * 1000)))