Beispiel #1
0
    def _get_broadcast(self, username):
        data = {
            "szBjId": username
        }
        res = http.post(BROAD_INFO_URL, headers=HEADERS, data=data)

        return http.json(res, schema=_broadcast_schema)
Beispiel #2
0
    def _get_stream(self, channel_id, quality):
        params = dict(channel_id=channel_id, quality=quality)
        res = http.post(CHINFO_URL, data=params, headers=AJAX_HEADERS)
        json = http.json(res)

        if not json:
            raise NoStreamsError(self.url)

        rtmp = json.get("serverURL")
        playpath = json.get("streamName")
        if not (rtmp and playpath):
            raise NoStreamsError(self.url)

        app = self._get_rtmp_app(rtmp)
        if not app:
            raise NoStreamsError(self.url)

        return RTMPStream(
            self.session, {
                "rtmp": rtmp,
                "pageUrl": self.url,
                "swfUrl": SWF_URL,
                "playpath": playpath,
                "app": app,
                "live": True
            })
Beispiel #3
0
    def _authenticate(self, email, password):
        csrf_token = http.get(LOGIN_PAGE_URL, schema=_csrf_token_schema)
        if not csrf_token:
            raise PluginError("Unable to find CSRF token")

        data = {
            "authenticity_token": csrf_token,
            "channel_id": "",
            "commit": "Login",
            "plan_id": "",
            "session[email]": email,
            "session[password]": password,
            "utf8": "\xE2\x9C\x93",  # Check Mark Character
        }

        res = http.post(LOGIN_POST_URL,
                        data=data,
                        acceptable_status=(200, 422))
        result = http.json(res, schema=_login_schema)

        errors = result.get("errors")
        if errors:
            errors = ", ".join(errors)
            raise PluginError("Unable to authenticate: {0}".format(errors))

        self.logger.info("Successfully logged in as {0}", result["email"])
Beispiel #4
0
    def _get_stream(self, channel_id, quality):
        params = dict(channel_id=channel_id, quality=quality)
        res = http.post(CHINFO_URL, data=params, headers=AJAX_HEADERS)
        json = http.json(res)

        if not json:
            raise NoStreamsError(self.url)

        rtmp = json.get("serverURL")
        playpath = json.get("streamName")
        if not (rtmp and playpath):
            raise NoStreamsError(self.url)

        app = self._get_rtmp_app(rtmp)
        if not app:
            raise NoStreamsError(self.url)

        return RTMPStream(self.session, {
            "rtmp": rtmp,
            "pageUrl": self.url,
            "swfUrl": SWF_URL,
            "playpath": playpath,
            "app": app,
            "live": True
        })
Beispiel #5
0
    def _get_channel_info(self, username):
        data = {
            "bid": username
        }
        res = http.post(CHANNEL_INFO_URL, data=data)

        return http.json(res, schema=_channel_schema)
Beispiel #6
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        channel = match.group("channel")

        http.headers.update({"User-Agent": USER_AGENT})
        room_id = http.get(self.url, schema=_room_id_schema)
        channel = room_id["room_id"]
        res = http.get(MAPI_URL.format(channel))
        room = http.json(res, schema=_room_schema)
        if not room:
            return

        if room["show_status"] != SHOW_STATUS_ONLINE:
            return

        ts = int(time.time() / 60)
        did = uuid.uuid4().hex.upper()
        sign = hashlib.md5(
            ("{0}{1}{2}{3}".format(channel, did, LAPI_SECRET,
                                   ts)).encode("utf-8")).hexdigest()

        data = {"cdn": "ws", "rate": "0", "tt": ts, "did": did, "sign": sign}

        res = http.post(LAPI_URL.format(channel), data=data)
        room = http.json(res, schema=_lapi_schema)

        url = "{room[rtmp_url]}/{room[rtmp_live]}".format(room=room)
        stream = HTTPStream(self.session, url)
        yield "source", stream

        data = {"cdn": "ws", "rate": "2", "tt": ts, "did": did, "sign": sign}

        res = http.post(LAPI_URL.format(channel), data=data)
        room = http.json(res, schema=_lapi_schema)

        url = "{room[rtmp_url]}/{room[rtmp_live]}".format(room=room)
        stream = HTTPStream(self.session, url)
        yield "middle", stream

        data = {"cdn": "ws", "rate": "1", "tt": ts, "did": did, "sign": sign}

        res = http.post(LAPI_URL.format(channel), data=data)
        room = http.json(res, schema=_lapi_schema)

        url = "{room[rtmp_url]}/{room[rtmp_live]}".format(room=room)
        stream = HTTPStream(self.session, url)
        yield "low", stream
