Beispiel #1
0
    def _get_streams(self):
        res = http.get(self.url)
        match = _embed_re.search(res.text)
        if match:
            res = http.get(match.group(1))

        match = _aptoma_id_re.search(res.text)
        if not match:
            return

        aptoma_id = match.group(1)
        if not _live_re.search(res.text):
            res = http.get(METADATA_URL.format(aptoma_id))
            metadata = http.json(res)
            video_id = metadata["videoId"]
        else:
            video_id = aptoma_id

        res = http.get(VIDEO_INFO_URL, params=dict(id=video_id))
        video = http.json(res, schema=_video_schema)
        streams = {}
        for fmt, providers in video["formats"].items():
            for name, provider in providers.items():
                for ext, playlists in provider.items():
                    for playlist in playlists:
                        url = PLAYLIST_URL_FORMAT.format(**playlist)
                        parser = STREAM_TYPES[fmt]

                        try:
                            streams.update(parser(self.session, url))
                        except IOError as err:
                            self.logger.error("Failed to extract {0} streams: {1}",
                                              fmt.upper(), err)

        return streams
Beispiel #2
0
    def _choose_server(self, json):
        res = http.get(self.GEOIPURL)
        loc = http.json(res)
        loc = [loc["latitude"], loc["longitude"]]
        sel_dist = float("inf")
        i = 0
        primary = -1
        secondary = -1

        for server in json["server"]:
            res = http.get(self.GEOURL+server["server"]["name"]+"&sensor=false")
            cord = http.json(res)
            cord = [cord["results"][0]["geometry"]["location"]["lat"], cord["results"][0]["geometry"]["location"]["lng"]]
            cur_dist = self._distance(loc, cord)

            if cur_dist < sel_dist:
                sel_dist = cur_dist

                if server["server"]["used"] < 90:
                    # nearest server with load < 90%
                    primary = i
                else:
                    # nearest server with load > 90%
                    secondary = i

            i += 1

        if primary == -1:
            # if all servers have load over 90% use nearest one
            return secondary

        return primary
Beispiel #3
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        if not match:
            return

        channel, media_id = match.group("channel", "media_id")
        if channel != "video":
            res = http.get(LIVE_API.format(channel))
            livestream = http.json(res, schema=_live_schema)
            if not livestream["media_is_live"]:
                return

            media_id = livestream["media_id"]
            media_type = "live"
        else:
            media_type = "video"

        res = http.get(PLAYER_API.format(media_type, media_id))
        player = http.json(res, schema=_player_schema)
        if media_type == "live":
            swf_url = SWF_URL
            for playlist in player.get("playlist", []):
                bitrates = playlist.get("bitrates")
                provider = playlist.get("connectionProvider")
                rtmp = None

                if bitrates:
                    rtmp = playlist.get("netConnectionUrl")
                elif provider and provider in player["plugins"]:
                    provider = player["plugins"][provider]
                    swf_name = provider["url"]
                    swf_url = SWF_BASE + swf_name
                    rtmp = provider["netConnectionUrl"]
                    bitrates = player["clip"]["bitrates"]
                else:
                    continue

                for bitrate in bitrates:
                    quality = self._get_quality(bitrate["label"])
                    url = bitrate["url"]
                    stream = RTMPStream(self.session, {
                        "rtmp": rtmp,
                        "pageUrl": self.url,
                        "playpath": url,
                        "swfVfy": swf_url,
                        "live": True
                    })
                    yield quality, stream
        else:
            base_url = player["clip"]["baseUrl"] or VOD_BASE_URL
            for bitrate in player["clip"]["bitrates"]:
                url = base_url + "/" + bitrate["url"]
                quality = self._get_quality(bitrate["label"])

                if urlparse(url).path.endswith("m3u8"):
                    stream = HLSStream(self.session, url)
                else:
                    stream = HTTPStream(self.session, url)

                yield quality, stream
