def _get_streams(self): api = self._create_api() match = _url_re.match(self.url) media_id = int(match.group("media_id")) try: info = api.get_info(media_id, fields=["media.stream_data"], schema=_media_schema) except CrunchyrollAPIError as err: raise PluginError(u"Media lookup error: {0}".format(err.msg)) if not info: return # The adaptive quality stream contains a superset of all the other streams listeed has_adaptive = any([s[u"quality"] == u"adaptive" for s in info[u"streams"]]) if has_adaptive: self.logger.debug(u"Loading streams from adaptive playlist") for stream in filter(lambda x: x[u"quality"] == u"adaptive", info[u"streams"]): return HLSStream.parse_variant_playlist(self.session, stream["url"]) else: streams = {} # If there is no adaptive quality stream then parse each individual result for stream in info[u"streams"]: # the video_encode_id indicates that the stream is not a variant playlist if u"video_encode_id" in stream: streams[stream[u"quality"]] = HLSStream(self.session, stream[u"url"]) else: # otherwise the stream url is actually a list of stream qualities streams.update(HLSStream.parse_variant_playlist(self.session, stream[u"url"])) return streams
def _get_streams(self): stream_type = self._url_re.match(self.url).group("type") hls_re = re.compile(r"""["'](?P<url>[^"']+\.m3u8[^"']*?)["']""") headers = { "Origin": "https://www.metube.id", "User-Agent": useragents.FIREFOX } res = self.session.http.get(self.url) match = hls_re.search(res.text) if not match: return stream_url = match.group("url") if stream_type == "live": return HLSStream.parse_variant_playlist(self.session, stream_url, headers=headers) else: streams = {} for quality, stream in HLSStream.parse_variant_playlist( self.session, stream_url, headers=headers).items(): name = self._VOD_STREAM_NAMES.get(quality, quality) streams[name] = stream return streams
def _get_streams(self): email = self.get_option("email") password = self.get_option("password") if not self._authed and (not email and not password): self.logger.error("A login for WWE Network is required, use --wwenetwork-email/" "--wwenetwork-password to set them") return if not self._authed: if not self.login(email, password): self.logger.error("Failed to login, check your username/password") return content_id = self._get_content_id() if content_id: self.logger.debug("Found content ID: {0}", content_id) info = self._get_media_info(content_id) if info["status"]["code"] == 1: # update the session attributes self._update_session_attribute("fprt", info.get("fingerprint")) for attr in info["session_attributes"]: self._update_session_attribute(attr["name"], attr["value"]) if info.get("session_key"): self.session_key = info.get("session_key") for url in info["urls"]: for s in HLSStream.parse_variant_playlist(self.session, url, name_fmt="{pixels}_{bitrate}").items(): yield s else: raise PluginError("Could not load streams: {message} ({code})".format(**info["status"]))
def _get_streams(self): match = _url_re.match(self.url) res = http.get(STREAM_INFO_URL, params=match.groupdict(), acceptable_status=STATUS_UNAVAILABLE) if res.status_code in STATUS_UNAVAILABLE: return data = http.json(res, schema=_stream_schema) if data.get("hls_url"): hls_url = data["hls_url"] hls_name = "live" elif data.get("replay_url"): self.logger.info("Live Stream ended, using replay instead") hls_url = data["replay_url"] hls_name = "replay" else: raise NoStreamsError(self.url) streams = HLSStream.parse_variant_playlist(self.session, hls_url) if not streams: return {hls_name: HLSStream(self.session, hls_url)} else: return streams
def _get_streams(self): iframe_url = self._get_iframe_url(self.url) if iframe_url: log.debug("Found iframe URL={0}".format(iframe_url)) info_url = self._get_stream_info_url(iframe_url) if info_url: log.debug("Getting info from URL: {0}".format(info_url)) res = self.session.http.get(info_url, headers={"Referer": iframe_url}) data = self.session.http.json(res) if data['status'] == 200: for media in data['data']['playlist']['medialist']: if media['errors']: log.error(media['errors'].replace('\n', '').replace('\r', '')) for media_type in media.get('sources', []): if media_type == "m3u8": hls_url = media['sources'][media_type]['auto'] for s in HLSStream.parse_variant_playlist(self.session, hls_url).items(): yield s if media_type == "http": for pix, url in media['sources'][media_type].items(): yield "{0}p".format(pix), HTTPStream(self.session, url) else: log.error("An error occurred: {0}".format(data['errors'].replace('\n', '').replace('\r', ''))) else: log.error("Unable to get stream info URL") else: log.error("Could not find video iframe")
def _get_streams(self): match = _url_re.match(self.url) username = match.group("username") CSRFToken = str(uuid.uuid4().hex.upper()[0:32]) headers = { "Content-Type": "application/x-www-form-urlencoded", "X-CSRFToken": CSRFToken, "X-Requested-With": "XMLHttpRequest", "Referer": self.url, } cookies = { "csrftoken": CSRFToken, } post_data = "room_slug={0}&bandwidth=high".format(username) res = http.post(API_HLS, headers=headers, cookies=cookies, data=post_data) data = http.json(res, schema=_post_schema) if data["success"] is True and data["room_status"] == "public": for s in HLSStream.parse_variant_playlist(self.session, data["url"]).items(): yield s
def _get_streams(self): if self.get_option("email") and self.get_option("password"): if not self.authenticate(self.get_option("email"), self.get_option("password")): self.logger.warning("Failed to login as {0}".format(self.get_option("email"))) # find the list of channels from the html in the page self.url = self.url.replace("https", "http") # https redirects to http res = http.get(self.url) if "enter your postcode" in res.text: self.logger.info("Setting your postcode to: {0}. " "This can be changed in the settings on tvplayer.com", self.dummy_postcode) res = http.post(self.update_url, data=dict(postcode=self.dummy_postcode), params=dict(return_url=self.url)) stream_attrs = self._get_stream_attrs(res) if stream_attrs: stream_data = self._get_stream_data(**stream_attrs) if stream_data: if stream_data.get("drmToken"): self.logger.error("This stream is protected by DRM can cannot be played") return else: return HLSStream.parse_variant_playlist(self.session, stream_data["stream"]) else: if "need to login" in res.text: self.logger.error( "You need to login using --tvplayer-email/--tvplayer-password to view this stream")
def _get_hls_streams(self, type="live"): self._authenticate() if self._check_for_host() and self.options.get("disable_hosting"): self.logger.info("hosting was disabled by command line option") return {} else: self.logger.info("switching to {}", self.channel) sig, token = self._access_token(type) if type == "live": url = self.usher.channel(self.channel, sig=sig, token=token) elif type == "video": url = self.usher.video(self.video_id, nauthsig=sig, nauth=token) try: streams = HLSStream.parse_variant_playlist(self.session, url) except IOError as err: err = str(err) if "404 Client Error" in err or "Failed to parse playlist" in err: return else: raise PluginError(err) try: token = parse_json(token, schema=_token_schema) for name in token["restricted_bitrates"]: if name not in streams: self.logger.warning("The quality '{0}' is not available " "since it requires a subscription.", name) except PluginError: pass return streams
def _get_streams(self): mdata = self._get_movie_data() if mdata: log.debug("Found video: {0} ({1})".format(mdata["title"], mdata["id"])) if mdata["media"]["url"]: for s in HLSStream.parse_variant_playlist(self.session, mdata["media"]["url"]).items(): yield s elif self.get_option("email") and self.get_option("password"): if self.login(self.get_option("email"), self.get_option("password")): details = self._get_details(mdata["id"]) if details: for item in details["items"]: for s in HLSStream.parse_variant_playlist(self.session, item["media"]["url"]).items(): yield s else: log.error("You must login to access this stream")
def _get_streams(self): if _stream_url_re.match(self.url): mode = MODE_STREAM else: mode = MODE_VOD res = http.get(self.url) match = _json_re.search(res.text) if match: data = json.loads(_json_re.search(res.text).group('json')) else: raise PluginError("Could not extract JSON metadata") streams = {} try: if mode == MODE_STREAM: sources = data['values']['episode']['livestream_playlist_data']['videos'][0]['sources'] elif mode == MODE_VOD: sources = data['values']['segment']['playlist_item_array']['sources'] except (KeyError, IndexError): raise PluginError("Could not extract sources") for source in sources: try: if source['delivery'] != 'hls': continue url = source['src'].replace('\/', '/') except KeyError: continue stream = HLSStream.parse_variant_playlist(self.session, url) streams.update(stream) return streams
def _get_streams(self): match = _url_re.match(self.url) channel = match.group("channel") self.session.http.headers.update({'User-Agent': useragents.CHROME}) payload = '{"liveStreamID": "%s"}' % (channel) res = self.session.http.post(API_URL, data=payload) status = _status_re.search(res.text) if not status: self.logger.info("Stream currently unavailable.") return http_url = _rtmp_re.search(res.text).group(1) http_url = http_url.replace("http:", "https:") yield "live", HTTPStream(self.session, http_url) if 'pull-rtmp' in http_url: url = http_url.replace("https:", "rtmp:").replace(".flv", "") stream = RTMPStream(self.session, { "rtmp": url, "live": True }) yield "live", stream if 'wansu-' in http_url: url = http_url.replace(".flv", "/playlist.m3u8") for stream in HLSStream.parse_variant_playlist(self.session, url).items(): yield stream else: url = http_url.replace("live-hdl", "live-hls").replace(".flv", ".m3u8") yield "live", HLSStream(self.session, url)
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): # 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 = self.session.http.get(API_URL.format(sdomain)) stream_url = self.session.http.xml(res, schema=_schema) return HLSStream.parse_variant_playlist(self.session, stream_url)
def _get_streams(self): match = _url_re.match(self.url) channel = match.group("channel") domain = match.group("domain") headers = { "Referer": self.url, "User-Agent": useragents.FIREFOX } if domain == "canlitv.plus": res = http.get(EMBED_URL_1.format(channel), headers=headers) elif domain == "ecanlitvizle.net": res = http.get(EMBED_URL_2.format(channel), headers=headers) else: res = http.get(self.url, headers=headers) url_match = _m3u8_re.search(res.text) if url_match: hls_url = url_match.group("url") if domain in ("canlitvlive.live", "canlitvlive.site"): hls_url = "http:" + hls_url self.logger.debug("Found URL: {0}".format(hls_url)) try: s = [] for s in HLSStream.parse_variant_playlist(self.session, hls_url).items(): yield s if not s: yield "live", HLSStream(self.session, hls_url) except IOError as err: self.logger.error("Failed to extract streams: {0}", err)
def _get_vod_streams(self, params): manifest_url = params.get("autoURL") if not manifest_url: return res = http.get(manifest_url) if res.headers.get("Content-Type") == "application/f4m+xml": streams = HDSStream.parse_manifest(self.session, res.url) # TODO: Replace with "yield from" when dropping Python 2. for __ in streams.items(): yield __ elif res.headers.get("Content-Type") == "application/vnd.apple.mpegurl": streams = HLSStream.parse_variant_playlist(self.session, res.url) # TODO: Replace with "yield from" when dropping Python 2. for __ in streams.items(): yield __ else: manifest = http.json(res, schema=_vod_manifest_schema) for params in manifest["alternates"]: name = "{0}p".format(params["height"]) stream = self._create_flv_playlist(params["template"]) yield name, stream failovers = params.get("failover", []) for failover in failovers: stream = self._create_flv_playlist(failover) yield name, stream
def mediaselector(self, vpid): urls = defaultdict(set) for platform in self.platforms: url = self.api_url.format(vpid=vpid, vpid_hash=self._hash_vpid(vpid), platform=platform) log.debug("Info API request: {0}", url) medias = self.session.http.get(url, schema=self.mediaselector_schema) for media in medias: for connection in media["connection"]: urls[connection.get("transferFormat")].add(connection["href"]) for stream_type, urls in urls.items(): log.debug("{0} {1} streams", len(urls), stream_type) for url in list(urls): try: if stream_type == "hds": for s in HDSStream.parse_manifest(self.session, url).items(): yield s if stream_type == "hls": for s in HLSStream.parse_variant_playlist(self.session, url).items(): yield s if stream_type == "dash": for s in DASHStream.parse_manifest(self.session, url).items(): yield s log.debug(" OK: {0}", url) except: log.debug(" FAIL: {0}", url)
def _get_streams(self): res = self.session.http.get(self.url) match = self._video_id_re.search(res.text) or self._video_id_alt_re.search(res.text) if match is None: return broadcaster_id = match.group('broadcaster_id') video_type = match.group('video_type') video_id = match.group('video_id') videos = self.session.http.get(self.DACAST_API_URL.format(broadcaster_id, video_type, video_id), schema=self._api_schema) token = self.session.http.get(self.DACAST_TOKEN_URL.format(broadcaster_id, video_type, video_id), schema=self._token_schema) parsed = [] for video_url in videos: video_url += token # Ignore duplicate video URLs if video_url in parsed: continue parsed.append(video_url) # Ignore HDS streams (broken) if '.m3u8' in video_url: for s in HLSStream.parse_variant_playlist(self.session, video_url).items(): yield s
def _get_streams(self): if "eltrecetv.com.ar/vivo" in self.url.lower(): try: http.headers = {'Referer': self.url, 'User-Agent': useragents.ANDROID} res = http.get('https://api.iamat.com/metadata/atcodes/eltrece') yt_id = parse_json(res.text)["atcodes"][0]["context"]["ahora"]["vivo"]["youtubeVideo"] yt_url = "https://www.youtube.com/watch?v={0}".format(yt_id) return self.session.streams(yt_url) except BaseException: self.logger.info("Live content is temporarily unavailable. Please try again later.") else: try: http.headers = {'Referer': self.url, 'User-Agent': useragents.CHROME} res = http.get(self.url) _player_re = re.compile(r'''data-kaltura="([^"]+)"''') match = _player_re.search(res.text) if not match: return entry_id = parse_json(match.group(1).replace(""", '"'))["entryId"] hls_url = "https://vodgc.com/p/111/sp/11100/playManifest/entryId/{0}/format/applehttp/protocol/https/a.m3u8".format(entry_id) return HLSStream.parse_variant_playlist(self.session, hls_url) except BaseException: self.logger.error("The requested VOD content is unavailable.")
def _get_vod_stream(self): vod_url = self.url if vod_url.endswith('/'): vod_url = vod_url[:-1] json_url = '{0}.securevideo.json'.format(vod_url) res = http.get(json_url) match = _json_re.search(res.text) if not match: return data = parse_json(match.group(1)) res = http.get(API_VOD.format(data['clientid'], data['mzid'])) data = http.json(res, schema=_stream_schema) for d in data['targetUrls']: if d['type'] == 'HDS': hds_url = d['url'] for s in HDSStream.parse_manifest(self.session, hds_url).items(): yield s if d['type'] == 'HLS': hls_url = d['url'] for s in HLSStream.parse_variant_playlist(self.session, hls_url).items(): yield s
def _get_streams(self): """ Finds the streams from tvcatchup.com. """ token = self.login(self.get_option("username"), self.get_option("password")) m = self._url_re.match(self.url) scode = m and m.group("scode") or self.get_option("station_code") res = http.get(self._guide_url) channels = {} for t in itertags(res.text, "a"): if t.attributes.get('cs'): channels[t.attributes.get('cs').lower()] = t.attributes.get('title').replace("Watch ", "") if not scode: self.logger.error("Station code not provided, use --ustvnow-station-code.") self.logger.error("Available stations are: {0}", ", ".join(channels.keys())) return if scode in channels: self.logger.debug("Finding streams for: {0}", channels.get(scode)) r = http.get(self._stream_url, params={"scode": scode, "token": token, "br_n": "Firefox", "br_v": "52", "br_d": "desktop"}, headers={"User-Agent": useragents.FIREFOX}) data = http.json(r) return HLSStream.parse_variant_playlist(self.session, data["stream"]) else: self.logger.error("Invalid station-code: {0}", scode)
def _get_streams(self): match = self._url_re.match(self.url) channel = match.group('channel') res = self.session.http.get(self.FORMATS_URL.format(channel)) streams = self.session.http.json(res, schema=self._formats_schema)['streams'] if streams == []: self.logger.error('Channel may be geo-restricted, not directly provided by PlayTV or not freely available') return for language in streams: for protocol, bitrates in list(streams[language].items()): # - Ignore non-supported protocols (RTSP, DASH) # - Ignore deprecated Flash (RTMPE/HDS) streams (PlayTV doesn't provide anymore a Flash player) if protocol in ['rtsp', 'flash', 'dash', 'hds']: continue for bitrate in bitrates['bitrates']: if bitrate['value'] == 0: continue api_url = self.API_URL.format(channel, protocol, language, bitrate['value']) res = self.session.http.get(api_url) video_url = self.session.http.json(res, schema=self._api_schema)['url'] bs = '{0}k'.format(bitrate['value']) if protocol == 'hls': for _, stream in HLSStream.parse_variant_playlist(self.session, video_url).items(): yield bs, stream elif protocol == 'hds': for _, stream in HDSStream.parse_manifest(self.session, video_url).items(): yield bs, stream
def _get_streams(self): res = self.session.http.get(self.url, headers={'User-Agent': useragents.CHROME}) video_search = res.text video_search = video_search[video_search.index('{"top":{"view":"PlayerContainer","model":{'):] video_search = video_search[: video_search.index('}]}}') + 4] + "}" video_url_found_hls = "" video_url_found_http = "" json_video_search = parse_json(video_search) json_video_search_sources = json_video_search["top"]["model"]["videos"][0]["sources"] self.logger.debug('Video ID found: {0}', json_video_search["top"]["model"]["id"]) for current_video_source in json_video_search_sources: if "HLS" in current_video_source["type"]: video_url_found_hls = "http://telefe.com" + current_video_source["url"] self.logger.debug("HLS content available") if "HTTP" in current_video_source["type"]: video_url_found_http = "http://telefe.com" + current_video_source["url"] self.logger.debug("HTTP content available") self.session.http.headers = {'Referer': self.url, 'User-Agent': useragents.CHROME, 'X-Requested-With': 'ShockwaveFlash/25.0.0.148'} if video_url_found_hls: hls_streams = HLSStream.parse_variant_playlist(self.session, video_url_found_hls) for s in hls_streams.items(): yield s if video_url_found_http: yield "http", HTTPStream(self.session, video_url_found_http)
def _get_streams(self): channel = self.url_re.match(self.url).group(1) res = http.get(self.api_url.format(channel)) data = http.json(res, schema=self.api_schema) return HLSStream.parse_variant_playlist(self.session, data["channel_stream_url"])
def _get_streams(self): http.headers.update({"User-Agent": useragents.CHROME, "Referer": self.referer}) fragment = dict(parse_qsl(urlparse(self.url).fragment)) link = fragment.get("link") if not link: link = self._get_tv_link() if not link: self.logger.error("Missing link fragment: stream unavailable") return player_url = self._api_url.format(link) self.logger.debug("Requesting player API: {0} (referer={1})", player_url, self.referer) res = http.get(player_url, params={"_": int(time.time() * 1000)}, headers={"X-Requested-With": "XMLHttpRequest"}) try: data = http.json(res, schema=self.api_schema) except PluginError as e: print(e) self.logger.error("Cannot play this stream type") else: if data["status"]: if data["file"].startswith("<"): self.logger.error("Cannot play embedded streams") else: return HLSStream.parse_variant_playlist(self.session, data["file"]) else: self.logger.error(data["text"])
def _get_streams(self): if self.is_live: self.logger.debug("Loading live stream for {0}...", self.channel) res = self.session.http.get(self.live_api_url, data={"r": random.randint(1, 100000)}) live_data = self.session.http.json(res) # all the streams are equal for each type, so pick a random one hls_streams = live_data.get("hls") if hls_streams: url = random.choice(hls_streams) url = url + '&' + urlencode(self.hls_session()) # TODO: use update_qsd for s in HLSStream.parse_variant_playlist(self.session, url, name_fmt="{pixels}_{bitrate}").items(): yield s mpd_streams = live_data.get("mpd") if mpd_streams: url = random.choice(mpd_streams) for s in DASHStream.parse_manifest(self.session, url).items(): yield s elif self.channel == "1tv": self.logger.debug("Attempting to find VOD stream...", self.channel) vod_data = self.vod_data() if vod_data: self.logger.info(u"Found VOD: {0}".format(vod_data[0]['title'])) for stream in vod_data[0]['mbr']: yield stream['name'], HTTPStream(self.session, update_scheme(self.url, stream['src']))
def _get_streams(self): if _stream_url_re.match(self.url): mode = MODE_STREAM else: mode = MODE_VOD res = http.get(self.url) match = _json_re.search(res.text) if match: data = json.loads(_json_re.search(res.text).group('json').replace('"', '"')) else: raise PluginError("Could not extract JSON metadata") streams = {} try: if mode == MODE_STREAM: sources = data['playlist']['videos'][0]['sources'] elif mode == MODE_VOD: sources = data['selected_video']['sources'] except (KeyError, IndexError): raise PluginError("Could not extract sources") for source in sources: try: if source['delivery'] != 'hls': continue url = source['src'].replace(r'\/', '/') except KeyError: continue stream = HLSStream.parse_variant_playlist(self.session, url) # work around broken HTTP connection persistence by acquiring a new connection http.close() streams.update(stream) return streams
def _get_video_streams(self): res = self.session.http.get(self.url) match = self._video_player_re.search(res.text) if match is None: return player_url = match.group('player_url') stream_data = self.session.http.get(player_url, schema=self._video_stream_schema) if stream_data is None: return # Check geolocation to prevent further errors when stream is parsed if not self.check_geolocation(stream_data['geoLocRestriction']): self.logger.error('Stream is geo-restricted') return # Check whether streams are DRM-protected if stream_data.get('drm', False): self.logger.error('Stream is DRM-protected') return now = datetime.datetime.now() try: if isinstance(stream_data['sources'], dict): urls = [] for profile, url in stream_data['sources'].items(): if not url or url in urls: continue match = self._stream_size_re.match(url) if match is not None: quality = match.group('size') else: quality = profile yield quality, HTTPStream(self.session, url) urls.append(url) hls_url = stream_data.get('urlHls') or stream_data.get('streamUrlHls') if hls_url: if stream_data.get('isLive', False): # Live streams require a token hls_url = self.tokenize_stream(hls_url) for stream in HLSStream.parse_variant_playlist(self.session, hls_url).items(): yield stream dash_url = stream_data.get('urlDash') or stream_data.get('streamUrlDash') if dash_url: if stream_data.get('isLive', False): # Live streams require a token dash_url = self.tokenize_stream(dash_url) for stream in DASHStream.parse_manifest(self.session, dash_url).items(): yield stream except IOError as err: if '403 Client Error' in str(err): # Check whether video is expired if 'startDate' in stream_data: if now < self.iso8601_to_epoch(stream_data['startDate']): self.logger.error('Stream is not yet available') elif 'endDate' in stream_data: if now > self.iso8601_to_epoch(stream_data['endDate']): self.logger.error('Stream has expired')
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): match = _url_re.match(self.url) channel = match.group("channel") channel = channel.replace("_", "-") playlist_url = PLAYLIST_URL.format(channel) return HLSStream.parse_variant_playlist(self.session, playlist_url, check_streams=True)
def _get_streams(self): user = self.login(self.options.get("email"), self.options.get("password")) if user: self.logger.debug("Logged in to Schoolism as {0}", user) res = http.get(self.url, headers={"User-Agent": useragents.SAFARI_8}) lesson_playlist = self.playlist_schema.validate(res.text) part = self.options.get("part") self.logger.info("Attempting to play lesson Part {0}", part) found = False # make request to key-time api, to get key specific headers res = http.get(self.key_time_url, headers={"User-Agent": useragents.SAFARI_8}) for i, video in enumerate(lesson_playlist, 1): if video["sources"] and i == part: found = True for source in video["sources"]: for s in HLSStream.parse_variant_playlist(self.session, source["src"], headers={"User-Agent": useragents.SAFARI_8, "Referer": self.url}).items(): yield s if not found: self.logger.error("Could not find lesson Part {0}", part)
def _get_streams(self): headers = { "User-Agent": useragents.FIREFOX, "Referer": self.url, } res = self.session.http.get(self.url, headers=headers) for id_re in (self._id_re, self._id_2_re): m = id_re.search(res.text) if not m: continue break if not m: log.error("No video id found") return dvr_id = m.group("id") log.debug("Found video id: {0}".format(dvr_id)) data = {"feed": "hd", "dvrId": dvr_id} res = self.session.http.post(self.api_url, headers=headers, data=data) if res.status_code == 200: yield from HLSStream.parse_variant_playlist( self.session, res.text, headers=headers).items()
def _get_streams(self): m = self._live_url_re.search(self.page.text) playlist_url = m and update_scheme(self.url, m.group(1)) player_url = self.url live_channel = None p = urlparse(player_url) channelnumber = 0 if p.netloc.endswith("tvc.com.ec"): live_channel = "Canal5" elif p.netloc.endswith("rts.com.ec"): live_channel = "Guayaquil" elif p.netloc.endswith("atv.pe"): if p.path.endswith(("ATVMas", "ATVMas/")): live_channel = "ATVMas" channelnumber = 1 else: live_channel = "ATV" token = self._get_token(channelnumber) log.debug("token {0}".format(token)) if playlist_url: log.debug("Found playlist URL in the page") else: if live_channel: log.debug("Live channel: {0}".format(live_channel)) player_url = self._channel_urls[live_channel] + quote(token) page = self.session.http.get(player_url, raise_for_status=False) if "block access from your country." in page.text: raise PluginError("Content is geo-locked") m = self._playlist_re.search(page.text) playlist_url = m and update_scheme(self.url, m.group(1)) else: log.error("Could not find the live channel") if playlist_url: stream_url = "{0}?{1}".format(playlist_url, urlencode({"iut": token})) return HLSStream.parse_variant_playlist(self.session, stream_url, headers={"referer": player_url})
def _get_streams(self): url_m = self._url_re.match(self.url) domain = url_m.group(1) or url_m.group(2) # remap the domain to channel channel = { "atv": "atvhd", "ahaber": "ahaberhd", "aspor": "asporhd", "anews": "anewshd", "minikacocuk": "minikagococuk" }.get(domain, domain) hls_url = self._hls_url.format(channel=channel) # get the secure HLS URL res = http.get(self._token_url, params="url={0}".format(hls_url), headers={ "Referer": self.url, "User-Agent": useragents.CHROME }) secure_hls_url = http.json(res, schema=self._token_schema) self.logger.debug("Found HLS URL: {0}".format(secure_hls_url)) return HLSStream.parse_variant_playlist(self.session, secure_hls_url)
def _get_streams(self): match = self._url_re.match(self.url) channel = match.group('channel') res = http.get(self.FORMATS_URL.format(channel)) streams = http.json(res, schema=self._formats_schema)['streams'] if streams == []: self.logger.error( 'Channel may be geo-restricted, not directly provided by PlayTV or not freely available' ) return for language in streams: for protocol, bitrates in list(streams[language].items()): # - Ignore non-supported protocols (RTSP, DASH) # - Ignore deprecated Flash (RTMPE/HDS) streams (PlayTV doesn't provide anymore a Flash player) if protocol in ['rtsp', 'flash', 'dash', 'hds']: continue for bitrate in bitrates['bitrates']: if bitrate['value'] == 0: continue api_url = self.API_URL.format(channel, protocol, language, bitrate['value']) res = http.get(api_url) video_url = http.json(res, schema=self._api_schema)['url'] bs = '{0}k'.format(bitrate['value']) if protocol == 'hls': for _, stream in HLSStream.parse_variant_playlist( self.session, video_url).items(): yield bs, stream elif protocol == 'hds': for _, stream in HDSStream.parse_manifest( self.session, video_url).items(): yield bs, stream
def _get_streams(self): if _stream_url_re.match(self.url): mode = MODE_STREAM else: mode = MODE_VOD res = self.session.http.get(self.url) match = _json_re.search(res.text) if match: data = json.loads( _json_re.search(res.text).group('json').replace('"', '"')) else: raise PluginError("Could not extract JSON metadata") streams = {} try: if mode == MODE_STREAM: sources = data['playlist']['videos'][0]['sources'] elif mode == MODE_VOD: sources = data['selected_video']['sources'] except (KeyError, IndexError): raise PluginError("Could not extract sources") for source in sources: try: if source['delivery'] != 'hls': continue url = source['src'].replace(r'\/', '/') except KeyError: continue stream = HLSStream.parse_variant_playlist(self.session, url) # work around broken HTTP connection persistence by acquiring a new connection self.session.http.close() streams.update(stream) return streams
def _get_streams(self): res = self._get_res(self.url) data = self._get_data(res) if not self._data_status(data): data = self._get_data_from_api(res) if not self._data_status(data): return video_id, self.author, self.title, is_live = self._schema_videodetails(data) log.debug(f"Using video ID: {video_id}") if is_live: log.debug("This video is live.") streams = {} hls_manifest, formats, adaptive_formats = self._schema_streamingdata(data) protected = next((True for url, *_ in formats + adaptive_formats if url is None), False) if protected: log.debug("This video may be protected.") for url, label in formats: if url is None: continue streams[label] = HTTPStream(self.session, url) if not is_live: streams.update(self._create_adaptive_streams(adaptive_formats)) if hls_manifest: streams.update(HLSStream.parse_variant_playlist(self.session, hls_manifest, name_key="pixels")) if not streams and protected: raise PluginError("This plugin does not support protected videos, try youtube-dl instead") return streams
def _get_streams(self): api_url = self.session.http.get(self.url, schema=self._data_content_schema) if api_url and (api_url.startswith("/") or api_url.startswith("http")): api_url = urljoin(self.url, api_url) stream_url = self.session.http.get(api_url, schema=self._api_schema, headers={"Referer": self.url}) elif api_url and api_url.startswith("[{"): stream_url = self._api_schema.validate(api_url) else: return parsed = urlparse(stream_url) api_url = urljoin( self.url, self._token_api_path.format(url=stream_url, netloc="{0}://{1}".format( parsed.scheme, parsed.netloc), time=int(time()))) stream_url = self.session.http.get(api_url, schema=self._stream_schema, headers={"Referer": self.url}) return HLSStream.parse_variant_playlist(self.session, stream_url)
def _get_streams(self): match = _url_re.match(self.url) if match: ident = match.group(1) data_url = STREAM_INFO_URL.format(ident=ident) # find the region, default to TOTS (international) res = http.get(self.url) geo_data = re.search(r'data-geo="([A-Z]+?)"', res.text) geo = geo_data and geo_data.group(1) or "TOTS" stream_data = http.json(http.get(data_url), schema=_channel_schema) # If there is only one item, it's not a list ... silly if isinstance(stream_data['media'], list): stream_infos = stream_data['media'] else: stream_infos = [stream_data['media']] for stream in stream_infos: if stream['geo'] == geo: return HLSStream.parse_variant_playlist( self.session, stream['url'])
def _get_streams_live(self): log.debug("Getting live HLS streams for {0}".format(self.channel)) try: data = json.dumps({"query": """query {{ userByDisplayName(displayname:"{displayname}") {{ livestream {{ title }} username }} }}""".format(displayname=self.channel)}) res = self.session.http.post("https://graphigo.prd.dlive.tv/", data=data) res = self.session.http.json(res, schema=self._schema_userByDisplayName) if res["livestream"] is None: return except PluginError: return self.author = self.channel self.title = res["livestream"]["title"] hls_url = "https://live.prd.dlive.tv/hls/live/{0}.m3u8".format(res["username"]) return HLSStream.parse_variant_playlist(self.session, hls_url)
def _get_streams(self): info = self._get_stream_info() if not info: return stream_info = info["event"]["stream_info"] if not (stream_info and stream_info["is_live"]): # Stream is not live return play_url = stream_info.get("play_url") if play_url: swf_url = info.get("playerUri") if swf_url: if not swf_url.startswith("http"): swf_url = "http://" + swf_url # Work around broken SSL. swf_url = swf_url.replace("https://", "http://") qualities = stream_info["qualities"] for bitrate, stream in self._parse_smil(play_url, swf_url): name = "{0:d}k".format(int(bitrate / 1000)) for quality in qualities: if quality["bitrate"] == bitrate: name = "{0}p".format(quality["height"]) yield name, stream m3u8_url = stream_info.get("m3u8_url") if m3u8_url: streams = HLSStream.parse_variant_playlist(self.session, m3u8_url, namekey="pixels") # TODO: Replace with "yield from" when dropping Python 2. for stream in streams.items(): yield stream
def _get_streams(self): res = self.session.http.get(self.url) # some pages have embedded players iframe_m = self.iframe_re.search(res.text) if iframe_m: url = urljoin(self.url, iframe_m.group("url")) res = self.session.http.get(url) video = self.src_re.search(res.text) stream_src = video and video.group("url") if stream_src and stream_src.endswith("m3u8"): # do not open empty m3u8 files if len(self.session.http.get(stream_src).text) <= 10: log.error("This stream is currently offline") return log.debug("URL={0}".format(stream_src)) streams = HLSStream.parse_variant_playlist(self.session, stream_src) if not streams: return {"live": HLSStream(self.session, stream_src)} else: return streams
def _get_streams(self): if '/news/videos/' in self.url: # VOD streams = self._get_vod_streams() else: # Live streams = self._get_live_streams() for video_url in streams: if '.f4m' in video_url: for stream in HDSStream.parse_manifest(self.session, video_url).items(): yield stream elif '.m3u8' in video_url: for stream in HLSStream.parse_variant_playlist( self.session, video_url).items(): yield stream if '.mp4' in video_url: match = self._mp4_bitrate_re.match(video_url) if match is not None: bitrate = match.group('bitrate') + 'k' else: bitrate = 'vod' yield bitrate, HTTPStream(self.session, video_url)
def _get_streams(self): match = _url_re.match(self.url) channel = match.group("channel") self.session.http.headers.update({'User-Agent': useragents.CHROME, 'Referer': self.url}) payload = '{"liveStreamID": "%s"}' % (channel) res = self.session.http.post(API_URL, data=payload) status = _status_re.search(res.text) if not status: self.logger.info("Stream currently unavailable.") return http_url = _rtmp_re.search(res.text).group(1) https_url = http_url.replace("http:", "https:") yield "live", HTTPStream(self.session, https_url) if 'pull-rtmp' in http_url: rtmp_url = http_url.replace("http:", "rtmp:").replace(".flv", "") stream = RTMPStream(self.session, { "rtmp": rtmp_url, "live": True, "pageUrl": self.url, }) yield "live", stream if 'wansu-' in http_url: hls_url = http_url.replace(".flv", "/playlist.m3u8") else: hls_url = http_url.replace("live-hdl", "live-hls").replace(".flv", ".m3u8") s = [] for s in HLSStream.parse_variant_playlist(self.session, hls_url).items(): yield s if not s: yield "live", HLSStream(self.session, hls_url)
def _get_streams(self): res = self.session.http.get(self.url) match = _playlist_url_re.search(res.text) if match is None: return res = self.session.http.get(match.group(1) + RUURL) sources = self.session.http.json(res, schema=_playlist_schema) streams = {} for source in sources: if source["type"] == "rtmp": streams["rtmp_live"] = RTMPStream(self.session, { "rtmp": source["streamer"], "pageUrl": self.url, "live": True }) elif source["type"] == "hls": streams.update( HLSStream.parse_variant_playlist(self.session, source["file"])) return streams
def _get_streams(self): """ Find the streams for web.tv :return: """ headers = {} res = http.get(self.url, headers=headers) headers["Referer"] = self.url sources = self._sources_re.findall(res.text) if len(sources): sdata = parse_json(sources[0], schema=self._sources_schema) for source in sdata: self.logger.debug("Found stream of type: {}", source[u'type']) if source[u'type'] == u"application/vnd.apple.mpegurl": # if the url has no protocol, assume it is http url = source[u"src"] if url.startswith("//"): url = "http:" + url try: # try to parse the stream as a variant playlist variant = HLSStream.parse_variant_playlist( self.session, url, headers=headers) if variant: for q, s in variant.items(): yield q, s else: # and if that fails, try it as a plain HLS stream yield 'live', HLSStream(self.session, url, headers=headers) except IOError: self.logger.warning( "Could not open the stream, perhaps the channel is offline" )
def _get_streams(self): vinit_req = self.session.http.get(self._video_init_url, params=dict(videoSeq=self.video_id), headers=dict(referer=self.url)) if vinit_req.status_code != 200: raise PluginError( 'Could not get video init page (HTTP Status {})'.format( vinit_req.status_code)) video_status_js = self._video_status.search(vinit_req.text) if not video_status_js: raise PluginError('Could not find video status information!') video_status = json.loads(video_status_js.group(1)) if video_status['viewType'] == 'vod': raise PluginError('VODs are not supported') if 'liveStreamInfo' not in video_status: raise PluginError('Stream is offline') stream_info = json.loads(video_status['liveStreamInfo']) streams = dict() # All "resolutions" have a variant playlist with only one entry, so just combine them for i in stream_info['resolutions']: res_streams = HLSStream.parse_variant_playlist( self.session, i['cdnUrl']) if len(res_streams.values()) > 1: log.warning( 'More than one stream in variant playlist, using first entry!' ) streams[i['name']] = res_streams.popitem()[1] return streams
def _get_streams(self): if "eltrecetv.com.ar/vivo" in self.url.lower(): try: self.session.http.headers = { 'Referer': self.url, 'User-Agent': useragents.ANDROID } res = self.session.http.get( 'https://api.iamat.com/metadata/atcodes/eltrece') yt_id = parse_json( res.text )["atcodes"][0]["context"]["ahora"]["vivo"]["youtubeVideo"] yt_url = "https://www.youtube.com/watch?v={0}".format(yt_id) return self.session.streams(yt_url) except BaseException: log.info( "Live content is temporarily unavailable. Please try again later." ) else: try: self.session.http.headers = { 'Referer': self.url, 'User-Agent': useragents.CHROME } res = self.session.http.get(self.url) _player_re = re.compile(r'''data-kaltura="([^"]+)"''') match = _player_re.search(res.text) if not match: return entry_id = parse_json(match.group(1).replace(""", '"'))["entryId"] hls_url = "https://vodgc.com/p/111/sp/11100/playManifest/entryId/" \ "{0}/format/applehttp/protocol/https/a.m3u8".format(entry_id) return HLSStream.parse_variant_playlist(self.session, hls_url) except BaseException: log.error("The requested VOD content is unavailable.")
def _get_streams(self): headers = {'User-Agent': CHROME} res = self.session.http.get(self.url, headers=headers) if 'page/live' in self.url: stream = ''.join([ 'https:', [i for i in list(itertags(res.text, 'source')) ][0].attributes['src'] ]) live = True else: stream = [(i.attributes['type'], ''.join(['https:', i.attributes['src']])) for i in list(itertags(res.text, 'source'))[:-1]] live = False headers.update({"Referer": self.url}) try: parse_hls = bool(strtobool(self.get_option('parse_hls'))) except AttributeError: parse_hls = True if live: if parse_hls: yield HLSStream.parse_variant_playlist(self.session, stream, headers=headers) else: yield dict( live=HTTPStream(self.session, stream, headers=headers)) else: for q, s in stream: yield q, HTTPStream(self.session, s, headers=headers)
def _get_streams(self): res = self.session.http.get(self.url) m = self._stream_data_re.search(res.text) if m: data = parse_json(m.group(1)) if data['LivestreamEnabled'] == '1': account_id = data['LivestreamArgs']['account_id'] event_id = data['LivestreamArgs']['event_id'] log.debug("Found account_id={0} and event_id={1}".format( account_id, event_id)) url = self.API_URL.format(account_id=account_id, event_id=event_id) api_res = self.session.http.get(url) api_data = self.session.http.json(api_res) stream_url = api_data.get('secure_m3u8_url') or api_data.get( 'm3u8_url') if stream_url: return HLSStream.parse_variant_playlist( self.session, stream_url) else: log.error("Could not find m3u8_url") else: log.error("Stream is offline")
def _get_streams(self): streams = [] content_id = self._get_content_id() if content_id: log.debug(f"Found content with id: {content_id}") stream_data = self.zclient.get_cdn_list(content_id, schema=self.cdn_schema) quality_map = None for stream in stream_data: for url in stream["urls"]: if ".m3u8" in url: try: streams.extend(HLSStream.parse_variant_playlist(self.session, url).items()) except (IOError, OSError) as err: log.error(str(err)) elif ((url.endswith("mp4") or url.endswith("mov") or url.endswith("avi")) and self.session.http.head(url, raise_for_status=False).status_code == 200): if quality_map is None: # only make the request when it is necessary quality_map = self._get_quality_map(content_id) # rename the HTTP sources to match the HLS sources quality = quality_map.get(stream["quality"], stream["quality"]) streams.append((quality, HTTPStream(self.session, url))) subtitles = None if self.get_option("mux_subtitles"): subtitles = self._get_subtitles(content_id) if subtitles: substreams = {} for i, subtitle in enumerate(subtitles): substreams[subtitle["lang"]] = HTTPStream(self.session, subtitle["src"]) for q, s in streams: yield q, MuxedStream(self.session, s, subtitles=substreams) else: for s in streams: yield s
def _resolve_stream(self): res = http.get(self.url) match = _data_stream_re.search(res.text) if not match: return data_stream = match.group(1) resolve_data = { 'stream': data_stream } res = http.post( 'http://www-ipv4.nos.nl/livestream/resolve/', data=json.dumps(resolve_data) ) data = http.json(res) res = http.get(data['url']) match = _js_re.search(res.text) if not match: return stream_url = parse_json(match.group(1)) return HLSStream.parse_variant_playlist(self.session, stream_url)
def _get_streams(self): self.session.http.headers.update({"Referer": self.url}) iframe_url = None res = self.session.http.get(self.url) for iframe in itertags(res.text, "iframe"): if "embed.lsm.lv" in iframe.attributes.get("src"): iframe_url = iframe.attributes.get("src") break if not iframe_url: log.error("Could not find player iframe") return log.debug("Found iframe: {0}".format(iframe_url)) res = self.session.http.get(iframe_url) for source in itertags(res.text, "source"): if source.attributes.get("src"): stream_url = source.attributes.get("src") url_path = urlparse(stream_url).path if url_path.endswith(".m3u8"): yield from HLSStream.parse_variant_playlist(self.session, stream_url).items() else: log.debug("Not used URL path: {0}".format(url_path))
def _get_streams(self): headers = {'User-Agent': CHROME} self.url = self.url.replace(u'ρικ', quote(u'ρικ'.encode('utf-8'))) get_page = self.session.http.get(self.url, headers=headers) tags = list(itertags(get_page.text, 'script')) if 'live-tv' in self.url: tag = [i for i in tags if 'm3u8' in i.text][0].text try: stream = re.search(r'''["'](http.+?\.m3u8)['"]''', tag).group(1) except IndexError: raise NoStreamsError('RIK Broadcast is currently disabled') else: tag = [i for i in tags if '.mp4' in i.text and 'sources' in i.text][0].text stream = re.search(r'''file: ['"](.+?\.mp4)['"]''', tag).group(1) headers.update({"Referer": self.url}) try: parse_hls = bool(strtobool(self.get_option('parse_hls'))) except AttributeError: parse_hls = True if parse_hls and 'live-tv' in self.url: return HLSStream.parse_variant_playlist(self.session, stream, headers=headers) else: return dict(stream=HTTPStream(self.session, stream, headers=headers))
def _get_streams(self): self.session.http.headers.update({"User-Agent": useragents.CHROME}) if '/news/videos/' in self.url: # VOD streams = self._get_vod_streams() or [] else: # Live streams = self._get_live_streams() or [] for video_url in streams: log.debug("Found stream: {0}".format(video_url)) if '.f4m' in video_url: yield from HDSStream.parse_manifest(self.session, video_url).items() elif '.m3u8' in video_url: yield from HLSStream.parse_variant_playlist( self.session, video_url).items() if '.mp4' in video_url: match = self._mp4_bitrate_re.match(video_url) if match is not None: bitrate = match.group('bitrate') + 'k' else: bitrate = 'vod' yield bitrate, HTTPStream(self.session, video_url)
def _get_streams(self): # Construct manifest URL for this program. program_type, program_id = self._url_re.match(self.url).groups() manifest_type = self._program_type_map.get(program_type) if manifest_type is None: log.error("Unknown program type '{0}'".format(program_type)) return None # Fetch program_id. res = self.session.http.get(self.url) m = self._program_id_re.search(res.text) if m is not None: program_id = m.group(1) elif program_id is None: log.error("Could not extract program ID from URL") return None manifest_url = urljoin( self._psapi_url, "playback/manifest/{0}/{1}".format(manifest_type, program_id)) # Extract media URL. res = self.session.http.get(manifest_url) manifest = self.session.http.json(res, schema=self._playable_schema) if 'nonPlayable' in manifest: reason = manifest["nonPlayable"]["reason"] log.error("Not playable ({0})".format(reason)) return None self._set_metadata(manifest) asset = manifest['playable']['assets'][0] # Some streams such as podcasts are not HLS but plain files. if asset['format'] == 'HLS': return HLSStream.parse_variant_playlist(self.session, asset['url']) else: return [("live", HTTPStream(self.session, asset['url']))]
def _get_streams(self): # Retrieve geolocation data res = self.session.http.get(self.GEO_URL) geo = self.session.http.json(res, schema=self._geo_schema) country_code = geo['reponse']['geo_info']['country_code'] log.debug('Country: {0}'.format(country_code)) # Retrieve URL page and search for video ID res = self.session.http.get(self.url) if 'france.tv' in self.url: match = self._pluzz_video_id_re.search(res.text) elif 'ludo.fr' in self.url or 'zouzous.fr' in self.url: match = self._jeunesse_video_id_re.search(res.text) elif 'sport.francetvinfo.fr' in self.url: match = self._sport_video_id_re.search(res.text) else: match = self._embed_video_id_re.search(res.text) if match is None: return video_id = match.group('video_id') log.debug('Video ID: {0}'.format(video_id)) res = self.session.http.get(self.API_URL.format(video_id)) videos = self.session.http.json(res, schema=self._api_schema) now = time.time() offline = False geolocked = False drm = False expired = False streams = [] for video in videos['videos']: log.trace('{0!r}'.format(video)) video_url = video['url'] # Check whether video format is available if video['statut'] != 'ONLINE': offline = offline or True continue # Check whether video format is geo-locked if video['geoblocage'] is not None and country_code not in video[ 'geoblocage']: geolocked = geolocked or True continue # Check whether video is DRM-protected if video['drm']: drm = drm or True continue # Check whether video format is expired available = False for interval in video['plages_ouverture']: available = (interval['debut'] or 0) <= now <= (interval['fin'] or sys.maxsize) if available: break if not available: expired = expired or True continue res = self.session.http.get(self.TOKEN_URL.format(video_url)) video_url = res.text if '.mpd' in video_url: # Get redirect video URL res = self.session.http.get(res.text) video_url = res.url for bitrate, stream in DASHStream.parse_manifest( self.session, video_url).items(): streams.append((bitrate, stream)) elif '.f4m' in video_url: for bitrate, stream in HDSStream.parse_manifest( self.session, video_url, is_akamai=True, pvswf=self.SWF_PLAYER_URL).items(): # HDS videos with data in their manifest fragment token # doesn't seem to be supported by HDSStream. Ignore such # stream (but HDS stream having only the hdntl parameter in # their manifest token will be provided) pvtoken = stream.request_params['params'].get( 'pvtoken', '') match = self._hds_pv_data_re.search(pvtoken) if match is None: streams.append((bitrate, stream)) elif '.m3u8' in video_url: for stream in HLSStream.parse_variant_playlist( self.session, video_url).items(): streams.append(stream) # HBB TV streams are not provided anymore by France Televisions elif '.mp4' in video_url and '/hbbtv/' not in video_url: match = self._mp4_bitrate_re.match(video_url) if match is not None: bitrate = match.group('bitrate') else: # Fallback bitrate (seems all France Televisions MP4 videos # seem have such bitrate) bitrate = '1500k' streams.append((bitrate, HTTPStream(self.session, video_url))) if self.get_option("mux_subtitles") and videos['subtitles'] != []: substreams = {} for subtitle in videos['subtitles']: # TTML subtitles are available but not supported by FFmpeg if subtitle['format'] == 'ttml': continue substreams[subtitle['type']] = HTTPStream( self.session, subtitle['url']) for quality, stream in streams: yield quality, MuxedStream(self.session, stream, subtitles=substreams) else: for stream in streams: yield stream if offline: log.error('Failed to access stream, may be due to offline content') if geolocked: log.error( 'Failed to access stream, may be due to geo-restricted content' ) if drm: log.error( 'Failed to access stream, may be due to DRM-protected content') if expired: log.error('Failed to access stream, may be due to expired content')
def _watch(self): log.debug('_watch ...') match = self._url_re.match(self.url) if not match: log.debug('_watch ... no match') return channel = match.group('channel') vod_id = match.group('vod_id') recording_id = match.group('recording_id') params = {'https_watch_urls': True} if channel: watch_url = self.API_WATCH.format(self.base_url) params_cid = self._get_params_cid(channel) if not params_cid: return params.update(params_cid) elif vod_id: log.debug('Found vod_id: {0}'.format(vod_id)) watch_url = self.API_WATCH_VOD.format(self.base_url, vod_id) elif recording_id: log.debug('Found recording_id: {0}'.format(recording_id)) watch_url = self.API_WATCH_REC.format(self.base_url, recording_id) else: log.debug('Missing watch_url') return zattoo_stream_types = self.get_option('stream-types') or ['hls'] for stream_type in zattoo_stream_types: params_stream_type = {'stream_type': stream_type} params.update(params_stream_type) try: res = self.session.http.post(watch_url, headers=self.headers, data=params) except Exception as e: if '404 Client Error' in str(e): log.error('Unfortunately streaming is not permitted in ' 'this country or this channel does not exist.') elif '402 Client Error: Payment Required' in str(e): log.error('Paid subscription required for this channel.') log.info('If paid subscription exist, use --zattoo-purge' '-credentials to start a new session.') elif '403 Client Error' in str(e): log.debug('Force session reset for watch_url') self.reset_session() else: log.error(str(e)) return data = self.session.http.json(res) log.debug('Found data for {0}'.format(stream_type)) if data['success'] and stream_type in ['hls', 'hls5']: for url in data['stream']['watch_urls']: for s in HLSStream.parse_variant_playlist( self.session, url['url']).items(): yield s elif data['success'] and stream_type == 'dash': for url in data['stream']['watch_urls']: for s in DASHStream.parse_manifest(self.session, url['url']).items(): yield s
def hls_stream(self, hls_url): log.debug("URL={0}".format(hls_url)) for s in HLSStream.parse_variant_playlist(self.session, hls_url).items(): yield s
def _get_streams(self): self.session.http.headers = {"User-Agent": useragents.CHROME} res = self.session.http.get(self.url) # remap en to english, and ja to japanese rlanguage = { "en": "english", "ja": "japanese" }.get( self.get_option("language").lower(), self.get_option("language").lower()) if "_Incapsula_Resource" in res.text: self.bypass_incapsula(res) res = self.session.http.get(self.url) id_m = self.experience_id_re.search(res.text) experience_id = id_m and int(id_m.group(1)) if experience_id: log.debug("Found experience ID: {0}", experience_id) exp = Experience(experience_id) if self.get_option("email") and self.get_option("password"): if exp.login(self.get_option("email"), self.get_option("password")): log.info("Logged in to Funimation as {0}", self.get_option("email")) else: log.warning("Failed to login") log.debug("Found episode: {0}", exp.episode_info["episodeTitle"]) log.debug(" has languages: {0}", ", ".join(exp.episode_info["languages"].keys())) log.debug(" requested language: {0}", rlanguage) log.debug(" current language: {0}", exp.language) if rlanguage != exp.language: log.debug("switching language to: {0}", rlanguage) exp.set_language(rlanguage) if exp.language != rlanguage: log.warning( "Requested language {0} is not available, continuing with {1}", rlanguage, exp.language) else: log.debug("New experience ID: {0}", exp.experience_id) subtitles = None stream_metadata = {} disposition = {} for subtitle in exp.subtitles(): log.debug("Subtitles: {0}", subtitle["src"]) if subtitle["src"].endswith( ".vtt") or subtitle["src"].endswith(".srt"): sub_lang = {"en": "eng", "ja": "jpn"}[subtitle["language"]] # pick the first suitable subtitle stream subtitles = subtitles or HTTPStream( self.session, subtitle["src"]) stream_metadata["s:s:0"] = [ "language={0}".format(sub_lang) ] stream_metadata["s:a:0"] = [ "language={0}".format(exp.language_code) ] sources = exp.sources() if 'errors' in sources: for error in sources['errors']: log.error("{0} : {1}".format(error['title'], error['detail'])) return for item in sources["items"]: url = item["src"] if ".m3u8" in url: for q, s in HLSStream.parse_variant_playlist( self.session, url).items(): if self.get_option("mux_subtitles") and subtitles: yield q, MuxedStream(self.session, s, subtitles, metadata=stream_metadata, disposition=disposition) else: yield q, s elif ".mp4" in url: # TODO: fix quality s = HTTPStream(self.session, url) if self.get_option("mux_subtitles") and subtitles: yield self.mp4_quality, MuxedStream( self.session, s, subtitles, metadata=stream_metadata, disposition=disposition) else: yield self.mp4_quality, s else: log.error("Could not find experience ID?!")
def _get_streams(self): res = self.session.http.get(self.API_URL) data = self.session.http.json(res, schema=self._player_schema) log.debug('{0!r}'.format(data)) return HLSStream.parse_variant_playlist(self.session, data['hlsmanifest'])