Beispiel #7
0
    def _send_amf_request(self, req, key):
        headers = {
            "content-type": "application/x-amf"
        }
        res = http.post(AMF_GATEWAY, data=bytes(req.serialize()),
                        headers=headers, params=dict(playerKey=key))

        return AMFPacket.deserialize(BytesIO(res.content))
Beispiel #8
0
    def _send_amf_request(self, req, key):
        headers = {"content-type": "application/x-amf"}
        res = http.post(AMF_GATEWAY,
                        data=bytes(req.serialize()),
                        headers=headers,
                        params=dict(playerKey=key))

        return AMFPacket.deserialize(BytesIO(res.content))
Beispiel #9
0
 def _get_channel_info(self, bid):
     headers = {
         "Referer": "http://play.afreecatv.com",
         "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
     }
     params = {"bid": bid}
     res = http.post(CHANNEL_INFO_URL, data=params, headers=headers)
     #print res.text
     return http.json(res, schema=_channel_schema)
Beispiel #10
0
    def _get_channel_info(self, username):
        headers = {
            "Referer": self.url
        }
        data = {
            "uid": username
        }
        res = http.post(CHANNEL_INFO_URL, data=data, headers=headers)

        return http.json(res, schema=_channel_schema)
Beispiel #11
0
    def _get_streams(self):
        """
            Find all the streams for the ITV url
            :return: Mapping of quality to stream
        """
        soap_message = self._soap_request()

        headers = {
            'Content-Length': '{0:d}'.format(len(soap_message)),
            'Content-Type': 'text/xml; charset=utf-8',
            'Host': 'mercury.itv.com',
            'Origin': 'http://www.itv.com',
            'Referer':
            'http://www.itv.com/Mercury/Mercury_VideoPlayer.swf?v=null',
            'SOAPAction': "http://tempuri.org/PlaylistService/GetPlaylist",
            'User-Agent': ITV_PLAYER_USER_AGENT,
            "X-Requested-With": "ShockwaveFlash/16.0.0.305"
        }

        res = http.post("http://mercury.itv.com/PlaylistService.svc?wsdl",
                        headers=headers,
                        data=soap_message)

        # looking for the <MediaFiles> tag
        xmldoc = http.xml(res)

        mediafiles = xmldoc.find(".//VideoEntries//MediaFiles")
        # No mediafiles, no streams
        if not mediafiles:
            return None

        rtmp = mediafiles.attrib['base']
        streams = {}

        for mediafile in mediafiles.findall("MediaFile"):
            playpath = mediafile.find("URL").text

            rtmp_url = urlparse(rtmp)
            app = (rtmp_url.path[1:] + '?' + rtmp_url.query).rstrip('?')
            live = app == "live"

            params = dict(
                rtmp="{u.scheme}://{u.netloc}{u.path}".format(u=rtmp_url),
                app=app.rstrip('?'),
                playpath=playpath,
                swfVfy=LIVE_SWF_URL if live else ONDEMAND_SWF_URL,
                timeout=10)
            if live:
                params['live'] = True

            bitrate = int(mediafile.attrib['bitrate']) / 1000
            quality = "{0}k".format(bitrate)
            streams[quality] = RTMPStream(self.session, params)

        return streams