Beispiel #4
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        media_is_live = 0

        match = re.search(r".*hitbox.tv/([^/]*)/?(\d+)?", self.url)
        if not match:
            raise NoStreamsError(self.url)

        stream_name, media_id = match.groups()

        if stream_name != "video":
            res = http.get(LIVE_API.format(stream_name))
            json = http.json(res)
            livestream = verifyjson(json, "livestream")
            media_id = verifyjson(livestream[0], "media_id")
            media_is_live = int(verifyjson(livestream[0], "media_is_live"))
            if not media_is_live:
                raise NoStreamsError(self.url)

        media_type = "live" if media_is_live else "video"
        res = http.get(PLAYER_API.format(media_type, media_id))
        json = http.json(res)
        clip = verifyjson(json, "clip")
        live = verifyjson(clip, "live")
        bitrates = verifyjson(clip, "bitrates")

        streams = {}
        if live:
            for bitrate in bitrates:
                connection_provider = clip.get("connectionProvider",
                                               "clustering")
                plugins = verifyjson(json, "plugins")
                provider_plugin = verifyjson(plugins, connection_provider)
                swf = verifyjson(provider_plugin, "url")
                rtmp = verifyjson(provider_plugin, "netConnectionUrl")
                quality = self._get_quality(verifyjson(bitrate, "label"))
                url = verifyjson(bitrate, "url")

                streams[quality] = RTMPStream(
                    self.session, {
                        "rtmp": rtmp,
                        "pageUrl": self.url,
                        "playpath": url,
                        "swfVfy": SWF_BASE + swf,
                        "live": True
                    })
        else:
            for bitrate in bitrates:
                base_url = verifyjson(clip, "baseUrl")
                url = verifyjson(bitrate, "url")
                quality = self._get_quality(verifyjson(bitrate, "label"))
                streams[quality] = HTTPStream(self.session,
                                              base_url + "/" + url)

        return streams
Beispiel #5
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        media_is_live = 0

        match = re.search(r".*hitbox.tv/([^/]*)/?(\d+)?", self.url)
        if not match:
            raise NoStreamsError(self.url)

        stream_name, media_id = match.groups()

        if stream_name != "video":
            res = http.get(LIVE_API.format(stream_name))
            json = http.json(res)
            livestream = verifyjson(json, "livestream")
            media_id = verifyjson(livestream[0], "media_id")
            media_is_live = int(verifyjson(livestream[0], "media_is_live"))
            if not media_is_live:
                raise NoStreamsError(self.url)

        media_type = "live" if media_is_live else "video"
        res = http.get(PLAYER_API.format(media_type, media_id))
        json = http.json(res)
        clip = verifyjson(json, "clip")
        live = verifyjson(clip, "live")
        bitrates = verifyjson(clip, "bitrates")

        streams = {}
        if live:
            for bitrate in bitrates:
                connection_provider = clip.get("connectionProvider", "clustering")
                plugins = verifyjson(json, "plugins")
                provider_plugin = verifyjson(plugins, connection_provider)
                swf = verifyjson(provider_plugin, "url")
                rtmp = verifyjson(provider_plugin, "netConnectionUrl")
                quality = self._get_quality(verifyjson(bitrate, "label"))
                url = verifyjson(bitrate, "url")

                streams[quality] = RTMPStream(self.session, {
                    "rtmp": rtmp,
                    "pageUrl": self.url,
                    "playpath": url,
                    "swfVfy": SWF_BASE + swf,
                    "live": True
                })
        else:
            for bitrate in bitrates:
                base_url = verifyjson(clip, "baseUrl")
                url = verifyjson(bitrate, "url")
                quality = self._get_quality(verifyjson(bitrate, "label"))
                streams[quality] = HTTPStream(self.session,
                                              base_url + "/" + url)

        return streams
