def _get_rtmp_streams(self, swfurl): if not RTMPStream.is_usable(self.session): raise NoStreamsError(self.url) self.logger.debug("Fetching RTMP stream info") res = http.get(swfurl) swf = swfdecompress(res.content) match = re.search("customURL[^h]+(https://.*?)\\\\", swf) if not match: raise NoStreamsError(self.url) res = http.get(match.group(1)) rtmp, playpath = rtmpparse(res.text) params = { "rtmp": rtmp, "pageUrl": self.url, "playpath": playpath, "live": True } match = re.search("file[^h]+(https?://.*?.swf)", swf) if match: params["swfUrl"] = match.group(1) return RTMPStream(self.session, params)
def _get_streams(self): self.logger.debug("Fetching stream info") res = http.get(self.url) match = re.search("\"User_channelid\".+?value=\"(.+?)\"", res.text) if not match: raise NoStreamsError(self.url) headers = {"Referer": self.url} res = http.get(self.PlayerURL.format(match.group(1)), headers=headers) match = re.search("stream:\s+'(rtmp://.+?)'", res.text) if not match: raise NoStreamsError(self.url) rtmp = match.group(1) streams = {} streams["live"] = RTMPStream(self.session, { "rtmp": rtmp, "pageUrl": self.url, "swfVfy": self.SWFURL, "live": True }) return streams
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): res = http.get(self.StreamURL, data={"from": "ongamenet"}) match = re.search("var stream = \"(.+?)\";", res.text) if not match: raise NoStreamsError(self.url) stream = match.group(1) match = re.search("var server = \"(.+?)\";", res.text) if not match: raise NoStreamsError(self.url) server = match.group(1) streams = {} streams["live"] = RTMPStream( self.session, { "rtmp": server, "playpath": stream, "swfUrl": self.SWFURL, "pageUrl": self.PageURL, "live": True, }) return streams
def _get_streams(self): self.logger.debug("Fetching stream info") info = self._get_stream_info() if not info: raise NoStreamsError(self.url) streaminfo = verifyjson(info, "stream_info") if not streaminfo: raise NoStreamsError(self.url) qualities = verifyjson(streaminfo, "qualities") streams = {} if not streaminfo["is_live"]: raise NoStreamsError(self.url) if "play_url" in streaminfo: smil = self._parse_smil(streaminfo["play_url"]) for bitrate, stream in smil.items(): sname = "{0}k".format(bitrate/1000) for quality in qualities: if quality["bitrate"] == bitrate: sname = "{0}p".format(quality["height"]) streams[sname] = stream return streams
def _get_streams(self): parsed = urlparse(self.url) if parsed.fragment: channelid = parsed.fragment 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 = urlget(self.APIURL.format(channelid)) json = res_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_streams(self): channelname = self._get_channel_name(self.url) if not channelname: raise NoStreamsError(self.url) if not self._check_channel_live(channelname): raise NoStreamsError(self.url) return self._get_rtmp_streams(channelname)
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 = urlget(LIVE_API.format(stream_name)) json = res_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 = urlget(PLAYER_API.format(media_type, media_id)) json = res_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") res = urlget(self.url) match = re.search("var current_channel = (.*);", res.text) if match: json = parse_json(match.group(1)) else: raise NoStreamsError(self.url) if not isinstance(json, dict): raise PluginError("Invalid JSON response") elif not "streams" in json: raise NoStreamsError(self.url) if not RTMPStream.is_usable(self.session): raise PluginError( "rtmpdump is not usable and required by Filmon plugin") match = re.search("var flash_config = (.*);", res.text) if match: config = parse_json(match.group(1)) if "streamer" in config: self.SWFURL = urljoin(self.SWFURL, config["streamer"]) streams = {} for stream in json["streams"]: if not ("url" in stream and "name" in stream): continue parsed = urlparse(stream["url"]) if not parsed.scheme.startswith("rtmp"): continue if parsed.query: app = "{0}?{1}".format(parsed.path[1:], parsed.query) else: app = parsed.path[1:] name = stream["quality"] streams[name] = RTMPStream( self.session, { "rtmp": stream["url"], "pageUrl": self.url, "swfUrl": self.SWFURL, "playpath": stream["name"], "app": app, "live": True }) return streams
def _get_streams_from_rtmp(self): password = self.options.get("password") module_info = self._get_module_info("channel", self.channel_id, password) if not module_info: raise NoStreamsError(self.url) providers = module_info.get("stream") if providers == "offline": raise NoStreamsError(self.url) elif not isinstance(providers, list): raise PluginError("Invalid stream info: {0}".format(providers)) streams = {} for provider in filter(valid_provider, providers): provider_url = provider.get("url") provider_name = provider.get("name") provider_streams = provider.get("streams") for stream_index, stream_info in enumerate(provider_streams): stream = None stream_height = int(stream_info.get("height", 0)) stream_name = stream_info.get("description") if not stream_name: if stream_height: if not stream_info.get("isTranscoded"): stream_name = "{0}p+".format(stream_height) else: stream_name = "{0}p".format(stream_height) else: stream_name = "live" if stream_name in streams: provider_name_clean = provider_name.replace("uhs_", "") stream_name += "_alt_{0}".format(provider_name_clean) if provider_name.startswith("uhs_"): stream = UHSStream(self.session, self.channel_id, self.url, provider_name, stream_index, password) elif (provider_url.startswith("rtmp") and RTMPStream.is_usable(self.session)): playpath = stream_info.get("streamName") stream = self._create_rtmp_stream(provider_url, playpath) if stream: streams[stream_name] = stream return streams
def get_live_streams(self): res = self._get_live_page(self.res) match = re.search("flashvars\s+=\s+({.+?});", res.text) if not match: raise NoStreamsError(self.url) flashvars = parse_json(match.group(1), "flashvars JSON") flashvars["uip"] = self._get_user_ip() levels = re.findall("setFlashLevel\((\d+)\);", res.text) streams = {} for level in levels: params = self._create_gox_params(flashvars, level) res = urlget(self.GOXLiveURL, params=params, session=self.rsession) gox = GOXFile(res.text) for entry in gox.filter_entries("live"): try: s = HDSStream.parse_manifest(self.session, entry.ref[0]) streams.update(s) except IOError: self.logger.warning("Unable to parse manifest") break return streams
def _get_streams(self): channelname = urlparse( self.url).path.rstrip("/").rpartition("/")[-1].lower() self.logger.debug("Fetching stream info") headers = {"Referer": self.url} res = urlget(self.PlayerURL.format(channelname), headers=headers) match = re.search("'FlashVars', '(id=\d+)&", res.text) if not match: raise NoStreamsError(self.url) channelname += "?" + match.group(1) res = urlget(self.BalancerURL, headers=headers) match = re.search("redirect=(.+)", res.text) if not match: raise PluginError( "Error retrieving RTMP address from loadbalancer") rtmp = match.group(1) streams = {} streams["live"] = RTMPStream( self.session, { "rtmp": "rtmp://{0}/live/{1}".format(rtmp, channelname), "pageUrl": self.url, "swfVfy": self.SWFURL, "conn": "S:OK", "live": True }) return streams
def _get_streams(self): self.logger.debug("Fetching stream info") res = urlget(self.url) match = re.search( "flashplayer: \"(.+.swf)\".+streamer: \"(.+)\".+file: \"(.+).flv\"", res.text, re.DOTALL) if not match: raise NoStreamsError(self.url) params = { "rtmp": match.group(2), "pageUrl": self.url, "swfVfy": match.group(1), "playpath": match.group(3), "live": True } match = re.search("(http(s)?://.+/server.php\?id=\d+)", res.text) if match: token_url = match.group(1) res = res_json(urlget(token_url, headers=dict(Referer=self.url))) token = res.get("token") if token: params["token"] = token streams = {} streams["live"] = RTMPStream(self.session, params) 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): channelid = urlparse( self.url).path.rstrip("/").rpartition("/")[-1].lower() self.logger.debug("Fetching stream info") headers = {"Referer": self.url} options = dict(id=channelid) res = urlget(self.StreamInfoURL, headers=headers, params=options) json = res_json(res, "stream info JSON") if not isinstance(json, dict): raise PluginError("Invalid JSON response") if not ("rtmp" in json and "streamname" in json): raise NoStreamsError(self.url) if not RTMPStream.is_usable(self.session): raise PluginError( "rtmpdump is not usable and required by Owncast plugin") rtmp = json["rtmp"] playpath = json["streamname"] streams = {} streams["live"] = RTMPStream( self.session, { "rtmp": rtmp, "pageUrl": self.url, "swfUrl": self.SWFURL, "playpath": playpath, "live": True }) return streams
def _get_streams(self): self.logger.debug("Fetching stream info") res = urlget(self.url) match = re.search( "flashplayer: \"(.+.swf)\".+streamer: \"(.+)\".+file: \"(.+).flv\"", res.text, re.DOTALL) if not match: raise NoStreamsError(self.url) rtmp = match.group(2) playpath = match.group(3) swfurl = match.group(1) streams = {} streams["live"] = RTMPStream(self.session, { "rtmp": rtmp, "pageUrl": self.url, "swfVfy": swfurl, "playpath": playpath, "live": True }, redirect=True) return streams
def _get_streams(self): self.logger.debug("Fetching stream info") res = http.get(self.url) match = re.search("var info = (.*);", res.text) if not match: raise NoStreamsError(self.url) json = parse_json(match.group(1)) if not isinstance(json, dict): return ios_url = json.get("ios_url") swf_url = json.get("swf_url") streams = {} if ios_url: hls = HLSStream.parse_variant_playlist(self.session, ios_url) streams.update(hls) if swf_url: try: streams["live"] = self._get_rtmp_streams(swf_url) except NoStreamsError: pass return streams
def _get_streams(self): parsed = urlparse(self.url) if not parsed.scheme in self.ProtocolMap: raise NoStreamsError(self.url) cls = self.ProtocolMap[parsed.scheme] split = self.url.split(" ") url = split[0] urlnoproto = re.match("^\w+://(.+)", url).group(1) params = (" ").join(split[1:]) params = self._parse_params(params) if cls == RTMPStream: params["rtmp"] = url for boolkey in ("live", "realtime", "quiet", "verbose", "debug"): if boolkey in params: params[boolkey] = bool(params[boolkey]) stream = cls(self.session, params) elif cls == HLSStream.parse_variant_playlist or cls == HDSStream.parse_manifest: return cls(self.session, urlnoproto, **params) else: stream = cls(self.session, urlnoproto, **params) return dict(live=stream)
def _get_streams(self): self.channelname = self._get_channel_name(self.url) if not self.channelname: raise NoStreamsError(self.url) streams = {} if RTMPStream.is_usable(self.session): try: rtmpstreams = self._get_rtmp_streams() 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() for name, stream in hlsstreams.items(): if name in streams: streams[name] = [streams[name], stream] else: streams[name] = stream except PluginError as err: self.logger.error("Error when fetching HLS stream info: {0}", str(err)) return streams
def _get_streams(self): info = self._get_stream_info(self.url) if not info: raise NoStreamsError(self.url) args = verifyjson(info, "args") if not "live_playback" in args or args["live_playback"] == "0": raise NoStreamsError(self.url) streams = {} uestreammap = verifyjson(args, "url_encoded_fmt_stream_map") fmtlist = verifyjson(args, "fmt_list") streammap = self._parse_stream_map(uestreammap) formatmap = self._parse_format_map(fmtlist) for streaminfo in streammap: if not ("url" in streaminfo and "sig" in streaminfo): continue stream = HTTPStream(self.session, streaminfo["url"], params=dict(signature=streaminfo["sig"])) if streaminfo["itag"] in formatmap: quality = formatmap[streaminfo["itag"]] else: quality = streaminfo["quality"] streams[quality] = stream if "hlsvp" in args: url = args["hlsvp"] try: hlsstreams = HLSStream.parse_variant_playlist( self.session, url) streams.update(hlsstreams) except IOError as err: self.logger.warning("Failed to get variant playlist: {0}", err) return streams
def _access_token(self): try: sig, token = self.api.channel_access_token(self.channel) except PluginError as err: if "404 Client Error" in str(err): raise NoStreamsError(self.url) else: raise return sig, token
def _get_streams(self): info = self._get_stream_info(self.url) if not info: raise NoStreamsError(self.url) args = verifyjson(info, "args") streams = {} uestreammap = verifyjson(args, "url_encoded_fmt_stream_map") fmtlist = verifyjson(args, "fmt_list") streammap = self._parse_stream_map(uestreammap) formatmap = self._parse_format_map(fmtlist) for streaminfo in streammap: if "s" in streaminfo and self._decrypt_signature(streaminfo["s"]): streaminfo["sig"] = self._decrypt_signature(streaminfo["s"]) if not ("url" in streaminfo and "sig" in streaminfo): continue stream = HTTPStream(self.session, streaminfo["url"], params=dict(signature=streaminfo["sig"])) if streaminfo["itag"] in formatmap: quality = formatmap[streaminfo["itag"]] else: quality = streaminfo["quality"] if streaminfo.get("stereo3d") == "1": quality += "_3d" streams[quality] = stream if "hlsvp" in args: url = args["hlsvp"] try: hlsstreams = HLSStream.parse_variant_playlist(self.session, url, namekey="pixels") streams.update(hlsstreams) except IOError as err: self.logger.warning("Failed to get variant playlist: {0}", err) if not streams and args.get("live_playback", "0") == "0": self.logger.warning( "VOD support may not be 100% complete. Try youtube-dl instead." ) return streams
def _get_rtmp_streams(self): chansub = self._authenticate() url = self.StreamInfoURL.format(self.channelname) params = dict(b_id="true", group="", private_code="null", p=int(random.random() * 999999), channel_subscription=chansub, type="any") self.logger.debug("Fetching stream info") res = urlget(url, params=params) json = res_json(res, "stream info JSON") if not isinstance(json, list): raise PluginError("Invalid JSON response") if len(json) == 0: raise NoStreamsError(self.url) streams = {} swfurl, swfhash, swfsize = self._verify_swf() for info in json: if not ("connect" in info and "play" in info and "type" in info): continue stream = RTMPStream( self.session, { "rtmp": ("{0}/{1}").format(info["connect"], info["play"]), "swfUrl": swfurl, "swfhash": swfhash, "swfsize": swfsize, "live": True }) if "display" in info: sname = info["display"] else: sname = info["type"] if "token" in info: stream.params["jtv"] = info["token"] else: self.logger.warning( "No token found for stream {0}, this stream may fail to play", sname) streams[sname] = stream return streams
def _get_streams(self): channelname = urlparse( self.url).path.rstrip("/").rpartition("/")[-1].lower() channelname = channelname.replace("_", "-") try: streams = HLSStream.parse_variant_playlist( self.session, self.PlaylistURL.format(channelname)) except IOError: raise NoStreamsError(self.url) return streams
def _get_streams(self): self.logger.debug('Extracting media URL') res = urlget( self.url, cookies={ 'NRK_PLAYER_SETTINGS_TV': 'devicetype=desktop&preferred-player-odm=hlslink&preferred-player-live=hlslink' }) m = re.search(r'<div[^>]*?id="playerelement"[^>]+data-media="([^"]+)"', res.text) if not m: raise NoStreamsError(self.url) return HLSStream.parse_variant_playlist(self.session, m.group(1))
def _get_streams(self): self.logger.debug("Fetching stream info") info = self._get_stream_info() if not info: raise NoStreamsError(self.url) event = verifyjson(info, "event") streaminfo = verifyjson(event, "stream_info") if not streaminfo or not streaminfo.get("is_live"): raise NoStreamsError(self.url) streams = defaultdict(list) play_url = streaminfo.get("play_url") if play_url: swfurl = info.get("viewerPlusSwfUrl") or info.get("hdPlayerSwfUrl") if not swfurl.startswith("http"): swfurl = "http://" + swfurl qualities = streaminfo.get("qualities", []) smil = self._parse_smil(streaminfo["play_url"], swfurl) for bitrate, stream in smil.items(): name = "{0}k".format(bitrate / 1000) for quality in qualities: if quality["bitrate"] == bitrate: name = "{0}p".format(quality["height"]) streams[name].append(stream) m3u8_url = streaminfo.get("m3u8_url") if m3u8_url: hls_streams = HLSStream.parse_variant_playlist(self.session, m3u8_url, namekey="pixels") for name, stream in hls_streams.items(): streams[name].append(stream) return streams
def _get_streams(self): country_code = urlparse(self.url).netloc.split(".")[0] self.logger.debug("Fetching stream info") res = urlget(self.APIURL) json = res_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 = urlget(self.GEOIPURL) geo = res_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_stream(self, channel_id, quality): params = dict(channel_id=channel_id, quality=quality) res = urlopen(CHINFO_URL, data=params, headers=AJAX_HEADERS, session=self.rsession) json = res_json(res) if not json: raise NoStreamsError(self.url) elif not isinstance(json, list): raise PluginError("Invalid JSON response") info = json[0] rtmp = info.get("serverURL") playpath = info.get("streamName") if not (rtmp and playpath): raise NoStreamsError(self.url) parsed = urlparse(rtmp) if not parsed.scheme.startswith("rtmp"): raise NoStreamsError(self.url) if parsed.query: app = "{0}?{1}".format(parsed.path[1:], parsed.query) else: app = parsed.path[1:] return RTMPStream( self.session, { "rtmp": rtmp, "pageUrl": self.url, "swfUrl": SWF_URL, "playpath": playpath, "app": app, "live": True })
def _get_streams(self): if not RTMPStream.is_usable(self.session): raise PluginError( "rtmpdump is not usable and required by Cybergame plugin") if "/videos/" in self.url: return self._get_vod_streams() self.logger.debug("Fetching live stream info") res = http.get(self.url) match = re.search("channel=([^\"]+)", res.text) if not match: raise NoStreamsError(self.url) channelname = match.group(1) res = http.get(CONFIG_URL, params=dict(c=channelname, ports="y")) json = http.json(res) servers = json.get("servers") if not servers: raise NoStreamsError(self.url) alternative = "" streams = {} for server in servers: srv, port = server.split(":") params = dict(channel=channelname, server=srv, port=port) tmpstreams = self._get_rtmp_streams(params, alternative) streams.update(tmpstreams) if not alternative: alternative = "_alt" else: break return streams
def _get_streams(self): key, video_player, player_id, is_live = self._get_player_params() if not is_live: raise NoStreamsError(self.url) req = self._create_amf_request(key, video_player, player_id) res = self._send_amf_request(req, key) streams = {} for message in res.messages: if message.target_uri == "/1/onResult": streams = self._parse_result(message.value) return streams