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
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
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
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
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
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
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
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)
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"])
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
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)
def _get_channel_info(self, username): data = { "bid": username } res = http.post(CHANNEL_INFO_URL, data=data) return http.json(res, schema=_channel_schema)
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 })
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
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
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)
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
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
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
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
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
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
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}
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
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)
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)
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
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)
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 })
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
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
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)
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
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)
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
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)
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)
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)
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)
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
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())
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
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