Beispiel #6
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        media_is_live = 0

        match = re.search(r".*hitbox.tv/([^/]*)/?(\d+)?", self.url)
        if not match:
            return

        stream_name, media_id = match.groups()
        if stream_name != "video":
            res = http.get(LIVE_API.format(stream_name))
            json = http.json(res)
            livestream = verifyjson(json, "livestream")
            media_id = verifyjson(livestream[0], "media_id")
            media_is_live = int(verifyjson(livestream[0], "media_is_live"))
            if not media_is_live:
                return

        media_type = "live" if media_is_live else "video"
        res = http.get(PLAYER_API.format(media_type, media_id))
        json = http.json(res)
        clip = verifyjson(json, "clip")
        live = verifyjson(clip, "live")

        streams = {}
        if live:
            playlists = verifyjson(json, "playlist") or []
            for playlist in filter(valid_playlist, playlists):
                bitrates = playlist.get("bitrates")
                rtmp = playlist.get("netConnectionUrl")
                for bitrate in bitrates:
                    quality = self._get_quality(verifyjson(bitrate, "label"))
                    url = verifyjson(bitrate, "url")
                    streams[quality] = RTMPStream(self.session, {
                        "rtmp": rtmp,
                        "pageUrl": self.url,
                        "playpath": url,
                        "swfVfy": SWF_URL,
                        "live": True
                    })
        else:
            bitrates = verifyjson(clip, "bitrates")
            for bitrate in bitrates:
                base_url = verifyjson(clip, "baseUrl")
                url = verifyjson(bitrate, "url")
                quality = self._get_quality(verifyjson(bitrate, "label"))
                streams[quality] = HTTPStream(self.session,
                                              base_url + "/" + url)

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

        ts = int(time.time() / 60)
        sign = hashlib.md5(
            ("{0}{1}{2}".format(channel, API_SECRET,
                                ts)).encode("utf-8")).hexdigest()

        res = http.get(API_URL.format(channel, ts, sign))
        room = http.json(res, schema=_room_schema)
        if not room:
            return

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

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

        for name, url in room["rtmp_multi_bitrate"].items():
            url = "{room[rtmp_url]}/{url}".format(room=room, url=url)
            stream = HTTPStream(self.session, url)
            yield name, stream
Beispiel #8
0
    def _get_live_streams(self, slug):
        res = http.get(LIVE_CHANNELS_API_URL)
        res = http.json(res, schema=_channels_schema)

        for channel in filter(lambda c: c["Slug"] == slug, res):
            servers = channel["StreamingServers"]
            return self._parse_streaming_servers(servers)
Beispiel #9
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 #10
0
    def _get_streams(self):
        info = http.get(self.url, schema=_schema)
        if not info:
            return

        headers = {"Referer": self.url}
        res = http.get(info["token_url"], headers=headers)
        token = http.json(res, schema=_token_schema)

        parsed = urlparse(info["rtmp_url"])
        if parsed.query:
            app = "{0}?{1}".format(parsed.path[1:], parsed.query)
        else:
            app = parsed.path[1:]

        params = {
            "rtmp": info["rtmp_url"],
            "app": app,
            "pageUrl": self.url,
            "swfVfy": info["swf_url"],
            "playpath": info["rtmp_playpath"],
            "token": token,
            "live": True
        }

        stream = RTMPStream(self.session, params)
        return dict(live=stream)
    def _api_call(self, entrypoint, params):
        '''Makes a call against the api.
        :param entrypoint: API method to call.
        :param params: parameters to include in the request data.
        '''
        url = API_URL.format(entrypoint)

        # default params
        params.update({
            'version': API_VERSION,
            'locale': API_LOCALE,
        })

        if self.session_id:
            params['session_id'] = self.session_id

        # The certificate used by Crunchyroll cannot be verified in some
        # environments.
        response = http.get(url, params=params, headers=API_HEADERS,
                            verify=False)
        json_response = http.json(response)

        if json_response['error']:
            raise APIError(json_response['message'])

        return json_response
    def _get_player_params(self, retries=5):
        match = _url_re.match(self.url)
        domain = match.group('domain')
        try:
            res = http.get(CHANNEL_INFO_URL % str(domain))
        except PluginError as err:
            # The server sometimes gives us 404 for no reason
            if "404" in str(err) and retries:
                sleep(1)
                return self._get_player_params(retries - 1)
            else:
                raise
        channel_info = http.json(res)
        channel_info = channel_info['data']

        reference_id = channel_info['reference_id']

        is_live = channel_info['status']
        if is_live == "ACTIVE":
            is_live = True
        else:
            is_live = False

        player_id = channel_info['id']

        return reference_id, player_id, is_live
Beispiel #13
0
    def _get_live_streams(self, slug):
        res = http.get(LIVE_CHANNELS_API_URL)
        res = http.json(res, schema=_channels_schema)

        for channel in filter(lambda c: c["Slug"] == slug, res):
            servers = channel["StreamingServers"]
            return self._parse_streaming_servers(servers)
Beispiel #14
0
 def _get_stream_info(self, broadcast, type):
     params = {
         "return_type": "gs_cdn",
         "broad_key": "{broadcast}-flash-hd-{type}".format(**locals())
     }
     res = http.get(STREAM_INFO_URLS[type], params=params)
     return http.json(res, schema=_stream_schema)