Beispiel #12
0
    def _get_streams(self):
        # If email option given, try to login
        if self.options.get("email"):
            res = http.get(self.LOGINPAGEURL)
            match = re.search('<meta content="([^"]+)" name="csrf-token"',
                              res.text)
            if not match:
                raise PluginError("Missing CSRF Token: " + self.LOGINPAGEURL)
            csrf_token = match.group(1)

            email = self.options.get("email")
            password = self.options.get("password")

            res = http.post(
                self.LOGINPOSTURL,
                data={
                    'authenticity_token': csrf_token,
                    'channel_id': '',
                    'commit': 'Login',
                    'plan_id': '',
                    'session[email]': email,
                    'session[password]': password,
                    'utf8': "\xE2\x9C\x93",  # Check Mark Character
                })

            self.logger.debug("Login account info: {0}", res.text)
            result = http.json(res)
            if result.get('email', 'no-mail') != email:
                raise PluginError("Invalid account")

        res = http.get(self.url)

        streams = {}

        if RTMPStream.is_usable(self.session):
            try:
                rtmpstreams = self._get_rtmp_streams(res.text)
                streams.update(rtmpstreams)
            except PluginError as err:
                self.logger.error("Error when fetching RTMP stream info: {0}",
                                  str(err))
        else:
            self.logger.warning(
                "rtmpdump is not usable, only HLS streams will be available")

        try:
            hlsstreams = self._get_hls_streams(res.text)
            streams.update(hlsstreams)
        except PluginError as err:
            self.logger.error("Error when fetching HLS stream info: {0}",
                              str(err))

        return streams
Beispiel #13
0
    def _get_streams(self):
        """
            Find all the streams for the ITV url
            :return: Mapping of quality to stream
        """
        soap_message = self._soap_request()

        headers = {
            "Content-Length": "{0:d}".format(len(soap_message)),
            "Content-Type": "text/xml; charset=utf-8",
            "Host": "mercury.itv.com",
            "Origin": "http://www.itv.com",
            "Referer": "http://www.itv.com/Mercury/Mercury_VideoPlayer.swf?v=null",
            "SOAPAction": "http://tempuri.org/PlaylistService/GetPlaylist",
            "User-Agent": ITV_PLAYER_USER_AGENT,
            "X-Requested-With": "ShockwaveFlash/16.0.0.305",
        }

        res = http.post("http://mercury.itv.com/PlaylistService.svc?wsdl", headers=headers, data=soap_message)

        # looking for the <MediaFiles> tag
        xmldoc = http.xml(res)

        mediafiles = xmldoc.find(".//VideoEntries//MediaFiles")
        # No mediafiles, no streams
        if not mediafiles:
            return None

        rtmp = mediafiles.attrib["base"]
        streams = {}

        for mediafile in mediafiles.findall("MediaFile"):
            playpath = mediafile.find("URL").text

            rtmp_url = urlparse(rtmp)
            app = (rtmp_url.path[1:] + "?" + rtmp_url.query).rstrip("?")
            live = app == "live"

            params = dict(
                rtmp="{u.scheme}://{u.netloc}{u.path}".format(u=rtmp_url),
                app=app.rstrip("?"),
                playpath=playpath,
                swfVfy=LIVE_SWF_URL if live else ONDEMAND_SWF_URL,
                timeout=10,
            )
            if live:
                params["live"] = True

            bitrate = int(mediafile.attrib["bitrate"]) / 1000
            quality = "{0}k".format(bitrate)
            streams[quality] = RTMPStream(self.session, params)

        return streams
