def get(self): data = self.get_urldata() match = re.search('data-audio-type="publication" data-audio-id="(\d+)">', data) # Nyheter if match: dataurl = "https://sverigesradio.se/sida/playerajax/" \ "getaudiourl?id={0}&type={1}&quality=high&format=iis".format(match.group(1), "publication") data = self.http.request("get", dataurl).text playerinfo = json.loads(data) yield HTTP(copy.copy(self.config), playerinfo["audioUrl"], 128) return match = re.search(r'href="(/topsy/ljudfil/\d+-mp3)"', data) # Ladda ner if match: yield HTTP(copy.copy(self.config), urljoin("https://sverigesradio.se", match.group(1)), 128) return else: match = re.search('data-audio-type="episode" data-audio-id="(\d+)"', data) # Ladda ner med musik match2 = re.search('data-audio-type="secondary" data-audio-id="(\d+)"', data) # Ladda ner utan musik if match: aid = match.group(1) type = "episode" elif match2: aid = match2.group(1) type = "secondary" else: yield ServiceError("Can't find audio info") return dataurl = "https://sverigesradio.se/sida/playerajax/" \ "getaudiourl?id={0}&type={1}&quality=high&format=iis".format(aid, type) data = self.http.request("get", dataurl).text playerinfo = json.loads(data) yield HTTP(copy.copy(self.config), playerinfo["audioUrl"], 128, output=self.output)
def get(self, options): vid = None data = self.get_urldata() match = re.search(r'video url-([^"]+)', data) if not match: match = re.search(r'embed.jsp\?id=([^&]+)&', data) if not match: log.error("Cant find video id") sys.exit(2) vid = match.group(1) if not vid: path = unquote_plus(match.group(1)) data = get_http_data("http://www.svd.se%s" % path) match = re.search(r'embed.jsp\?id=([^&]+)&', data) if not match: log.error("Cant find video id2") sys.exit(2) vid = match.group(1) url = "http://amz.lwcdn.com/api/cache/VideoCache.jsp?id=%s" % vid data = get_http_data(url) xml = ET.XML(data) videofile = xml.find("{http://www.lemonwhale.com/xml11}VideoFile") mediafiles = videofile.find( "{http://www.lemonwhale.com/xml11}MediaFiles") high = mediafiles.find("{http://www.lemonwhale.com/xml11}VideoURLHigh") if high.text: yield HTTP(copy.copy(options), high.text, 720) videourl = mediafiles.find( "{http://www.lemonwhale.com/xml11}VideoURL").text yield HTTP(copy.copy(options), videourl, 480)
def get(self): data = self.get_urldata() match = re.search('params","([^"]+)"', data) if not match: yield ServiceError( "Cant find params info. video need to be public.") return data2 = json.loads('["{0}"]'.format(match.group(1))) data2 = json.loads(unquote_plus(data2[0])) if "sd_src_no_ratelimit" in data2["video_data"]["progressive"][0]: yield HTTP( copy.copy(self.config), data2["video_data"]["progressive"][0]["sd_src_no_ratelimit"], "240", output=self.output) else: yield HTTP(copy.copy(self.config), data2["video_data"]["progressive"][0]["sd_src"], "240") if "hd_src_no_ratelimit" in data2["video_data"]["progressive"][0]: yield HTTP( copy.copy(self.config), data2["video_data"]["progressive"][0]["hd_src_no_ratelimit"], "720", output=self.output) else: if data2["video_data"]["progressive"][0]["hd_src"]: yield HTTP(copy.copy(self.config), data2["video_data"]["progressive"][0]["hd_src"], "720", output=self.output)
def get(self): data = self.get_urldata() if self.exclude(): yield ServiceError("Excluding video") return parse = urlparse(self.url) vidoid = parse.path[parse.path.rfind("/") + 1:] match = re.search(r'JSONdata = ({.*});', data) if not match: yield ServiceError("Cant find json data") return janson = json.loads(match.group(1)) playlist = janson["playlist"] for i in playlist: if i["brightcoveId"] == int(vidoid): if i["HLSURL"]: streams = hlsparse(self.options, self.http.request("get", i["HLSURL"]), i["HLSURL"]) for n in list(streams.keys()): yield streams[n] for n in i["renditions"]: if n["container"] == "MP4": yield HTTP(copy.copy(self.options), n["URL"], int(n["rate"]) / 1000)
def get(self): data = self.get_urldata() if self.exclude(): yield ServiceError("Excluding video") return match = re.search(r'"([^"]+geo.php)"', data) if match: data = self.http.request("get", match.group(1)).content match = re.search(r'punktur=\(([^ ]+)\)', data) if match: janson = json.loads(match.group(1)) self.options.live = checklive(janson["result"][1]) streams = hlsparse( self.options, self.http.request("get", janson["result"][1]), janson["result"][1]) for n in list(streams.keys()): yield streams[n] else: yield ServiceError("Can't find json info") else: match = re.search(r'<source [^ ]*[ ]*src="([^"]+)" ', self.get_urldata()) if not match: yield ServiceError("Can't find video info for: %s" % self.url) return if match.group(1).endswith("mp4"): yield HTTP(copy.copy(self.options), match.group(1), 800) else: m3u8_url = match.group(1) self.options.live = checklive(m3u8_url) yield HLS(copy.copy(self.options), m3u8_url, 800)
def get(self, options): match = re.search(r'data-videoid="([^"]+)"', self.get_urldata()) if not match: parse = urlparse(self.url) match = re.search(r'video/(\d+)/', parse.fragment) if not match: log.error("Can't find video id") sys.exit(2) videoid = match.group(1) data = get_http_data("http://svp.vg.no/svp/api/v1/vgtv/assets/%s?appName=vgtv-website" % videoid) jsondata = json.loads(data) if options.output_auto: directory = os.path.dirname(options.output) title = "%s" % jsondata["title"] title = filenamify(title) if len(directory): options.output = "%s/%s" % (directory, title) else: options.output = title if "hds" in jsondata["streamUrls"]: parse = urlparse(jsondata["streamUrls"]["hds"]) manifest = "%s://%s%s?%s&hdcore=3.3.0" % (parse.scheme, parse.netloc, parse.path, parse.query) streams = hdsparse(copy.copy(options), manifest) if streams: for n in list(streams.keys()): yield streams[n] if "hls" in jsondata["streamUrls"]: streams = hlsparse(jsondata["streamUrls"]["hls"]) for n in list(streams.keys()): yield HLS(copy.copy(options), streams[n], n) if "mp4" in jsondata["streamUrls"]: yield HTTP(copy.copy(options), jsondata["streamUrls"]["mp4"])
def get(self): data = self.get_urldata() match = re.search(r"mgid=\"(mgid.*[0-9]+)\" data-wi", data) if not match: yield ServiceError("Can't find video file") return url = "http://media.mtvnservices.com/player/html5/mediagen/?uri=%s" % match.group( 1) data = self.http.request("get", url) start = data.index("<?xml version=") data = data[start:] xml = ET.XML(data) ss = xml.find("video").find("item") if is_py2_old: sa = list(ss.getiterator("rendition")) else: sa = list(ss.iter("rendition")) if self.exclude(): yield ServiceError("Excluding video") return for i in sa: temp = i.find("src").text.index("gsp.comedystor") url = "http://mtvnmobile.vo.llnwd.net/kip0/_pxn=0+_pxK=18639+_pxE=mp4/44620/mtvnorigin/%s" % i.find( "src").text[temp:] yield HTTP(copy.copy(self.options), url, i.attrib["height"])
def get(self): match = re.search("_([a-zA-Z0-9]+)$", self.url) if not match: yield ServiceError("Cant find video id.") return vid = match.group(1) res = self.http.get("http://www.riksdagen.se/api/videostream/get/%s" % vid) data = res.json() try: janson = data["videodata"][0]["streams"]["files"] except TypeError: yield ServiceError("Cant find video.") return for i in janson: if i["mimetype"] == "application/x-mpegurl": data2 = self.http.get(i["url"]).json() streams = hlsparse(self.config, self.http.request("get", data2["url"]), data2["url"], output=self.output) for n in list(streams.keys()): yield streams[n] if i["mimetype"] == "video/mp4": for n in i["bandwidth"]: yield HTTP(copy.copy(self.config), n["url"], n["quality"], output=self.output)
def get(self): data = self.get_urldata() match = re.search(r'script async defer src="(//content.youplay.se[^"]+)"', data) if not match: yield ServiceError("Cant find video info for {}".format(self.url)) return data = self.http.request("get", "http:{}".format(match.group(1)).content) match = re.search(r'decodeURIComponent\("([^"]+)"\)\)', data) if not match: yield ServiceError("Can't decode video info") return data = unquote_plus(match.group(1)) match = re.search(r"videoData = ({[^;]+});", data) if not match: yield ServiceError("Cant find video info for {}".format(self.url)) return # fix broken json. regex = re.compile(r"\s(\w+):") data = regex.sub(r"'\1':", match.group(1)) data = data.replace("'", '"') j = re.sub(r"{\s*(\w)", r'{"\1', data) j = j.replace("\n", "") j = re.sub(r'",\s*}', '"}', j) jsondata = json.loads(j) for i in jsondata["episode"]["sources"]: match = re.search(r"mp4_(\d+)", i) if match: yield HTTP(copy.copy(self.config), jsondata["episode"]["sources"][i], match.group(1), output=self.output)
def test_sort(self): data = [ DASH(setup_defaults(), "http://example.com", 3000, None), HLS(setup_defaults(), "http://example.com", 2000, None), HTTP(setup_defaults(), "http://example.com", 3001, None), ] assert all([ a[0] == b.bitrate for a, b in zip( sort_quality(data), [ HTTP(setup_defaults(), "http://example.com", 3001, None), DASH(setup_defaults(), "http://example.com", 3000, None), HLS(setup_defaults(), "http://example.com", 2000, None), ], ) ])
def get(self): data = self.get_urldata() match = re.search(r'data-videoid="([^"]+)"', data) if not match: parse = urlparse(self.url) match = re.search(r"video/(\d+)/", parse.fragment) if not match: yield ServiceError(f"Can't find video file for: {self.url}") return videoid = match.group(1) data = self.http.request("get", f"http://svp.vg.no/svp/api/v1/vgtv/assets/{videoid}?appName=vgtv-website").text jsondata = json.loads(data) self.output["title"] = jsondata["title"] if "hds" in jsondata["streamUrls"]: streams = hdsparse( self.config, self.http.request("get", jsondata["streamUrls"]["hds"], params={"hdcore": "3.7.0"}), jsondata["streamUrls"]["hds"], output=self.output, ) for n in list(streams.keys()): yield streams[n] if "hls" in jsondata["streamUrls"]: streams = hlsparse( self.config, self.http.request("get", jsondata["streamUrls"]["hls"]), jsondata["streamUrls"]["hls"], output=self.output, ) for n in list(streams.keys()): yield streams[n] if "mp4" in jsondata["streamUrls"]: yield HTTP(copy.copy(self.config), jsondata["streamUrls"]["mp4"], output=self.output)
def get(self): self.backupapi = None ajax_auth = self.get_auth() if not ajax_auth: yield ServiceError("Cant find token for video") return mediaid = self.get_mediaid() if not mediaid: yield ServiceError("Cant find media id") return if not isinstance(mediaid, str): mediaid = mediaid.group(1) jsondata = self.http.request( "get", "http://csp.screen9.com/player?eventParam=1&" "ajaxauth={}&method=embed&mediaid={}".format( ajax_auth.group(1), mediaid), ).text jsondata = json.loads(jsondata) if "data" in jsondata: if "live" in jsondata["data"]["publishing_status"]: self.config.set("live", jsondata["data"]["publishing_status"]["live"]) playlist = jsondata["data"]["streams"] for i in playlist: if "application/x-mpegurl" in i: streams = hlsparse( self.config, self.http.request("get", i["application/x-mpegurl"]), i["application/x-mpegurl"], output=self.output, ) if streams: for n in list(streams.keys()): yield streams[n] if "video/mp4" in i: yield HTTP(copy.copy(self.config), i["video/mp4"], 800, output=self.output) if self.backupapi: res = self.http.get(self.backupapi.replace("i=", ""), params={"i": "object"}) data = res.text.replace("ps.embedHandler(", "").replace('"");', "") data = data[:data.rfind(",")] jansson = json.loads(data) for i in jansson["media"]["playerconfig"]["playlist"]: if "provider" in i and i["provider"] == "httpstreaming": streams = hlsparse(self.config, self.http.request("get", i["url"]), i["url"], output=self.output) for n in list(streams.keys()): yield streams[n]
def get(self): data = self.get_urldata() match = re.search(r'id="(bcPl[^"]+)"', data) if not match: yield ServiceError("Can't find flash id.") return flashid = match.group(1) match = re.search(r'playerID" value="([^"]+)"', self.get_urldata()) if not match: yield ServiceError("Can't find playerID") return playerid = match.group(1) match = re.search(r'playerKey" value="([^"]+)"', self.get_urldata()) if not match: yield ServiceError("Can't find playerKey") return playerkey = match.group(1) match = re.search(r'videoPlayer" value="([^"]+)"', self.get_urldata()) if not match: yield ServiceError("Can't find videoPlayer info") return videoplayer = match.group(1) dataurl = ( "http://c.brightcove.com/services/viewer/htmlFederated?flashID={}&playerID={}&playerKey={}" "&isVid=true&isUI=true&dynamicStreaming=true&@videoPlayer={}".format(flashid, playerid, playerkey, videoplayer) ) data = self.http.request("get", dataurl).content match = re.search(r"experienceJSON = ({.*});", data) if not match: yield ServiceError("Can't find json data") return jsondata = json.loads(match.group(1)) renditions = jsondata["data"]["programmedContent"]["videoPlayer"]["mediaDTO"]["renditions"] if jsondata["data"]["publisherType"] == "PREMIUM": yield ServiceError("Premium content") return for i in renditions: if i["defaultURL"].endswith("f4m"): streams = hdsparse( copy.copy(self.config), self.http.request("get", i["defaultURL"], params={"hdcore": "3.7.0"}), i["defaultURL"], output=self.output ) for n in list(streams.keys()): yield streams[n] if i["defaultURL"].endswith("m3u8"): streams = hlsparse(self.config, self.http.request("get", i["defaultURL"]), i["defaultURL"], output=self.output) for n in list(streams.keys()): yield streams[n] if i["defaultURL"].endswith("mp4"): yield HTTP(copy.copy(self.config), i["defaultURL"], i["encodingRate"] / 1024, output=self.output)
def _get_static_video(self, vid, options, vidtype): url = "http://api.justin.tv/api/broadcast/by_%s/%s.xml?onsite=true" % ( vidtype, vid) data = get_http_data(url) xml = ET.XML(data) url = xml.find("archive").find("video_file_url").text yield HTTP(copy.copy(options), url)
def get(self, options): parse = urlparse(self.url) if parse.hostname == "video.disney.se": match = re.search(r"Grill.burger=({.*}):", self.get_urldata()) if not match: log.error("Can't find video info") return jsondata = json.loads(match.group(1)) for n in jsondata["stack"]: if len(n["data"]) > 0: for x in n["data"]: if "flavors" in x: for i in x["flavors"]: if i["format"] == "mp4": yield HTTP(copy.copy(options), i["url"], i["bitrate"]) else: match = re.search(r"uniqueId : '([^']+)'", self.get_urldata()) if not match: log.error("Can't find video info") return uniq = match.group(1) match = re.search("entryId : '([^']+)'", self.get_urldata()) entryid = match.group(1) match = re.search("partnerId : '([^']+)'", self.get_urldata()) partnerid = match.group(1) match = re.search("uiConfId : '([^']+)'", self.get_urldata()) uiconfid = match.group(1) url = "http://cdnapi.kaltura.com/html5/html5lib/v1.9.7.6/mwEmbedFrame.php?&wid=%s&uiconf_id=%s&entry_id=%s&playerId=%s&forceMobileHTML5=true&urid=1.9.7.6&callback=mwi" % \ (partnerid, uiconfid, entryid, uniq) data = get_http_data(url) match = re.search(r"mwi\(({.*})\);", data) jsondata = json.loads(match.group(1)) data = jsondata["content"] match = re.search(r"window.kalturaIframePackageData = ({.*});", data) jsondata = json.loads(match.group(1)) ks = jsondata["enviornmentConfig"]["ks"] if options.output_auto: name = jsondata["entryResult"]["meta"]["name"] directory = os.path.dirname(options.output) options.service = "disney" title = "%s-%s" % (name, options.service) title = filenamify(title) if len(directory): options.output = "%s/%s" % (directory, title) else: options.output = title url = "http://cdnapi.kaltura.com/p/%s/sp/%s00/playManifest/entryId/%s/format/applehttp/protocol/http/a.m3u8?ks=%s&referrer=aHR0cDovL3d3dy5kaXNuZXkuc2U=&" % ( partnerid[1:], partnerid[1:], entryid, ks) redirect = check_redirect(url) streams = hlsparse(redirect) for n in list(streams.keys()): yield HLS(copy.copy(options), streams[n], n)
def get(self): match = re.search(r'[^/]file: "(http[^"]+)', self.get_urldata()) if not match: yield ServiceError("Can't find the video file") return yield HTTP(copy.copy(self.config), match.group(1), 480, output=self.output)
def get(self): if self.exclude(): yield ServiceError("Excluding video") return match = re.search(r'[^/]file: "(http[^"]+)', self.get_urldata()) if not match: yield ServiceError("Can't find the video file") return yield HTTP(copy.copy(self.options), match.group(1), 480)
def get(self, options): match = re.search(r"RP.vcdData = ({.*});</script>", self.get_urldata()) if match: data = json.loads(match.group(1)) for i in list(data["station"]["streams"].keys()): yield HTTP(copy.copy(options), data["station"]["streams"][i], i) else: log.error("Can't find stream info") sys.exit(2)
def get(self): data = self.get_urldata() match = re.search(r"RP.vcdData = ({.*});</script>", data) if match: data = json.loads(match.group(1)) for i in list(data["station"]["streams"].keys()): yield HTTP(copy.copy(self.config), data["station"]["streams"][i], i) else: yield ServiceError("Can't find stream info") return
def _get_clips(self): match = re.search(r"quality_options: (\[[^\]]+\])", self.get_urldata()) if not match: yield ServiceError("Can't find the video clip") return name = re.search(r'slug: "([^"]+)"', self.get_urldata()).group(1) brodcaster = re.search('broadcaster_login: "******"]+)"', self.get_urldata()).group(1) self.output["title"] = "twitch-{}".format(brodcaster) self.output["episodename"] = name dataj = json.loads(match.group(1)) for i in dataj: yield HTTP(copy.copy(self.config), i["source"], i["quality"], output=self.output)
def get(self, options): match = re.search(r'href="(/sida/[\.\/=a-z0-9&;\?]+\d+)" aria-label', self.get_urldata()) if not match: log.error("Can't find audio info") sys.exit(2) path = quote_plus(match.group(1)) dataurl = "http://sverigesradio.se/sida/ajax/getplayerinfo?url=%s&isios=false&playertype=html5" % path data = get_http_data(dataurl) playerinfo = json.loads(data)["playerInfo"] for i in playerinfo["AudioSources"]: url = i["Url"] if not url.startswith('http'): url = 'http:%s' % url yield HTTP(copy.copy(options), url, i["Quality"])
def get(self): data = self.get_urldata() match = re.search(r'data-audio-id="(\d+)"', data) match2 = re.search(r'data-audio-type="(\w+)"', data) if match and match2: aid = match.group(1) type = match2.group(1) else: yield ServiceError("Can't find audio info") return dataurl = "https://sverigesradio.se/sida/playerajax/" "getaudiourl?id={}&type={}&quality=high&format=iis".format(aid, type) data = self.http.request("get", dataurl).text playerinfo = json.loads(data) yield HTTP(copy.copy(self.config), playerinfo["audioUrl"], 128, output=self.output)
def get(self): data = self.get_urldata() match_cfg_url = re.search( 'data-config-url="([^"]+)" data-fallback-url', data) match_clip_page_cfg = re.search( r'vimeo\.clip_page_config\s*=\s*({.+?});', data) if match_cfg_url: player_url = match_cfg_url.group(1).replace("&", "&") elif match_clip_page_cfg: page_config = json.loads(match_clip_page_cfg.group(1)) player_url = page_config["player"]["config_url"] else: yield ServiceError("Can't find video file for: {0}".format( self.url)) return player_data = self.http.request("get", player_url).text if player_data: jsondata = json.loads(player_data) if ("hls" in jsondata["request"]["files"]) and ( "fastly_skyfire" in jsondata["request"]["files"]["hls"]["cdns"]): hls_elem = jsondata["request"]["files"]["hls"]["cdns"][ "fastly_skyfire"] stream = hlsparse(self.config, self.http.request("get", hls_elem["url"]), hls_elem["url"], output=self.output) if stream: for n in list(stream.keys()): yield stream[n] avail_quality = jsondata["request"]["files"]["progressive"] for i in avail_quality: yield HTTP(copy.copy(self.config), i["url"], i["height"], output=self.output) else: yield ServiceError("Can't find any streams.") return
def get(self, options): match = re.search(r"v/(\d+)", self.url) if not match: log.error("Can't find video id in url") sys.exit(2) json_url = "http://player-c.api.bambuser.com/getVideo.json?api_key=005f64509e19a868399060af746a00aa&vid=%s" % match.group(1) data = get_http_data(json_url) info = json.loads(data)["result"] video = info["url"] if video[:4] == "rtmp": playpath = info["id"][len(info["id"])-36:] options.other = "-y %s" % playpath if info["type"] == "live": options.live = True yield RTMP(copy.copy(options), video, "0") else: yield HTTP(copy.copy(options), video, "0")
def get(self, options): match = re.search("data-config-url=\"(.*)\" data-fallback-url", self.get_urldata()) if not match: log.error("Can't find data") sys.exit(4) player_url = match.group(1).replace("&", "&") player_data = get_http_data(player_url) if player_data: jsondata = json.loads(player_data) avail_quality = jsondata["request"]["files"]["h264"] for i in avail_quality.keys(): yield HTTP(copy.copy(options), avail_quality[i]["url"], avail_quality[i]["bitrate"]) else: log.error("Can't find any streams.") sys.exit(2)
def _get_clips(self, options): match = re.search("quality_options: (\[[^\]]+\])", self.get_urldata()) if not match: yield ServiceError("Can't find the video clip") return if options.output_auto: name = re.search('slug: "([^"]+)"', self.get_urldata()).group(1) brodcaster = re.search('broadcaster_login: "******"]+)"', self.get_urldata()).group(1) name = "twitch-%s-%s" % (brodcaster, name) directory = os.path.dirname(options.output) if os.path.isdir(directory): name = os.path.join(directory, name) options.output = name dataj = json.loads(match.group(1)) for i in dataj: yield HTTP(copy.copy(options), i["source"], i["quality"])
def get(self): data = self.get_urldata() if self.exclude(): yield ServiceError("Excluding video") return match = re.search(r'href="(/sida/[\.\/=a-z0-9&;\?]+play(?:audio|episode)=\d+)"', data) if not match: yield ServiceError("Can't find audio info") return path = quote_plus(match.group(1)) dataurl = "http://sverigesradio.se/sida/ajax/getplayerinfo?url=%s&isios=false&playertype=html5" % path data = self.http.request("get", dataurl).text playerinfo = json.loads(data)["playerInfo"] for i in playerinfo["AudioSources"]: url = i["Url"] if not url.startswith('http'): url = 'http:%s' % url yield HTTP(copy.copy(self.options), url, i["Quality"]/1000)
def get(self, options): data = self.get_urldata() parse = urlparse(self.url) vidoid = parse.path[parse.path.rfind("/") + 1:] match = re.search(r'JSONdata = ({.*});', data) if not match: log.error("Cant find json data") sys.exit(2) janson = json.loads(match.group(1)) playlist = janson["playlist"] for i in playlist: if i["brightcoveId"] == vidoid: if i["HLSURL"]: streams = hlsparse(i["HLSURL"]) for n in list(streams.keys()): yield HLS(copy.copy(options), streams[n], n) for n in i["renditions"]: if n["container"] == "MP4": yield HTTP(copy.copy(options), n["URL"], int(n["rate"]) / 1000)
def get(self): match = re.search(r"v/(\d+)", self.url) if not match: yield ServiceError("Can't find video id in url") return json_url = "http://player-c.api.bambuser.com/getVideo.json?api_key=005f64509e19a868399060af746a00aa&vid={0}".format( match.group(1)) data = self.http.request("get", json_url).text info = json.loads(data)["result"] video = info["url"] if video[:4] == "rtmp": playpath = info["id"][len(info["id"]) - 36:] other = "-y {0}".format(playpath) if info["type"] == "live": self.config.set("live", True) yield RTMP(copy.copy(self.config), video, "0", other=other) else: yield HTTP(copy.copy(self.config), video, "0")
def get(self): data = self.get_urldata() if self.exclude(): yield ServiceError("Excluding video") return match = re.search('data-config-url="([^"]+)" data-fallback-url', data) if not match: yield ServiceError("Can't find video file for: %s" % self.url) return player_url = match.group(1).replace("&", "&") player_data = self.http.request("get", player_url).text if player_data: jsondata = json.loads(player_data) avail_quality = jsondata["request"]["files"]["progressive"] for i in avail_quality: yield HTTP(copy.copy(self.options), i["url"], i["height"]) else: yield ServiceError("Can't find any streams.") return