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_smil(self, url, swf_url): res = http.get(url) smil = http.xml(res, "SMIL config", schema=_smil_schema) for src, bitrate in smil["videos"]: url = urljoin(smil["http_base"], src) yield bitrate, AkamaiHDStream(self.session, url, swf=swf_url)
def _get_streams(self): # get the HLS xml from the same sub domain as the main url, defaulting to www sdomain = _url_re.match(self.url).group(1) or "www" res = http.get(API_URL.format(sdomain)) stream_url = http.xml(res, schema=_schema) return HLSStream.parse_variant_playlist(self.session, stream_url)
def _get_streams(self): match = _url_re.match(self.url) video_id = match.group("video_id") res = http.get(API_URL, params=dict(ak="web", id=video_id)) fmts = http.xml(res, schema=_schema) streams = {} for fmt in fmts: if fmt["type"] in STREAMING_TYPES: name, parser = STREAMING_TYPES[fmt["type"]] try: streams.update(parser(self.session, fmt["url"])) except IOError as err: self.logger.error("Failed to extract {0} streams: {1}", name, err) elif fmt["type"] == "h264_aac_mp4_rtmp_zdfmeta_http": name = fmt["quality"] try: streams[name] = self._create_rtmp_stream(fmt["url"]) except IOError as err: self.logger.error("Failed to extract RTMP stream '{0}': {1}", name, err) return streams
def _get_streams(self): data_url = http.get(self.url, schema=self._player_url_schema) if data_url: res = http.get(urljoin(self.url, data_url)) stream_info = http.xml(res, schema=self._livestream_schema) for stream in stream_info: url = stream["url"] try: if ".m3u8" in url: for s in HLSStream.parse_variant_playlist( self.session, url, name_key="bitrate").items(): yield s elif ".f4m" in url: for s in HDSStream.parse_manifest( self.session, url, pvswf=self.swf_url, is_akamai=True).items(): yield s elif ".mp4" in url: yield "{0}k".format(stream["bitrate"]), HTTPStream( self.session, url) except IOError as err: self.logger.warning("Error parsing stream: {0}", err)
def _get_smil_streams(self, info): res = http.get(info["_stream"]) smil = http.xml(res, "SMIL config", schema=_smil_schema) for video in smil["videos"]: url = "{0}/{1}{2}".format(smil["base"], video, HDCORE_PARAMETER) streams = HDSStream.parse_manifest(self.session, url, pvswf=SWF_URL, is_akamai=smil["cdn"] == "akamai") for stream in streams.items(): yield stream
def _login(self, username, password): res = http.post(self.auth_url, data={ "username": username, "password": password, "cookielink": False }) login_status = http.xml(res, schema=self.auth_schema) self.logger.debug("Login status for {0}: {1}", username, login_status) if login_status == "loginlocked": self.logger.error("The account {0} has been locked, the password needs to be reset") return login_status == "loginsuccess"
def _get_smil_streams(self, info): res = http.get(info["_stream"]) smil = http.xml(res, "SMIL config", schema=_smil_schema) for video in smil["videos"]: url = "{0}/{1}{2}".format(smil["base"], video, HDCORE_PARAMETER) streams = HDSStream.parse_manifest(self.session, url, pvswf=SWF_URL) # TODO: Replace with "yield from" when dropping Python 2. for stream in streams.items(): yield stream
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 _get_streams(self): match = _url_re.match(self.url) channel = match.group("channel") res = http.get(STREAM_INFO_URL.format(channel)) urls = http.xml(res, schema=_livestream_schema) streams = {} for (name, parser), url in urls.items(): try: streams.update(parser(self.session, url)) except IOError as err: self.logger.warning("Unable to extract {0} streams: {1}", name, err) return streams
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 _login(self, username, password): res = http.post(self.auth_url.format(self._domain), data={ "username": username, "password": password, "cookielink": False }) login_status = http.xml(res, schema=self.auth_schema) self.logger.debug("Login status for {0}: {1}", username, login_status) if login_status == "loginlocked": self.logger.error( "The account {0} has been locked, the password needs to be reset" ) return login_status == "loginsuccess"
def _get_smil_streams(self, info): res = http.get(info["_stream"]) smil = http.xml(res, "SMIL config", schema=_smil_schema) for video in smil["videos"]: url = "{0}/{1}{2}".format(smil["base"], video, HDCORE_PARAMETER) streams = HDSStream.parse_manifest( self.session, url, pvswf=SWF_URL, is_akamai=smil["cdn"] == "akamai") for stream in streams.items(): yield stream
def _get_rtmp_stream(self, channel_name): params = { "l": "info", "a": "xmlClipPath", "clip_id": channel_name, "rid": time() } res = http.get(API_URL, params=params) rtmp_url = http.xml(res, schema=_rtmp_schema) return RTMPStream(self.session, { "rtmp": rtmp_url, "swfVfy": SWF_URL, "live": True })
def _get_streams(self): match = self._url_re.match(self.url) video_id = match.group('video_id') if video_id is not None: # VOD res = http.get(self.VOD_API_URL.format(video_id)) stream_data = http.json(res, schema=self._vod_api_schema) # Check whether video format is expired current_date = datetime.strptime(stream_data['current_date'], '%Y-%m-%dT%H:%M:%S.%f') valid_start = datetime.strptime( stream_data['shows']['valid_start'], '%Y-%m-%dT%H:%M:%S') valid_end = datetime.strptime(stream_data['shows']['valid_end'], '%Y-%m-%dT%H:%M:%S') if current_date < valid_start or current_date > valid_end: self.logger.error( 'Failed to access stream, may be due to expired content') return streams = stream_data['shows']['media:group'] else: # Live channel_id = match.group('channel_id') # Get live streams for desktop res = http.get(self.LIVE_API_URL, params={'channelid': channel_id}) streams = http.xml(res, schema=self._live_api_schema) # Get HLS streams for Iphone res = http.get(self.LIVE_API_URL, params={ 'channelid': channel_id, 'platform': 'iphone' }) stream = http.json(res, schema=self._live_api_iphone_schema) if stream != 'none': streams.append(stream) for stream in streams: if '.f4m' in stream: for s in HDSStream.parse_manifest(self.session, stream).items(): yield s if '.m3u8' in stream: for s in HLSStream.parse_variant_playlist( self.session, stream).items(): yield s
def _get_streams(self): cubeid = self._get_live_cubeid() if not cubeid: return res = http.get(API_URL_LIVE, params=dict(cubeid=cubeid)) entries = http.xml(res, schema=_entries_schema) streams = {} for url in entries: try: streams.update( HLSStream.parse_variant_playlist(self.session, url)) except IOError as err: self.logger.error("Failed to open playlist: {0}", err) return streams
def _get_streams(self): cubeid = self._get_live_cubeid() if not cubeid: return res = http.get(API_URL_LIVE, params=dict(cubeid=cubeid)) entries = http.xml(res, schema=_entries_schema) streams = {} for url in entries: try: streams.update( HLSStream.parse_variant_playlist(self.session, url) ) except IOError as err: self.logger.error("Failed to open playlist: {0}", err) return streams
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_media_info(self, content_id): """ Get the info about the content, based on the ID :param content_id: :return: """ params = {"identityPointId": self._session_attributes.get("ipid"), "fingerprint": self._session_attributes.get("fprt"), "contentId": content_id, "playbackScenario": self.playback_scenario, "platform": "WEB_MEDIAPLAYER_5", "subject": "LIVE_EVENT_COVERAGE", "frameworkURL": "https://ws.media.net.wwe.com", "_": int(time.time())} if self.session_key: params["sessionKey"] = self.session_key url = self.api_url.format(id=content_id) res = http.get(url, params=params) return http.xml(res, ignore_ns=True, schema=self._info_schema)
def _get_streams(self): data_url = http.get(self.url, schema=self._player_url_schema) if data_url: res = http.get(urljoin(self.url, data_url)) stream_info = http.xml(res, schema=self._livestream_schema) for stream in stream_info: url = stream["url"] try: if ".m3u8" in url: for s in HLSStream.parse_variant_playlist(self.session, url, name_key="bitrate").items(): yield s elif ".f4m" in url: for s in HDSStream.parse_manifest(self.session, url, pvswf=self.swf_url, is_akamai=True).items(): yield s elif ".mp4" in url: yield "{0}k".format(stream["bitrate"]), HTTPStream(self.session, url) except IOError as err: self.logger.warning("Error parsing stream: {0}", err)
def _get_streams(self): match = _url_re.match(self.url) channel = match.group("channel") res = http.get(CHANNEL_INFO.format(channel)) channel_info = http.json(res) if not channel_info["online"]: return res = http.get(CHANNEL_MANIFEST.format(channel_info["id"])) assets = http.xml(res, schema=_assets_schema) streams = {} for video in assets["videos"]: name = "{0}p".format(video["height"]) stream = RTMPStream(self.session,{ "rtmp" : "{0}/{1}".format(assets["base"], video["src"]) }) streams[name] = stream return streams
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 _get_live_stream(self, channel): res = http.get(self.api_url.format(type="channels", id=channel)) channel_info = http.json(res) if not channel_info["online"]: return res = http.get(self.channel_manifest.format(id=channel_info["id"], type="smil")) assets = http.xml(res, schema=self._assets_schema) for video in assets["videos"]: name = "{0}p".format(video["height"]) stream = RTMPStream(self.session, { "rtmp": "{0}/{1}".format(assets["base"], video["src"]) }) yield name, stream for s in HLSStream.parse_variant_playlist(self.session, self.channel_manifest.format(id=channel_info["id"], type="m3u8")).items(): yield s
def _get_streams(self): match = _url_re.match(self.url) channel = match.group("channel") res = http.get(CHANNEL_INFO.format(channel)) channel_info = http.json(res) if not channel_info["online"]: return res = http.get(CHANNEL_MANIFEST.format(channel_info["id"])) assets = http.xml(res, schema=_assets_schema) streams = {} for video in assets["videos"]: name = "{0}p".format(video["height"]) stream = RTMPStream(self.session, { "rtmp": "{0}/{1}".format(assets["base"], video["src"]) }) streams[name] = stream return streams
def _get_media_info(self, content_id): """ Get the info about the content, based on the ID :param content_id: :return: """ params = { "identityPointId": self._session_attributes.get("ipid"), "fingerprint": self._session_attributes.get("fprt"), "contentId": content_id, "playbackScenario": self.playback_scenario, "platform": "WEB_MEDIAPLAYER_5", "subject": "LIVE_EVENT_COVERAGE", "frameworkURL": "https://ws.media.net.wwe.com", "_": int(time.time()) } if self.session_key: params["sessionKey"] = self.session_key url = self.api_url.format(id=content_id) res = http.get(url, params=params) return http.xml(res, ignore_ns=True, schema=self._info_schema)
def _get_streams(self): match = self._url_re.match(self.url) video_id = match.group('video_id') if video_id is not None: # VOD res = http.get(self.VOD_API_URL.format(video_id)) stream_data = http.json(res, schema=self._vod_api_schema) # Check whether video format is expired current_date = datetime.strptime(stream_data['current_date'], '%Y-%m-%dT%H:%M:%S.%f') valid_start = datetime.strptime(stream_data['shows']['valid_start'], '%Y-%m-%dT%H:%M:%S') valid_end = datetime.strptime(stream_data['shows']['valid_end'], '%Y-%m-%dT%H:%M:%S') if current_date < valid_start or current_date > valid_end: self.logger.error('Failed to access stream, may be due to expired content') return streams = stream_data['shows']['media:group'] else: # Live channel_id = match.group('channel_id') # Get live streams for desktop res = http.get(self.LIVE_API_URL, params={'channelid': channel_id}) streams = http.xml(res, schema=self._live_api_schema) # Get HLS streams for Iphone res = http.get(self.LIVE_API_URL, params={'channelid': channel_id, 'platform': 'iphone'}) stream = http.json(res, schema=self._live_api_iphone_schema) if stream != 'none': streams.append(stream) for stream in streams: if '.f4m' in stream: for s in HDSStream.parse_manifest(self.session, stream).items(): yield s if '.m3u8' in stream: for s in HLSStream.parse_variant_playlist(self.session, stream).items(): yield s
def _get_vod_streams(self, stream_type, page): m = self.stream_vod_data_re.search(page.text) if m is None: return stream_url, stream_id = m.groups() if stream_type == "video": stream_api_id = "v-{}".format(stream_id) default_quality = "vod" elif stream_type == "audio": stream_api_id = "a-{}".format(stream_id) default_quality = "audio" else: return # Retrieve stream embedded in web page yield self._create_stream(stream_url, default_quality) # Retrieve streams using API res = http.get(self.smil_api_url.format(stream_api_id)) videos = http.xml(res, schema=self.smil_schema) for video in videos['streams']: url = videos["base"] + video["src"] if url == stream_url or url.replace("_dwdownload.", ".") == stream_url: continue if video["system-bitrate"] > 0: # If width is available, use it to select the best stream # amongst those with same bitrate quality = "{}k".format( (video["system-bitrate"] + video.get("width", 0)) // 1000) else: quality = default_quality yield self._create_stream(url, quality)
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': 'secure-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("https://secure-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
def _get_meta_url(self, url): res = http.get(url, exception=IOError) root = http.xml(res, exception=IOError) return root.findtext("default-stream-url")
def _get_live_cubeid(self): res = http.get(API_URL_APP, params=dict(mode="get_live")) root = http.xml(res) return root.findtext("./cube/cubeid")
def _get_streams(self): page = http.get(self.url, schema=_schema) if not page: return pubkey_pem = get_public_key(self.cache, urljoin(self.url, page["clientlibs"])) if not pubkey_pem: raise PluginError("Unable to get public key") flashvars = page["flashvars"] params = { "cashPath": int(time.time() * 1000) } res = http.get(urljoin(self.url, flashvars["country"]), params=params) if not res: return language = http.xml(res, schema=_language_schema) api_params = {} for key in ("ss_id", "mv_id", "device_cd", "ss1_prm", "ss2_prm", "ss3_prm"): if flashvars.get(key, ""): api_params[key] = flashvars[key] aeskey = number.long_to_bytes(random.getrandbits(8 * 32), 32) params = { "s": flashvars["s"], "c": language, "e": self.url, "d": aes_encrypt(aeskey, json.dumps(api_params)), "a": rsa_encrypt(pubkey_pem, aeskey) } res = http.get(urljoin(self.url, flashvars["init"]), params=params) if not res: return rtn = http.json(res, schema=_init_schema) if not rtn: return init_data = parse_json(aes_decrypt(aeskey, rtn)) parsed = urlparse(init_data["play_url"]) if parsed.scheme != "https" or not parsed.path.startswith("/i/") or not parsed.path.endswith("/master.m3u8"): return hlsstream_url = init_data["play_url"] streams = HLSStream.parse_variant_playlist(self.session, hlsstream_url) if "caption_url" in init_data: if self.get_option("mux_subtitles") and FFMPEGMuxer.is_usable(self.session): res = http.get(init_data["caption_url"]) srt = http.xml(res, ignore_ns=True, schema=_xml_to_srt_schema) subfiles = [] metadata = {} for i, lang, srt in ((i, s[0], s[1]) for i, s in enumerate(srt)): subfile = tempfile.TemporaryFile() subfile.write(srt.encode("utf8")) subfile.seek(0) subfiles.append(FileStream(self.session, fileobj=subfile)) metadata["s:s:{0}".format(i)] = ["language={0}".format(lang)] for n, s in streams.items(): yield n, MuxedStream(self.session, s, *subfiles, maps=list(range(0, len(metadata) + 1)), metadata=metadata) return else: self.logger.info("Subtitles: {0}".format(init_data["caption_url"])) for s in streams.items(): yield s