Beispiel #14
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        channel_name = match.group("channel")

        form = {
            "cid": channel_name,
            "watchTime": 0,
            "firstConnect": 1,
            "ip": "NaN"
        }
        res = http.post(API_URL, data=form, headers=HEADERS)
        params = parse_query(res.text, schema=_schema)

        if params["status"] <= 0:
            return

        if params["block_type"] != 0:
            if params["block_type"] == BLOCK_TYPE_VIEWING_LIMIT:
                msg = BLOCKED_MSG_FORMAT.format(
                    params.get("block_time", "UNKNOWN"),
                    params.get("reconnect_time", "UNKNOWN"))
                raise PluginError(msg)
            elif params["block_type"] == BLOCK_TYPE_NO_SLOTS:
                raise PluginError("No free slots available")
            else:
                raise PluginError("Blocked for unknown reasons")

        if "token" not in params:
            raise PluginError("Server seems busy, retry again later")

        streams = {}
        stream_names = ["sd"]
        if params["multibitrate"]:
            stream_names += ["hd"]

        for stream_name in stream_names:
            playpath = params["playpath"]
            if stream_name == "hd":
                playpath += "HI"

            stream = RTMPStream(
                self.session, {
                    "rtmp": "{0}/{1}".format(params["rtmp"], playpath),
                    "pageUrl": self.url,
                    "swfVfy": SWF_URL,
                    "weeb": params["token"],
                    "live": True
                })
            streams[stream_name] = stream

        return streams
Beispiel #15
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        channel_name = match.group("channel")

        form = {
            "cid": channel_name,
            "watchTime": 0,
            "firstConnect": 1,
            "ip": "NaN"
        }
        res = http.post(API_URL, data=form, headers=HEADERS)
        params = parse_query(res.text, schema=_schema)

        if params["status"] <= 0:
            return

        if params["block_type"] != 0:
            if params["block_type"] == BLOCK_TYPE_VIEWING_LIMIT:
                msg = BLOCKED_MSG_FORMAT.format(
                    params.get("block_time", "UNKNOWN"),
                    params.get("reconnect_time", "UNKNOWN")
                )
                raise PluginError(msg)
            elif params["block_type"] == BLOCK_TYPE_NO_SLOTS:
                raise PluginError("No free slots available")
            else:
                raise PluginError("Blocked for unknown reasons")

        if "token" not in params:
            raise PluginError("Server seems busy, retry again later")

        streams = {}
        stream_names = ["sd"]
        if params["multibitrate"]:
            stream_names += ["hd"]

        for stream_name in stream_names:
            playpath = params["playpath"]
            if stream_name == "hd":
                playpath += "HI"

            stream = RTMPStream(self.session, {
                "rtmp": "{0}/{1}".format(params["rtmp"], playpath),
                "pageUrl": self.url,
                "swfVfy": SWF_URL,
                "weeb": params["token"],
                "live": True
            })
            streams[stream_name] = stream

        return streams
    def _get_streams(self):
        # If email option given, try to login
        if self.options.get("email"):
            res = http.get(self.LOGINPAGEURL)
            match = re.search('<meta content="([^"]+)" name="csrf-token"', res.text)
            if not match:
                raise PluginError("Missing CSRF Token: " + self.LOGINPAGEURL)
            csrf_token = match.group(1)

            email = self.options.get("email")
            password = self.options.get("password")

            res = http.post(
                self.LOGINPOSTURL,
                data={
                    "authenticity_token": csrf_token,
                    "channel_id": "",
                    "commit": "Login",
                    "plan_id": "",
                    "session[email]": email,
                    "session[password]": password,
                    "utf8": "\xE2\x9C\x93",  # Check Mark Character
                },
            )

            self.logger.debug("Login account info: {0}", res.text)
            result = http.json(res)
            if result.get("email", "no-mail") != email:
                raise PluginError("Invalid account")

        res = http.get(self.url)

        streams = {}

        if RTMPStream.is_usable(self.session):
            try:
                rtmpstreams = self._get_rtmp_streams(res.text)
                streams.update(rtmpstreams)
            except PluginError as err:
                self.logger.error("Error when fetching RTMP stream info: {0}", str(err))
        else:
            self.logger.warning("rtmpdump is not usable, only HLS streams will be available")

        try:
            hlsstreams = self._get_hls_streams(res.text)
            streams.update(hlsstreams)
        except PluginError as err:
            self.logger.error("Error when fetching HLS stream info: {0}", str(err))

        return streams
