def find_iframe(self, url): self.session.http.headers.update({"User-Agent": useragents.CHROME}) res = self.session.http.get(self.url) for iframe_url in self.iframe_re.findall(res.text): if "googletagmanager" not in iframe_url: iframe_url = html_unescape(iframe_url) return update_scheme(self.url, iframe_url)
def _get_streams(self): streamdata = None if self.get_option("email"): if self.login(self.get_option("email"), self.get_option("password")): log.info("Logged in as {0}".format(self.get_option("email"))) self.save_cookies(lambda c: "steamMachineAuth" in c.name) # Handle steam.tv URLs if self._steamtv_url_re.match(self.url) is not None: # extract the steam ID from the page res = self.session.http.get(self.url) for div in itertags(res.text, 'div'): if div.attributes.get("id") == "webui_config": broadcast_data = html_unescape(div.attributes.get("data-broadcast")) steamid = parse_json(broadcast_data).get("steamid") self.url = self._watch_broadcast_url + steamid # extract the steam ID from the URL steamid = self._url_re.match(self.url).group(1) res = self.session.http.get(self.url) # get the page to set some cookies sessionid = res.cookies.get('sessionid') while streamdata is None or streamdata[u"success"] in ("waiting", "waiting_for_start"): streamdata = self._get_broadcast_stream(steamid, sessionid=sessionid) if streamdata[u"success"] == "ready": return DASHStream.parse_manifest(self.session, streamdata["url"]) elif streamdata[u"success"] == "unavailable": log.error("This stream is currently unavailable") return else: r = streamdata[u"retry"] / 1000.0 log.info("Waiting for stream, will retry again in {} seconds...".format(r)) time.sleep(r)
def _parse_streams(self, res): _found_stream_url = False for meta in itertags(res.text, "meta"): if meta.attributes.get("property") == "og:video:url": stream_url = html_unescape(meta.attributes.get("content")) if ".mpd" in stream_url: for s in DASHStream.parse_manifest(self.session, stream_url).items(): yield s _found_stream_url = True elif ".mp4" in stream_url: yield "vod", HTTPStream(self.session, stream_url) _found_stream_url = True break else: log.debug("No meta og:video:url") if _found_stream_url: return for match in self._src_re.finditer(res.text): stream_url = match.group("url") if "\\/" in stream_url: # if the URL is json encoded, decode it stream_url = parse_json("\"{}\"".format(stream_url)) if ".mpd" in stream_url: for s in DASHStream.parse_manifest(self.session, stream_url).items(): yield s elif ".mp4" in stream_url: yield match.group(1), HTTPStream(self.session, stream_url) else: log.debug("Non-dash/mp4 stream: {0}".format(stream_url)) match = self._dash_manifest_re.search(res.text) if match: # facebook replaces "<" characters with the substring "\\x3C" manifest = match.group("manifest").replace("\\/", "/") if is_py3: manifest = bytes(unquote_plus(manifest), "utf-8").decode("unicode_escape") else: manifest = unquote_plus(manifest).decode("string_escape") # Ignore unsupported manifests until DASH SegmentBase support is implemented if "SegmentBase" in manifest: log.error("Skipped DASH manifest with SegmentBase streams") else: for s in DASHStream.parse_manifest(self.session, manifest).items(): yield s
def _get_streams(self): """ Find the streams for vk.com :return: """ self.session.http.headers.update({'User-Agent': useragents.IPHONE_6}) # If this is a 'videos' catalog URL # with an video ID in the GET request, get that instead url = self.follow_vk_redirect(self.url) m = self._url_re.match(url) if not m: log.error('URL is not compatible: {0}'.format(url)) return video_id = m.group('video_id') log.debug('video ID: {0}'.format(video_id)) params = { 'act': 'show_inline', 'al': '1', 'video': video_id, } res = self.session.http.post(self.API_URL, params=params) for _i in itertags(res.text, 'iframe'): if _i.attributes.get('src'): iframe_url = update_scheme(self.url, _i.attributes['src']) log.debug('Found iframe: {0}'.format(iframe_url)) for s in self.session.streams(iframe_url).items(): yield s for _i in itertags(res.text.replace('\\', ''), 'source'): if _i.attributes.get('type') == 'application/vnd.apple.mpegurl': video_url = html_unescape(_i.attributes['src']) streams = HLSStream.parse_variant_playlist( self.session, video_url) if not streams: yield 'live', HLSStream(self.session, video_url) else: for s in streams.items(): yield s elif _i.attributes.get('type') == 'video/mp4': q = 'vod' video_url = _i.attributes['src'] m = self._vod_quality_re.search(video_url) if m: q = '{0}p'.format(m.group(1)) yield q, HTTPStream(self.session, video_url)
def _get_streams(self): p = urlparse(self.url) if "ott.streann.com" != p.netloc: self._domain = p.netloc res = self.session.http.get(self.url) for iframe in itertags(res.text, "iframe"): iframe_url = html_unescape(iframe.attributes.get("src")) if "ott.streann.com" in iframe_url: self.url = iframe_url break else: log.error("Could not find 'ott.streann.com' iframe") return if not self._domain and self.get_option("url"): self._domain = urlparse(self.get_option("url")).netloc if self._domain is None: log.error("Missing source URL use --streann-url") return self.session.http.headers.update({"Referer": self.url}) # Get the query string encrypted_data = urlparse(self.url).query data = base64.b64decode(encrypted_data) # and decrypt it passphrase = self.passphrase() if passphrase: log.debug("Found passphrase") params = decrypt_openssl(data, passphrase) config = parse_qsd(params.decode("utf8")) log.trace("config: {0!r}".format(config)) token = self.get_token(**config) if not token: return hls_url = self.stream_url.format(time=self.time, deviceId=self.device_id, token=token, **config) log.debug("URL={0}".format(hls_url)) return HLSStream.parse_variant_playlist( self.session, hls_url, acceptable_status=(200, 403, 404, 500))
def get_title(self): res = self.session.http.get(self.url) m = self._title_re.search(res.text) if m: return html_unescape(m.group(1))
class CeskatelevizeAPI2(object): _player_api = 'https://playlist.ceskatelevize.cz/' _url_re = re.compile(r'http(s)?://([^.]*.)?ceskatelevize.cz') _playlist_info_re = re.compile( r'{\s*"type":\s*"([a-z]+)",\s*"id":\s*"(\w+)"') _playlist_schema = validate.Schema({ "CODE": validate.contains("OK"), "RESULT": { "playlist": [{ "streamUrls": { "main": validate.url(), } }] } }) _ctcomp_re = re.compile( r'data-ctcomp="Video"\sdata-video-id="(?P<val1>[^"]*)"\sdata-ctcomp-data="(?P<val2>[^"]+)">' ) _ctcomp_schema = validate.Schema( validate.text, validate.transform(_ctcomp_re.findall), validate.transform( lambda vl: [{ "video-id": v[0], "ctcomp-data": json.loads(html_unescape(v[1])) } for v in vl])) _playlist_info_schema = validate.Schema({ "type": validate.text, "id": validate.any(validate.text, int), "key": validate.text, "date": validate.text, "requestSource": validate.text, "drm": int, validate.optional("canBePlay"): int, validate.optional("assetId"): validate.text, "quality": validate.text, validate.optional("region"): int }) def __init__(self, session, url, res=None): self.session = session self.url = url self.response = res def _get_streams(self): if self.response is None: infos = self.session.http.get(self.url, schema=self._ctcomp_schema) else: infos = self.session.http.json(self.response, schema=self._ctcomp_schema) if not infos: # playlist infos not found raise PluginError('Cannot find playlist infos!') vod_prio = len(infos) == 2 for info in infos: try: pl = info['ctcomp-data']['source']['playlist'][0] except KeyError: raise PluginError('Cannot find playlist info!') pl = self._playlist_info_schema.validate(pl) if vod_prio and pl['type'] != 'VOD': continue log.trace('{0!r}'.format(info)) if pl['type'] == 'LIVE': data = { "contentType": "live", "items": [{ "id": pl["id"], "assetId": pl["assetId"], "key": pl["key"], "playerType": "dash", "date": pl["date"], "requestSource": pl["requestSource"], "drm": pl["drm"], "quality": pl["quality"], }] } elif pl['type'] == 'VOD': data = { "contentType": "vod", "items": [{ "id": pl["id"], "key": pl["key"], "playerType": "dash", "date": pl["date"], "requestSource": pl["requestSource"], "drm": pl["drm"], "canBePlay": pl["canBePlay"], "quality": pl["quality"], "region": pl["region"] }] } headers = { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", } data = json.dumps(data) response = self.session.http.post(self._player_api, data="data={}".format(quote(data)), headers=headers) json_data = self.session.http.json(response, schema=self._playlist_schema) log.trace('{0!r}'.format(json_data)) playlist = json_data['RESULT']['playlist'][0]['streamUrls']['main'] for s in DASHStream.parse_manifest(self.session, playlist).items(): yield s
class Huya(Plugin): _re_url = re.compile(r'https?://(?:www\.)?huya\.com/(?P<channel>[^/]+)') _re_stream = re.compile(r'"stream"\s?:\s?"([^"]+)"') _schema_data = validate.Schema( { # 'status': int, # 'msg': validate.any(None, validate.text), 'data': [{ 'gameStreamInfoList': [{ 'sCdnType': validate.text, 'sStreamName': validate.text, 'sFlvUrl': validate.text, 'sFlvUrlSuffix': validate.text, 'sFlvAntiCode': validate.all( validate.text, validate.transform(lambda v: html_unescape(v))), # 'sHlsUrl': validate.text, # 'sHlsUrlSuffix': validate.text, # 'sHlsAntiCode': validate.all(validate.text, validate.transform(lambda v: html_unescape(v))), validate.optional('iIsMultiStream'): int, 'iPCPriorityRate': int, }] }], # 'vMultiStreamInfo': [{ # 'sDisplayName': validate.text, # 'iBitRate': int, # }], }, validate.get('data'), validate.get(0), validate.get('gameStreamInfoList'), ) QUALITY_WEIGHTS = {} @classmethod def can_handle_url(cls, url): return cls._re_url.match(url) is not None @classmethod def stream_weight(cls, key): weight = cls.QUALITY_WEIGHTS.get(key) if weight: return weight, 'huya' return Plugin.stream_weight(key) def _get_streams(self): res = self.session.http.get(self.url) data = self._re_stream.search(res.text) if not data: return data = parse_json(base64.b64decode(data.group(1)), schema=self._schema_data) for info in data: log.trace('{0!r}'.format(info)) flv_url = '{0}/{1}.{2}?{3}'.format(info["sFlvUrl"], info["sStreamName"], info["sFlvUrlSuffix"], info["sFlvAntiCode"]) name = 'source_{0}'.format(info["sCdnType"].lower()) self.QUALITY_WEIGHTS[name] = info['iPCPriorityRate'] yield name, HTTPStream(self.session, flv_url) log.debug('QUALITY_WEIGHTS: {0!r}'.format(self.QUALITY_WEIGHTS))
def _get_streams(self): self.session.http.headers.update({'User-Agent': useragents.FIREFOX}) res = self.session.http.get(self.url) for iframe in itertags(res.text, 'iframe'): return self.session.streams( html_unescape(iframe.attributes.get('src')))