Beispiel #15
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 #16
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 #17
0
    def _get_vod_stream(self, movie_id):
        res = http.get(VODINFO_URL.format(movie_id), headers=AJAX_HEADERS)
        json = http.json(res)
        json = json and json.get("data")
        json = json and json.get("streams")

        if not json:
            raise NoStreamsError(self.url)

        streams = {}
        for quality in ("low", "high"):
            stream = json.get(quality)
            if not stream:
                continue

            rtmp = stream.get("url")
            app = self._get_rtmp_app(rtmp)
            if not app:
                continue

            playpath = stream.get("name")
            if ".mp4" in playpath:
                playpath = "mp4:" + playpath

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

        return streams
Beispiel #18
0
 def _get_stream_info(self, broadcast, type):
     params = {
         "return_type": "gs_cdn",
         "broad_key": "{broadcast}-flash-hd-{type}".format(**locals())
     }
     res = http.get(STREAM_INFO_URLS[type], params=params)
     return http.json(res, schema=_stream_schema)
Beispiel #19
0
    def _get_streams(self):
        res = http.get(self.url)
        channel_id = self._find_channel_id(res.text)
        if not channel_id:
            return

        stream_id = self._get_stream_id(channel_id)
        if not stream_id:
            return

        res = http.get(STREAM_API_URL.format(stream_id),
                       params=dict(format="all"))
        json = http.json(res)
        data = verifyjson(json, "data")
        items = verifyjson(data, "items")

        streams = {}
        for stream in filter(valid_stream, items):
            parser = STREAM_TYPES[stream["format"]]

            try:
                streams.update(parser(self.session, stream["url"]))
            except IOError as err:
                if not re.search(r"(404|400) Client Error", str(err)):
                    self.logger.error("Failed to extract {0} streams: {1}",
                                      stream["format"].upper(), err)

        return streams
Beispiel #20
0
    def _create_flv_playlist(self, template):
        res = http.get(template)
        json = http.json(res)

        if not isinstance(json, dict):
            raise PluginError("Invalid JSON response")

        parsed = urlparse(template)
        try:
            url_template = '{0}://{1}{2}'.format(parsed.scheme, parsed.netloc,
                                                 json['template'])
            segment_max = reduce(lambda i, j: i + j[0], json['fragments'], 0)
            duration = json['duration']
        except KeyError:
            raise PluginError('Unexpected JSON response')

        substreams = [
            HTTPStream(self.session,
                       url_template.replace('$fragment$', str(i)))
            for i in range(1, segment_max + 1)
        ]

        return FLVPlaylist(self.session,
                           streams=substreams,
                           duration=duration,
                           skip_header=True,
                           flatten_timestamps=True)
Beispiel #21
0
    def _get_streams(self):
        res = http.get(self.url)
        channel_id = self._find_channel_id(res.text)
        if not channel_id:
            return

        stream_id = self._get_stream_id(channel_id)
        if not stream_id:
            return

        res = http.get(STREAM_API_URL.format(stream_id),
                       params=dict(format="all"))
        items = http.json(res, schema=_stream_schema)
        streams = {}
        for stream in items:
            parser = STREAM_TYPES[stream["format"]]

            try:
                streams.update(parser(self.session, stream["url"]))
            except IOError as err:
                if not re.search(r"(404|400) Client Error", str(err)):
                    self.logger.error("Failed to extract {0} streams: {1}",
                                      stream["format"].upper(), err)

        return streams
Beispiel #22
0
    def _api_call(self, entrypoint, params, schema=None):
        """Makes a call against the api.

        :param entrypoint: API method to call.
        :param params: parameters to include in the request data.
        :param schema: schema to use to validate the data
        """
        url = API_URL.format(entrypoint)

        # Default params
        params = dict(params)
        params.update({
            "version": API_VERSION,
            "locale": API_LOCALE,
        })

        if self.session_id:
            params["session_id"] = self.session_id

        # The certificate used by Crunchyroll cannot be verified in some environments.
        res = http.get(url, params=params, headers=API_HEADERS, verify=False)
        json_res = http.json(res, schema=_api_schema)

        if json_res["error"]:
            err_msg = json_res.get("message", "Unknown error")
            err_code = json_res.get("code", "unknown_error")
            raise CrunchyrollAPIError(err_msg, err_code)

        data = json_res.get("data")
        if schema:
            data = schema.validate(data, name="API response")

        return data
    def _get_streams(self):
        res = http.get(self.url, schema=_schema)
        if not res:
            return
        owner = res["vars"]["owner"]
        token = res["vars"].get("token", "null")
        swf_url = res["swf"]

        # Check if the stream is online
        res = http.get(CHANNEL_DETAILS_URI.format(owner, token))
        channel_details = http.json(res, schema=_channel_details_schema)
        if not channel_details["channel"]["live"]:
            return

        stream_ip = http.get(REDIRECT_SERVICE_URI.format(owner)).text

        streams = {}
        streams["live"] = RTMPStream(
            self.session,
            {
                "rtmp": RTMP_URL.format(stream_ip, channel_details["channel"]["slug"]),
                "pageUrl": self.url,
                "swfUrl": urljoin(self.url, swf_url),
                "live": True,
            },
        )
        return streams
