def _get_streams(self): self.url = http.resolve_url(self.url) match = _url_re.match(self.url) parsed = urlparse(self.url) if parsed.fragment: channel_id = parsed.fragment elif parsed.path[:3] == '/v/': channel_id = parsed.path.split('/')[-1] 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_stream_info(self, url): match = _url_re.match(url) user = match.group("user") live_channel = match.group("liveChannel") if user: video_id = self._find_channel_video() elif live_channel: return self._find_canonical_stream_info() else: video_id = match.group("video_id") video_id2 = match.group("video_id2") if video_id2: video_id = video_id2 if video_id == "live_stream": query_info = dict(parse_qsl(urlparse(url).query)) if "channel" in query_info: video_id = self._get_channel_video(query_info["channel"]) if not video_id: return params = { "video_id": video_id, } res = http.get(API_VIDEO_INFO, params=params, headers=HLS_HEADERS) return parse_query(res.text, name="config", schema=_config_schema)
def _create_stream(self, stream, is_live): stream_name = "{0}p".format(stream["height"]) stream_type = stream["mediaType"] stream_url = stream["url"] if stream_type in ("hls", "mp4"): if urlparse(stream_url).path.endswith("m3u8"): try: streams = HLSStream.parse_variant_playlist( self.session, stream_url) # TODO: Replace with "yield from" when dropping Python 2. for stream in streams.items(): yield stream except IOError as err: self.logger.error("Failed to extract HLS streams: {0}", err) else: yield stream_name, HTTPStream(self.session, stream_url) elif stream_type == "rtmp": params = { "rtmp": stream["streamer"], "playpath": stream["url"], "swfVfy": SWF_URL, "pageUrl": self.url, } if is_live: params["live"] = True else: params["playpath"] = "mp4:{0}".format(params["playpath"]) stream = RTMPStream(self.session, params) yield stream_name, stream
def _get_streams(self): res = http.get(self.url) match = _info_re.search(res.text) if not match: return info = parse_json(match.group(1), schema=_schema) stream_name = info["mode"] mp4_url = info.get("mp4_url") ios_url = info.get("ios_url") swf_url = info.get("swf_url") if mp4_url: stream = HTTPStream(self.session, mp4_url) yield stream_name, stream if ios_url: if urlparse(ios_url).path.endswith(".m3u8"): streams = HLSStream.parse_variant_playlist( self.session, ios_url) # TODO: Replace with "yield from" when dropping Python 2. for stream in streams.items(): yield stream if swf_url: stream = self._get_rtmp_stream(swf_url) if stream: yield stream_name, stream
def _get_streams(self): match = _url_re.match(self.url) video_id = match.group("video_id") res = http.get(ASSET_URL.format(video_id)) assets = http.xml(res, schema=_asset_schema) streams = {} for asset in assets: base = asset["base"] url = asset["url"] if urlparse(url).path.endswith(".f4m"): streams.update( HDSStream.parse_manifest(self.session, url, pvswf=SWF_URL) ) elif base.startswith("rtmp"): name = "{0}k".format(asset["bitrate"]) params = { "rtmp": asset["base"], "playpath": url, "live": True } streams[name] = RTMPStream(self.session, params) return streams
def _parse_vod_streams(self, vod): for name, stream in vod["streams"].items(): scheme = urlparse(stream["url"]).scheme if scheme == "http": yield name, HLSStream(self.session, stream["url"]) elif scheme == "rtmp": yield name, self._create_rtmp_stream(stream, live=False)
def _get_streams(self): res = http.get(self.url, schema=_live_schema) if not res: return if res["type"] == "hls" and urlparse(res["url"]).path.endswith("m3u8"): stream = HLSStream(self.session, res["url"]) return dict(hls=stream)
def _get_video_streams(self, player): base_url = player["clip"]["baseUrl"] or VOD_BASE_URL mapper = StreamMapper(cmp=lambda ext, bitrate: urlparse(bitrate["url"]) .path.endswith(ext)) mapper.map(".m3u8", self._create_video_stream, HLSStream, base_url) mapper.map(".mp4", self._create_video_stream, HTTPStream, base_url) mapper.map(".flv", self._create_video_stream, HTTPStream, base_url) return mapper(player["clip"]["bitrates"])
def _get_streams(self): res = http.get(self.url, schema=_schema) if not res: return if res["type"] == "channel" and urlparse( res["url"]).path.endswith("m3u8"): return HLSStream.parse_variant_playlist(self.session, res["url"]) elif res["type"] == "video": stream = HTTPStream(self.session, res["url"]) return dict(video=stream)
def _create_rtmp_stream(self, cdn, stream_name): parsed = urlparse(cdn) params = { "rtmp": cdn, "app": parsed.path[1:], "playpath": stream_name, "pageUrl": self.url, "swfUrl": SWF_URL, "live": True } return RTMPStream(self.session, params)
def _get_streams(self): res = http.get(self.url) match = _meta_xmlurl_id_re.search(res.text) if not match: return xml_info_url = STREAMS_INFO_URL.format(match.group(1)) video_info_res = http.get(xml_info_url) parsed_info = http.xml(video_info_res) live_el = parsed_info.find("live") live = live_el is not None and live_el.text == "1" streams = {} hdsurl_el = parsed_info.find("hdsurl") if hdsurl_el is not None and hdsurl_el.text is not None: hdsurl = hdsurl_el.text streams.update(HDSStream.parse_manifest(self.session, hdsurl)) if live: vurls_el = parsed_info.find("vurls") if vurls_el is not None: for i, vurl_el in enumerate(vurls_el): bitrate = vurl_el.get("bitrate") name = bitrate + "k" if bitrate is not None else "rtmp{0}".format( i) params = { "rtmp": vurl_el.text, } streams[name] = RTMPStream(self.session, params) parsed_urls = set() mobileurls_el = parsed_info.find("mobileurls") if mobileurls_el is not None: for mobileurl_el in mobileurls_el: text = mobileurl_el.text if not text: continue if text in parsed_urls: continue parsed_urls.add(text) url = urlparse(text) if url[0] == "http" and url[2].endswith("m3u8"): streams.update( HLSStream.parse_variant_playlist(self.session, text)) return streams
def can_handle_url(self, url): self.url = url self.scheme = None try: parsed = urlparse(url) self.domain = parsed.netloc self.scheme = self.get_scheme(self.domain) except Exception as e: self.logger.error("Failed to get scheme for '{0}'. {1}", url, str(e)) return self.scheme != None
def _get_streams(self): url_params = dict(parse_qsl(urlparse(self.url).query)) video_id = url_params.get("videoid") if video_id: self.logger.debug("Found Video ID: {}", video_id) res = http.get(self.api_url.format(id=video_id)) data = http.json(res, schema=self.api_schema) hls = self._make_stream(data["video_info"]["hlsvideosource"]) video = self._make_stream(data["video_info"]["videosource"]) if hls: yield "live", hls if video: yield "live", video
def _get_streams(self): parsed = urlparse(self.url) cls = PROTOCOL_MAP.get(parsed.scheme) if not cls: return split = self.url.split(" ") url = split[0] urlnoproto = re.match("^\w+://(.+)", url).group(1) # Prepend http:// if needed. if cls != RTMPStream and not len(urlparse(urlnoproto).scheme): urlnoproto = "http://{0}".format(urlnoproto) 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: try: streams = cls(self.session, urlnoproto, **params) except IOError as err: raise PluginError(err) return streams else: stream = cls(self.session, urlnoproto, **params) return dict(live=stream)
def __init__(self, url): Plugin.__init__(self, url) match = _url_re.match(url).groupdict() self.channel = match.get("channel").lower() self.subdomain = match.get("subdomain") self.video_type = match.get("video_type") self.video_id = match.get("video_id") self.clip_name = match.get("clip_name") self._hosted_chain = [] parsed = urlparse(url) self.params = parse_query(parsed.query) self.api = TwitchAPI(beta=self.subdomain == "beta") self.usher = UsherService()
def _create_rtmp_stream(self, url): parsed = urlparse(url) if parsed.query: app = "{0}?{1}".format(parsed.path[1:], parsed.query) else: app = parsed.path[1:] params = { "rtmp": url, "app": app, "pageUrl": self.url, "live": True } stream = RTMPStream(self.session, params) return "live", stream
def _parse_live_streams(self, channel): for stream in channel["streams"]: name = stream["quality"] scheme = urlparse(stream["url"]).scheme if scheme == "http": try: streams = HLSStream.parse_variant_playlist( self.session, stream["url"]) for __, stream in streams.items(): yield name, stream except IOError as err: self.logger.error( "Failed to extract HLS stream '{0}': {1}", name, err) elif scheme == "rtmp": yield name, self._create_rtmp_stream(stream)
def _get_playlist(self, **params): res = http.get(PLAYLIST_URL, params=params) playlist = http.xml(res, schema=_playlist_schema) streams = {} for video in playlist["videos"]: name = "{0}p".format(video["height"]) stream = RTMPStream( self.session, { "rtmp": "{0}/{1}".format(playlist["base"], video["src"]), "app": urlparse(playlist["base"]).path[1:], "pageUrl": self.url, "rtmp": playlist["base"], "playpath": video["src"], "live": True }) streams[name] = stream return streams
def _get_streams(self): res = http.get(self.url, schema=_schema) streams = {} for url in res["urls"]: parsed = urlparse(url) if parsed.scheme.startswith("rtmp"): params = {"rtmp": url, "pageUrl": self.url, "live": True} if res["swf"]: params["swfVfy"] = res["swf"] stream = RTMPStream(self.session, params) streams["live"] = stream elif parsed.scheme.startswith("http"): name = splitext(parsed.path)[1][1:] stream = HTTPStream(self.session, url) streams[name] = stream return streams
def _create_flv_playlist(self, template): res = http.get(template) playlist = http.json(res, schema=_vod_playlist_schema) parsed = urlparse(template) url_template = "{0}://{1}{2}".format(parsed.scheme, parsed.netloc, playlist["template"]) segment_max = reduce(lambda i, j: i + j[0], playlist["fragments"], 0) substreams = [ HTTPStream(self.session, url_template.replace("$fragment$", str(i))) for i in range(1, segment_max + 1) ] return FLVPlaylist(self.session, duration=playlist["duration"], flatten_timestamps=True, skip_header=True, streams=substreams)
def __init__(self, url): Plugin.__init__(self, url) self._hosted_chain = [] match = _url_re.match(url).groupdict() parsed = urlparse(url) self.params = parse_query(parsed.query) self.subdomain = match.get("subdomain") self.video_id = None self.video_type = None self._channel_id = None self._channel = None self.clip_name = None if self.subdomain == "player": # pop-out player if self.params.get("video"): try: self.video_type = self.params["video"][0] self.video_id = self.params["video"][1:] except IndexError: self.logger.debug("Invalid video param: {0}", self.params["video"]) self._channel = self.params.get("channel") elif self.subdomain == "clips": # clip share URL self.clip_name = match.get("channel") # handle embed: # https://clips.twitch.tv/embed?clip=ImportantSlipperyEndiveBudStar if self.clip_name.startswith("embed?clip="): self.clip_name = self.clip_name.replace("embed?clip=", "") else: self._channel = match.get("channel") and match.get("channel").lower() self.video_type = match.get("video_type") if match.get("videos_id"): self.video_type = "v" self.video_id = match.get("video_id") or match.get("videos_id") self.clip_name = match.get("clip_name") self.api = TwitchAPI(beta=self.subdomain == "beta", version=5) self.usher = UsherService()
def _get_streams(self): args = dict(parse_qsl(urlparse(self.url).query)) if "k" in args: self.logger.debug("Loading channel: {k}", **args) res = http.get(self.url) stream_data_m = self.stream_data_re.search(res.text) if stream_data_m: script_vars = b64decode(stream_data_m.group(1)) url_m = self.m3u8_re.search(script_vars) hls_url = url_m and url_m.group("url") if hls_url: for s in HLSStream.parse_variant_playlist( self.session, hls_url).items(): yield s f4m_m = self.f4mm_re.search(script_vars) f4m_url = f4m_m and f4m_m.group("url") if f4m_url: for n, s in HDSStream.parse_manifest( self.session, f4m_url).items(): yield n, s
def _create_rtmp_stream(self, stream, live=True): rtmp = stream["url"] playpath = stream["name"] parsed = urlparse(rtmp) if parsed.query: app = "{0}?{1}".format(parsed.path[1:], parsed.query) else: app = parsed.path[1:] if playpath.endswith(".mp4"): playpath = "mp4:" + playpath params = { "rtmp": rtmp, "pageUrl": self.url, "swfUrl": SWF_URL, "playpath": playpath, "app": app, } if live: params["live"] = True return RTMPStream(self.session, params)
def _get_live_stream(self, export_url): res = http.get(export_url) match = _live_json_re.search(res.text) if not match: return json = parse_json(match.group(1), schema=_live_schema) streams = {} for stream in json["streams"]: stream_name = stream["quality"] parsed = urlparse(stream["url"]) stream = RTMPStream( self.session, { "rtmp": stream["url"], "app": "{0}?{1}".format(parsed.path[1:], parsed.query), "playpath": stream["name"], "swfVfy": SWF_LIVE_URL, "pageUrl": self.url, "live": True }) streams[stream_name] = stream return streams
def can_handle_url(cls, url): if cls.url_re.match(url) is not None: args = dict(parse_qsl(urlparse(url).query)) return args.get("y") == "tv"
def can_handle_url(self, url): parsed = urlparse(url) return parsed.scheme in PROTOCOL_MAP
def _get_streams(self): """ Find all the streams for the ITV url :return: Mapping of quality to stream """ soap_message = self._soap_request() headers = { 'Content-Length': '{0:d}'.format(len(soap_message)), 'Content-Type': 'text/xml; charset=utf-8', 'Host': 'mercury.itv.com', 'Origin': 'http://www.itv.com', 'Referer': 'http://www.itv.com/Mercury/Mercury_VideoPlayer.swf?v=null', 'SOAPAction': "http://tempuri.org/PlaylistService/GetPlaylist", 'User-Agent': ITV_PLAYER_USER_AGENT, "X-Requested-With": "ShockwaveFlash/16.0.0.305" } res = http.post("http://mercury.itv.com/PlaylistService.svc?wsdl", headers=headers, data=soap_message) # Parse XML xmldoc = http.xml(res) # Check that geo region has been accepted faultcode = xmldoc.find('.//faultcode') if faultcode is not None: if 'InvalidGeoRegion' in faultcode.text: self.logger.error('Failed to retrieve playlist data ' '(invalid geo region)') return None # Look for <MediaFiles> tag (RTMP streams) mediafiles = xmldoc.find('.//VideoEntries//MediaFiles') # Look for <ManifestFile> tag (HDS streams) manifestfile = xmldoc.find('.//VideoEntries//ManifestFile') # No streams if not mediafiles and not manifestfile: return None streams = {} # Proxy not needed for media retrieval (Note: probably better to use flag) # for x in ('http', 'https'): # if x in http.proxies: # http.proxies.pop(x); # Parse RTMP streams if mediafiles: rtmp = mediafiles.attrib['base'] for mediafile in mediafiles.findall("MediaFile"): playpath = mediafile.find("URL").text rtmp_url = urlparse(rtmp) app = (rtmp_url.path[1:] + '?' + rtmp_url.query).rstrip('?') live = app == "live" params = dict( rtmp="{u.scheme}://{u.netloc}{u.path}".format(u=rtmp_url), app=app.rstrip('?'), playpath=playpath, swfVfy=LIVE_SWF_URL if live else ONDEMAND_SWF_URL, timeout=10) if live: params['live'] = True bitrate = int(mediafile.attrib['bitrate']) / 1000 quality = "{0:d}k".format(int(bitrate)) streams[quality] = RTMPStream(self.session, params) # Parse HDS streams if manifestfile: url = manifestfile.find('URL').text if urlparse(url).path.endswith('f4m'): streams.update( HDSStream.parse_manifest(self.session, url, pvswf=LIVE_SWF_URL)) return streams