Beispiel #17
0
    def _get_hls_key(self, broad_key, bid):
        headers = {
            "Referer": self.url,
            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
        }
        data = {
            "bid": bid,
            "bno": broad_key,
            "type": "pwd",
            "player_type": "html5",
            "quality": quality,
        }
        res = http.post(CHANNEL_INFO_URL, data=data, headers=headers)

        return http.json(res, schema=_channel_aid_schema)
Beispiel #18
0
    def _get_live_streams(self, channel_id):
        params = dict(channel_id=channel_id)
        res = http.post(CHINFO_URL, data=params, headers=AJAX_HEADERS)
        channel = http.json(res, schema=_channel_schema)

        streams = {}
        for stream in channel["streams"]:
            name = stream["quality"]
            rtmp = stream["url"]
            playpath = stream["name"]
            app = self._get_rtmp_app(rtmp)

            stream = RTMPStream(self.session, {
                "rtmp": rtmp,
                "pageUrl": self.url,
                "swfUrl": SWF_URL,
                "playpath": playpath,
                "app": app,
                "live": True
            })
            streams[name] = stream

        return streams
Beispiel #19
0
    def _authenticate(self, email, password):
        csrf_token = http.get(LOGIN_PAGE_URL, schema=_csrf_token_schema)
        if not csrf_token:
            raise PluginError("Unable to find CSRF token")

        data = {
            "authenticity_token": csrf_token,
            "channel_id": "",
            "commit": "Login",
            "plan_id": "",
            "session[email]": email,
            "session[password]": password,
            "utf8": "\xE2\x9C\x93", # Check Mark Character
        }

        res = http.post(LOGIN_POST_URL, data=data, acceptable_status=(200, 422))
        result = http.json(res, schema=_login_schema)

        errors = result.get("errors")
        if errors:
            errors = ", ".join(errors)
            raise PluginError("Unable to authenticate: {0}".format(errors))

        self.logger.info("Successfully logged in as {0}", result["email"])
Beispiel #20
0
    def _resolve_stream(self):
        res = http.get(self.url)
        match = _data_stream_re.search(res.text)
        if not match:
            return
        data_stream = match.group(1)

        resolve_data = {
            'stream': data_stream
        }
        res = http.post(
            'http://www-ipv4.nos.nl/livestream/resolve/',
            data=json.dumps(resolve_data)
        )
        data = http.json(res)

        res = http.get(data['url'])
        match = _js_re.search(res.text)
        if not match:
            return

        stream_url = parse_json(match.group(1))

        return HLSStream.parse_variant_playlist(self.session, stream_url)
Beispiel #21
0
    def _get_live_streams(self, channel_id):
        params = dict(channel_id=channel_id)
        res = http.post(CHINFO_URL, data=params, headers=AJAX_HEADERS)
        channel = http.json(res, schema=_channel_schema)

        streams = {}
        for stream in channel["streams"]:
            name = stream["quality"]
            rtmp = stream["url"]
            playpath = stream["name"]
            app = self._get_rtmp_app(rtmp)

            stream = RTMPStream(
                self.session, {
                    "rtmp": rtmp,
                    "pageUrl": self.url,
                    "swfUrl": SWF_URL,
                    "playpath": playpath,
                    "app": app,
                    "live": True
                })
            streams[name] = stream

        return streams
Beispiel #22
0
def ajax(*args, **kwargs):
    kwargs["headers"] = AJAX_HEADERS
    return http.post(*args, **kwargs)
Beispiel #23
0
    def _get_channel_info(self, username):
        data = {"bid": username}
        res = http.post(CHANNEL_INFO_URL, data=data)

        return http.json(res, schema=_channel_schema)