Beispiel #24
0
    def _get_vod_stream(self, movie_id):
        res = http.get(VODINFO_URL.format(movie_id), headers=AJAX_HEADERS)
        json = http.json(res)
        json = json and json.get("data")
        json = json and json.get("streams")

        if not json:
            raise NoStreamsError(self.url)

        streams = {}
        for quality in ("low", "high"):
            stream = json.get(quality)
            if not stream:
                continue

            rtmp = stream.get("url")
            app = self._get_rtmp_app(rtmp)
            if not app:
                continue

            playpath = stream.get("name")
            if ".mp4" in playpath:
                playpath = "mp4:" + playpath

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

        return streams
Beispiel #25
0
    def _get_streams(self):
        parsed = urlparse(self.url)

        if parsed.fragment:
            channelid = parsed.fragment
        elif "/v/" in parsed.path:
            channelid = parsed.path.rpartition("/v/")[-1]
        else:
            channelid = parsed.path.rpartition("view/")[-1]

        if not channelid:
            raise NoStreamsError(self.url)

        channelid = channelid.lower().replace("/", "_")

        self.logger.debug("Fetching stream info")
        res = http.get(self.APIURL.format(channelid))
        json = http.json(res)

        if not isinstance(json, dict):
            raise PluginError("Invalid JSON response")
        elif not ("success" in json and "payload" in json):
            raise PluginError("Invalid JSON response")
        elif json["success"] == False:
            raise NoStreamsError(self.url)

        streams = {}
        streams["live"] = HTTPStream(self.session, json["payload"])

        return streams
Beispiel #26
0
    def _get_player_params(self, retries=5):
        match = _url_re.match(self.url);
        domain = match.group('domain');
        try:
            res = http.get(CHANNEL_INFO_URL % str(domain))
        except PluginError as err:
            # The server sometimes gives us 404 for no reason
            if "404" in str(err) and retries:
                sleep(1)
                return self._get_player_params(retries - 1)
            else:
                raise
        channel_info = http.json(res)
        channel_info = channel_info['data']

        key = channel_info['player_key'];

        is_live = channel_info['is_live'];

        stream_video = channel_info['stream_video']
        if stream_video:
            video_player = "ref:" + stream_video['reference_id']
        else:
            is_live = False

        player_id = channel_info['player_id']

        return key, video_player, player_id, is_live
Beispiel #27
0
    def _api_call(self, entrypoint, params, schema=None):
        """Makes a call against the api.

        :param entrypoint: API method to call.
        :param params: parameters to include in the request data.
        :param schema: schema to use to validate the data
        """
        url = API_URL.format(entrypoint)

        # Default params
        params = dict(params)
        params.update({
            "version": API_VERSION,
            "locale": API_LOCALE,
        })

        if self.session_id:
            params["session_id"] = self.session_id

        # The certificate used by Crunchyroll cannot be verified in some environments.
        res = http.get(url, params=params, headers=API_HEADERS, verify=False)
        json_res = http.json(res, schema=_api_schema)

        if json_res["error"]:
            err_msg = json_res.get("message", "Unknown error")
            err_code = json_res.get("code", "unknown_error")
            raise CrunchyrollAPIError(err_msg, err_code)

        data = json_res.get("data")
        if schema:
            data = schema.validate(data, name="API response")

        return data
    def _get_vod_streams(self, channelname):
        res = http.get(self.url)
        match = re.search('autoURL%22%3A%22(.*?)%22', res.text)
        if not match:
            raise PluginError('Error retrieving manifest url')
        manifest_url = unquote(match.group(1)).replace('\\', '')

        try:
            res = http.get(manifest_url)
            manifest = http.json(res)
        except:
            raise PluginError('Error retrieving manifest')

        # A fallback host (http://proxy-xx...) is sometimes provided
        # that we could make us of.
        streams = {}
        for params in manifest.get('alternates', []):
            name = params.get('name')
            template = params.get('template')
            if not (name and template):
                continue

            name = '{0}p'.format(name)
            streams[name] = self._create_flv_playlist(template)

        return streams
Beispiel #29
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        parsed = urlparse(self.url)
        if parsed.fragment:
            channel_id = parsed.fragment
        else:
            channel_id = match.group("channel")

        if not channel_id:
            return

        channel_id = channel_id.lower().replace("/", "_")
        res = http.get(API_URL.format(channel_id))
        info = http.json(res, schema=_schema)

        if not info["success"]:
            return

        if info.get("isLive"):
            name = "live"
        else:
            name = "vod"

        stream = HTTPStream(self.session, info["payload"])
        # Wrap the stream in a FLVPlaylist to verify the FLV tags
        stream = FLVPlaylist(self.session, [stream])

        return {name: stream}
Beispiel #30
0
    def _get_player_params(self, retries=5):
        match = _url_re.match(self.url)
        domain = match.group('domain')
        try:
            res = http.get(CHANNEL_INFO_URL % str(domain))
        except PluginError as err:
            # The server sometimes gives us 404 for no reason
            if "404" in str(err) and retries:
                sleep(1)
                return self._get_player_params(retries - 1)
            else:
                raise
        channel_info = http.json(res)
        channel_info = channel_info['data']

        key = channel_info['player_key']

        is_live = channel_info['is_live']

        stream_video = channel_info['stream_video']
        if stream_video:
            video_player = "ref:" + stream_video['reference_id']
        else:
            is_live = False

        player_id = channel_info['player_id']

        return key, video_player, player_id, is_live
Beispiel #31
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 #32
0
    def _get_streams_from_media(self, media_id):
        res = http.get(STREAM_INFO_URL.format(media_id), cookies=COOKIES)
        media = http.json(res, schema=_media_schema)

        params = extra_params = swf_url = None
        for __ in media:
            for __ in __["layerList"]:
                for __ in __.get("sequenceList", []):
                    for layer in __["layerList"]:
                        name = layer["name"]
                        if name == "video":
                            params = layer.get("param")
                        elif name == "reporting":
                            extra_params = layer.get("param", {})
                            extra_params = extra_params.get("extraParams", {})

        if not params:
            return

        if extra_params:
            swf_url = extra_params.get("videoSwfURL")

        mode = params.get("mode")
        if mode == "live":
            return self._get_live_streams(params, swf_url)
        elif mode == "vod":
            return self._get_vod_streams(params)
Beispiel #33
0
    def _get_streams(self):
        res = http.get(self.url, schema=_schema)
        if not res:
            return
        owner = res["vars"]["owner"]
        token = res["vars"].get("token", "null")
        swf_url = res["swf"]

        # Check if the stream is online
        res = http.get(CHANNEL_DETAILS_URI.format(owner, token))
        channel_details = http.json(res, schema=_channel_details_schema)
        if not channel_details["channel"]["live"]:
            return

        stream_ip = http.get(REDIRECT_SERVICE_URI.format(owner)).text

        streams = {}
        streams["live"] = RTMPStream(
            self.session, {
                "rtmp":
                RTMP_URL.format(stream_ip, channel_details["channel"]["slug"]),
                "pageUrl":
                self.url,
                "swfUrl":
                urljoin(self.url, swf_url),
                "live":
                True
            })
        return streams
Beispiel #34
0
    def _get_vod_streams(self, channelname):
        res = http.get(self.url)
        match = re.search('autoURL%22%3A%22(.*?)%22', res.text)
        if not match:
            raise PluginError('Error retrieving manifest url')
        manifest_url = unquote(match.group(1)).replace('\\', '')

        try:
            res = http.get(manifest_url)
            manifest = http.json(res)
        except:
            raise PluginError('Error retrieving manifest')

        # A fallback host (http://proxy-xx...) is sometimes provided
        # that we could make us of.
        streams = {}
        for params in manifest.get('alternates', []):
            name = params.get('name')
            template = params.get('template')
            if not (name and template):
                continue

            name = '{0}p'.format(name)
            streams[name] = self._create_flv_playlist(template)

        return streams