Beispiel #24
0
    def _get_streams(self):
        channelname = urlparse(self.url).path.rstrip("/").rpartition("/")[-1].lower()
        self.logger.debug("Fetching stream info")

        headers = {
            "Referer": self.SWFURL
        }

        form = dict(cid=channelname, watchTime="0",
                    firstConnect="1", ip="NaN")

        res = http.post(self.APIURL, data=form, headers=headers)

        params = parse_qsd(res.text)

        if "0" in params and int(params["0"]) <= 0:
            raise PluginError("Server refused to send required parameters.")

        rtmp = params["10"]
        playpath = params["11"]
        multibitrate = int(params["20"])
        premiumuser = params["5"]
        blocktype = int(params["13"])

        if blocktype != 0:
            if blocktype == 1:
                blocktime = params["14"]
                reconnectiontime = params["16"]
                msg = ("You have crossed free viewing limit. ",
                       "You have been blocked for %s minutes. " % blocktime,
                       "Try again in %s minutes." % reconnectiontime)
                raise PluginError(msg)
            elif blocktype == 11:
                raise PluginError("No free slots available.")

        if "73" in params:
            token = params["73"]
        else:
            raise PluginError("Server seems busy, please try after some time.")

        if not RTMPStream.is_usable(self.session):
            raise PluginError("rtmpdump is not usable and required by Weeb plugin")

        streams = {}
        stream_name = "sd"

        if multibitrate:
            streams[stream_name] = RTMPStream(self.session, {
                "rtmp": "{0}/{1}".format(rtmp, playpath),
                "pageUrl": self.url,
                "swfVfy": self.SWFURL,
                "weeb": token,
                "live": True
            })
            playpath += "HI"
            stream_name = "hd"

        streams[stream_name] = RTMPStream(self.session, {
            "rtmp": "{0}/{1}".format(rtmp, playpath),
            "pageUrl": self.url,
            "swfVfy": self.SWFURL,
            "weeb": token,
            "live": True
        })

        return streams
Beispiel #25
0
    def _get_streams(self):
        channelname = urlparse(
            self.url).path.rstrip("/").rpartition("/")[-1].lower()
        self.logger.debug("Fetching stream info")

        headers = {"Referer": self.SWFURL}

        form = dict(cid=channelname, watchTime="0", firstConnect="1", ip="NaN")

        res = http.post(self.APIURL, data=form, headers=headers)

        params = parse_qsd(res.text)

        if "0" in params and int(params["0"]) <= 0:
            raise PluginError("Server refused to send required parameters.")

        rtmp = params["10"]
        playpath = params["11"]
        multibitrate = int(params["20"])
        premiumuser = params["5"]
        blocktype = int(params["13"])

        if blocktype != 0:
            if blocktype == 1:
                blocktime = params["14"]
                reconnectiontime = params["16"]
                msg = ("You have crossed free viewing limit. ",
                       "You have been blocked for %s minutes. " % blocktime,
                       "Try again in %s minutes." % reconnectiontime)
                raise PluginError(msg)
            elif blocktype == 11:
                raise PluginError("No free slots available.")

        if "73" in params:
            token = params["73"]
        else:
            raise PluginError("Server seems busy, please try after some time.")

        if not RTMPStream.is_usable(self.session):
            raise PluginError(
                "rtmpdump is not usable and required by Weeb plugin")

        streams = {}
        stream_name = "sd"

        if multibitrate:
            streams[stream_name] = RTMPStream(
                self.session, {
                    "rtmp": "{0}/{1}".format(rtmp, playpath),
                    "pageUrl": self.url,
                    "swfVfy": self.SWFURL,
                    "weeb": token,
                    "live": True
                })
            playpath += "HI"
            stream_name = "hd"

        streams[stream_name] = RTMPStream(
            self.session, {
                "rtmp": "{0}/{1}".format(rtmp, playpath),
                "pageUrl": self.url,
                "swfVfy": self.SWFURL,
                "weeb": token,
                "live": True
            })

        return streams
Beispiel #26
0
    def _get_broadcast(self, username):
        data = {"szBjId": username}
        res = http.post(BROAD_INFO_URL, headers=HEADERS, data=data)

        return http.json(res, schema=_broadcast_schema)