Beispiel #35
0
    def _get_stream_info(self, assign_url, cdn, quality, broad_key, type):
        headers = {
            "Referer": self.url,
        }
        params = {
            "rtmp": {
                "return_type":
                cdn,
                "use_cors":
                "true",
                "cors_origin_url":
                "play.afreecatv.com",
                "broad_key":
                "{broad_key}-flash-{quality}-{type}".format(
                    broad_key=broad_key, quality=quality, type=type),
                "time":
                1234.56
            },
            "hls": {
                "return_type":
                cdn,
                "use_cors":
                "true",
                "cors_origin_url":
                "play.afreecatv.com",
                "broad_key":
                "{broad_key}-flash-{quality}-{type}".format(
                    broad_key=broad_key, quality=quality, type=type),
                "time":
                1234.56
            }
        }
        res = http.get(assign_url, params=params[type], headers=headers)

        return http.json(res, schema=_stream_schema)
Beispiel #36
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 #37
0
    def _get_streams_from_media(self, media_id):
        res = http.get(STREAM_INFO_URL.format(media_id), cookies=COOKIES)
        media = http.json(res, schema=_media_schema)

        params = extra_params = swf_url = None
        for __ in media:
            for __ in __["layerList"]:
                for __ in __.get("sequenceList", []):
                    for layer in __["layerList"]:
                        name = layer["name"]
                        if name == "video":
                            params = layer.get("param")
                        elif name == "reporting":
                            extra_params = layer.get("param", {})
                            extra_params = extra_params.get("extraParams", {})

        if not params:
            return

        if extra_params:
            swf_url = extra_params.get("videoSwfURL")

        mode = params.get("mode")
        if mode == "live":
            return self._get_live_streams(params, swf_url)
        elif mode == "vod":
            return self._get_vod_streams(params)
Beispiel #38
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 #39
0
    def _get_streams(self):
        country_code = urlparse(self.url).netloc.split(".")[0]

        self.logger.debug("Fetching stream info")
        res = http.get(self.APIURL)
        json = http.json(res)

        if not isinstance(json, dict):
            raise PluginError("Invalid JSON response")
        elif not ("primary" in json or "secondary" in json):
            raise PluginError("Invalid JSON response")

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

        streams = {}

        self.logger.debug("Euronews Countries:{0}", " ".join(json["primary"].keys()))

        if not (country_code in json["primary"] or country_code in json["secondary"]):
            res = http.get(self.GEOIPURL)
            geo = http.json(res)
            if isinstance(json, dict) and "country_code" in geo:
                country_code = geo["country_code"].lower()
                if not (country_code in json["primary"] or country_code in json["secondary"]):
                    country_code = "en"
            else:
                country_code = "en"

        for site in ("primary", "secondary"):
            for quality in json[site][country_code]["rtmp_flash"]:
                stream = json[site][country_code]["rtmp_flash"][quality]
                name = quality + "k"
                if site == "secondary":
                    name += "_alt"
                streams[name] = RTMPStream(self.session, {
                    "rtmp": stream["server"],
                    "playpath" : stream["name"],
                    "swfUrl": self.SWFURL,
                    "live": True
                })

        if len(streams) == 0:
            raise NoStreamsError(self.url)

        return streams
Beispiel #40
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 #41
0
    def _get_vod_streams(self, movie_id):
        for stream_type in STREAM_TYPES:
            cookies = {"flash-player-type": stream_type}
            res = ajax(VODINFO_URL.format(movie_id), cookies=cookies)
            vod = http.json(res, schema=_vod_schema)

            # TODO: Replace with "yield from" when dropping Python 2.
            for stream in self._parse_vod_streams(vod):
                yield stream
Beispiel #42
0
def get_json(url):
    """Fetch page for given URL and return json Python object.

    :param url: URL to fetch

    """
    res = http.get(url)

    return http.json(res)
Beispiel #43
0
    def _get_rtmp_streams(self, text):
        match = re.search("streamer=(rtmp://.+?)&", text)
        if not match:
            raise PluginError(
                ("No RTMP streamer found on URL {0}").format(self.url))

        rtmp = match.group(1)

        match = re.search("<meta content=\"(http://.+?\.swf)\?", text)
        if not match:
            self.logger.warning(
                "Failed to get player SWF URL location on URL {0}", self.url)
        else:
            self.SWFURL = match.group(1)
            self.logger.debug("Found player SWF URL location {0}", self.SWFURL)

        match = re.search("<meta content=\"(.+)\" name=\"item-id\" />", text)
        if not match:
            raise PluginError(
                ("Missing channel item-id on URL {0}").format(self.url))

        res = http.get(self.APIURL.format(match.group(1), time()),
                       params=dict(output="json"))
        json = http.json(res)

        if not isinstance(json, list):
            raise PluginError("Invalid JSON response")

        rtmplist = {}

        for jdata in json:
            if "stream_name" not in jdata or "type" not in jdata:
                continue

            if "rtmp" not in jdata["type"]:
                continue

            playpath = jdata["stream_name"]

            if "token" in jdata and jdata["token"]:
                playpath += jdata["token"]

            if len(json) == 1:
                stream_name = "live"
            else:
                stream_name = jdata["stream_name"]

            rtmplist[stream_name] = RTMPStream(
                self.session, {
                    "rtmp": rtmp,
                    "pageUrl": self.url,
                    "swfVfy": self.SWFURL,
                    "playpath": playpath,
                    "live": True
                })

        return rtmplist
Beispiel #44
0
    def _get_streams(self):
        res = http.get(self.url, params=dict(output="json"))
        videos = http.json(res, schema=_video_schema)

        mapper = StreamMapper(cmp=lambda type, video: video["playerType"] == type)
        mapper.map("ios", self._create_streams, "HLS", HLSStream.parse_variant_playlist)
        mapper.map("flash", self._create_streams, "HDS", HDSStream.parse_manifest)

        return mapper(videos)
Beispiel #45
0
    def _get_stream_info(self, url):
        res = http.get(url, headers=HEADERS)
        match = re.search("embed.swf\?p=(\d+)", res.text)
        if not match:
            return
        program = match.group(1)
        res = http.get(BEAT_PROGRAM.format(program), headers=HEADERS)

        return http.json(res, schema=_schema)
Beispiel #46
0
    def _get_streams(self):
        res = http.get(DATA_URL)
        data = http.json(res, schema=_data_schema)
        video_id = data["channel"] or data["channel2"]
        if not video_id:
            return

        url = "http://youtu.be/v/{0}".format(video_id)
        return self.session.streams(url)
Beispiel #47
0
    def _get_stream_info(self, url):
        res = http.get(url, headers=HEADERS)
        match = re.search("embed.swf\?p=(\d+)", res.text)
        if not match:
            return
        program = match.group(1)
        res = http.get(BEAT_PROGRAM.format(program), headers=HEADERS)

        return http.json(res)
Beispiel #48
0
    def _get_channel_id(self, domain):
        channel_info = http.get(CHANNEL_INFO_URL % str(domain))
        info = http.json(channel_info, schema=_channel_schema)
        if info is None:
            return False
        cnid = info['channel']['vid']
        if cnid <= 0:
            return False

        return cnid
Beispiel #49
0
    def _extract_streams(self, stream_id):
        res = http.get(STREAM_API_URL.format(stream_id), raise_for_status=False)
        stream_info = http.json(res, schema=_stream_schema)

        mapper = StreamMapper(lambda pattern, video: re.search(pattern, video[1]))
        mapper.map(r"\.m3u8$", self._create_dynamic_streams, "HLS", HLSStream.parse_variant_playlist)
        mapper.map(r"\.f4m$", self._create_dynamic_streams, "HDS", HDSStream.parse_manifest)
        mapper.map(r"^rtmp://", self._create_rtmp_stream)

        return mapper(stream_info.items())
Beispiel #50
0
    def _get_vod_streams(self, name):
        res = http.get(API_URL.format("videos", name))
        json = http.json(res, schema=_vod_schema)
        if not json:
            return

        streams = {}
        streams["source"] = self._create_rtmp_stream(VOD_RTMP_URL.format(json["channel_slug"]), json["name"], True)

        return streams
Beispiel #51
0
    def _get_live_streams(self, channel_id):
        params = {"channel_id": channel_id}
        for stream_type in STREAM_TYPES:
            cookies = {"flash-player-type": stream_type}
            res = ajax(CHINFO_URL, cookies=cookies, data=params)
            channel = http.json(res, schema=_channel_schema)

            # TODO: Replace with "yield from" when dropping Python 2.
            for stream in self._parse_live_streams(channel):
                yield stream