def _get_streams(self): streams = {} # streaming.media.ccc.de match = _url_streaming_media_re.match(self.url) if match: query_url = API_URL_STREAMING_MEDIA live_streams = parse_streaming_media_json(get_json(query_url), match.group('room')) for stream_name, stream_url in live_streams.items(): if re.search(r"m3u8", live_streams[stream_name]): streams[stream_name] = HLSStream(self.session, stream_url) else: streams[stream_name] = HTTPStream(self.session, stream_url) # media.ccc.de elif _url_media_re.search(self.url): event_id = get_event_id(self.url) query_url = "%s/public/events/%i" % (API_URL_MEDIA, event_id) recordings = parse_media_json(get_json(query_url)) for name, stream_url in recordings.items(): streams[name] = HTTPStream(self.session, stream_url) if not streams: raise PluginError("This plugin does not support your " "selected video.") return streams
def _get_streams(self): http.headers = {"User-Agent": useragents.CHROME} res = http.get(self.url) rlanguage = self.get_option("language") id_m = self.experience_id_re.search(res.text) experience_id = id_m and int(id_m.group(1)) if experience_id: self.logger.debug("Found experience ID: {0}", experience_id) exp = Experience(experience_id) self.logger.debug("Found episode: {0}", exp.episode_info["episodeTitle"]) self.logger.debug(" has languages: {0}", ", ".join(exp.episode_info["languages"].keys())) self.logger.debug(" requested language: {0}", rlanguage) self.logger.debug(" current language: {0}", exp.language) if rlanguage != exp.language: self.logger.debug("switching language to: {0}", rlanguage) exp.set_language(rlanguage) if exp.language != rlanguage: self.logger.warning("Requested language {0} is not available, continuing with {1}", rlanguage, exp.language) else: self.logger.debug("New experience ID: {0}", exp.experience_id) subtitles = None stream_metadata = {} disposition = {} for subtitle in exp.subtitles(): self.logger.info("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)] for item in exp.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: self.logger.error("Could not find experience ID?!")
def _get_streams(self): if "empty" in self.url: return if "NoStreamsError" in self.url: raise NoStreamsError(self.url) streams = {} streams["test"] = TestStream(self.session) streams["rtmp"] = RTMPStream(self.session, dict(rtmp="rtmp://test.se")) streams["hls"] = HLSStream(self.session, "http://test.se/playlist.m3u8") streams["http"] = HTTPStream(self.session, "http://test.se/stream") streams["akamaihd"] = AkamaiHDStream(self.session, "http://test.se/stream") streams["240p"] = HTTPStream(self.session, "http://test.se/stream") streams["360p"] = HTTPStream(self.session, "http://test.se/stream") streams["1080p"] = HTTPStream(self.session, "http://test.se/stream") streams["350k"] = HTTPStream(self.session, "http://test.se/stream") streams["800k"] = HTTPStream(self.session, "http://test.se/stream") streams["1500k"] = HTTPStream(self.session, "http://test.se/stream") streams["3000k"] = HTTPStream(self.session, "http://test.se/stream") streams["480p"] = [ HTTPStream(self.session, "http://test.se/stream"), RTMPStream(self.session, dict(rtmp="rtmp://test.se")) ] streams.update(testplugin_support.get_streams(self.session)) return streams
def _get_streams(self): """ Find the streams for vk.com :return: """ # If this is a 'videos' catalog URL with an video ID in the GET request, get that instead url = self.follow_vk_redirect(self.url) if url != self.url: self.logger.debug('Grabbing data from real video page at {}', url) headers = {} res = http.get(url, headers=headers) headers["Referer"] = url # Try and find an HLS source (livestream) stream_urls = self._livestream_sources_re.findall(res.text) if len(stream_urls): stream_url = stream_urls[0].replace('\/', '/') self.logger.debug("Found live stream at {}", stream_url) try: # try to parse the stream as a variant playlist variant = HLSStream.parse_variant_playlist(self.session, stream_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, stream_url, headers=headers) except IOError: self.logger.warning("Could not open the stream, perhaps the channel is offline") return # Try and find a set of MP4 sources (VOD) vod_urls = self._vod_sources_re.findall(res.text) if len(vod_urls): vod_urls = [v.replace('\/', '/') for v in vod_urls] # Try to get quality from URL qualities = {} for s in vod_urls: q = self._vod_quality_re.findall(s) if not len(q): break qualities[s] = q[0] try: if len(qualities) == len(vod_urls): for s in vod_urls: yield qualities[s] + 'p', HTTPStream(self.session, s) else: # Fall back to numerical ranking for q, s in enumerate(vod_urls): yield str(q), HTTPStream(self.session, s) except IOError: self.logger.warning("Could not open the stream, perhaps the channel is offline")
def _create_playlist_streams(self, videos): start_offset = int(videos.get("start_offset", 0)) stop_offset = int(videos.get("end_offset", 0)) streams = {} for quality, chunks in videos.get("chunks").items(): if not chunks: if videos.get("restrictions", {}).get(quality) == "chansub": self.logger.warning( "The quality '{0}' is not available " "since it requires a subscription.", quality) continue # Rename 'live' to 'source' if quality == "live": quality = "source" chunks_filtered = list(filter(lambda c: c["url"], chunks)) if len(chunks) != len(chunks_filtered): self.logger.warning( "The video '{0}' contains invalid chunks. " "There will be missing data.", quality) chunks = chunks_filtered chunks_duration = sum(c.get("length") for c in chunks) # If it's a full broadcast we just use all the chunks if start_offset == 0 and chunks_duration == stop_offset: # No need to use the FLV concat if it's just one chunk if len(chunks) == 1: url = chunks[0].get("url") stream = HTTPStream(self.session, url) else: chunks = [ HTTPStream(self.session, c.get("url")) for c in chunks ] stream = FLVPlaylist(self.session, chunks, duration=chunks_duration) else: try: stream = self._create_video_clip(chunks, start_offset, stop_offset) except StreamError as err: self.logger.error("Error while creating video '{0}': {1}", quality, err) continue streams[quality] = stream return streams
def _get_streams(self): email, password = self.get_option("email"), self.get_option("password") if not email or not password: self.logger.error( "AnimeLab requires authentication, use --animelab-email " "and --animelab-password to set your email/password combination" ) return if self.login(email, password): self.logger.info("Successfully logged in as {0}", email) video_collection = http.get(self.url, schema=self.video_collection_schema) if video_collection["playlist"] is None or video_collection[ "position"] is None: return data = video_collection["playlist"][video_collection["position"]] self.logger.debug("Found {0} version {1} hard-subs", data["language"]["name"], "with" if data["hardSubbed"] else "without") for video in data["videoInstances"]: if video["httpUrl"]: q = video["videoQuality"]["description"] s = HTTPStream(self.session, video["httpUrl"]) yield q, s
def get_streams(self, video_id): self.logger.debug("Finding streams for video: {0}", video_id) policy_key = self.policy_key(video_id) self.logger.debug("Found policy key: {0}", policy_key) data = self.video_info(video_id, policy_key) for source in data.get("sources"): # determine quality name if source.get("height"): q = "{0}p".format(source.get("height")) elif source.get("avg_bitrate"): q = "{0}k".format(source.get("avg_bitrate") // 1000) else: q = "live" if ((source.get("type") == "application/x-mpegURL" and source.get("src")) or (source.get("src") and ".m3u8" in source.get("src"))): for s in HLSStream.parse_variant_playlist( self.session, source.get("src")).items(): yield s elif source.get("app_name"): s = RTMPStream( self.session, { "rtmp": source.get("app_name"), "playpath": source.get("stream_name") }) yield q, s elif source.get("src") and source.get("src").endswith(".mp4"): yield q, HTTPStream(self.session, source.get("src"))
def _get_streams(self): asset_id = self._get_prid(self.get_option("subtitles")) if asset_id: self.logger.debug("Found asset id: {0}", asset_id) streams = self.api_call(asset_id, params=dict(adaptive="yes", token=self.token), schema=self.streams_schema) for stream in streams: if stream["format"] in ("adaptive", "hls", "mp4"): if stream["contentType"] == "url": stream_url = stream["url"] else: # using type=json removes the javascript function wrapper info_url = stream["url"].replace( "type=jsonp", "type=json") # find the actual stream URL stream_url = http.json(http.get(info_url), schema=self.stream_info_schema) if stream["format"] in ("adaptive", "hls"): for s in HLSStream.parse_variant_playlist( self.session, stream_url).items(): yield s elif stream["format"] in ("mp3", "mp4"): yield "vod", HTTPStream(self.session, stream_url)
def _get_streams(self): match = _url_re.match(self.url) channel = match.group("channel") http.headers.update({'User-Agent': useragents.CHROME}) payload = '{"liveStreamID": "%s"}' % (channel) res = 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 handle_module_info(self, args, media_id, application, cluster="live", referrer=None, retries=3): has_results = False for streams in UHSClient.module_info_schema.validate(args): has_results = True if isinstance(streams, list): for stream in streams: for q, s in HLSStream.parse_variant_playlist( self.session, stream["url"]).items(): yield q, UStreamHLSStream(self.session, s.url, self.api) elif isinstance(streams, dict): for stream in streams.get("streams", []): name = "{0}k".format(stream["bitrate"]) for surl in stream["streamName"]: yield name, HTTPStream(self.session, surl) elif streams == "offline": self.logger.warning("This stream is currently offline") if not has_results: raise ModuleInfoNoStreams
def _get_streams(self): headers = {"User-Agent": useragents.FIREFOX, "Referer": self.url} data = http.get(self.url, headers=headers, schema=self._data_schema) metadata = data.get("metadata") metadata_url = data.get("metadataUrl") if metadata_url: metadata = http.post(metadata_url, headers=headers, schema=self._metadata_schema) if metadata: list_hls = [ metadata.get("hlsManifestUrl"), metadata.get("hlsMasterPlaylistUrl"), ] for hls_url in list_hls: if hls_url is not None: for s in HLSStream.parse_variant_playlist( self.session, hls_url, headers=headers).items(): yield s if metadata.get("videos"): for http_stream in metadata.get("videos"): http_name = http_stream["name"] http_url = http_stream["url"] yield http_name, HTTPStream(self.session, http_url, headers=headers) if metadata.get("rtmpUrl"): yield "live", RTMPStream( self.session, params={"rtmp": metadata.get("rtmpUrl")})
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): headers = {"User-Agent": useragents.FIREFOX, "Referer": self.url} res = http.get(self.url, headers=headers) files = self._files_re.findall(res.text) if files is None: return files = list(set(files)) for url in files: if ".m3u8" in url: if url.startswith("https://weltmediathek-vh."): url = "https://www.welt.de/video/services/token/{0}".format( quote(url, safe="")) res = http.get(url, headers=headers) r_json = http.json(res) url = r_json["urlWithToken"] for s in HLSStream.parse_variant_playlist( self.session, url, headers=headers).items(): yield s elif url.endswith(".mp4"): m = self._mp4_bitrate_re.search(url) bitrate = m.group("bitrate") if bitrate: name = "{0}k".format(bitrate) else: name = "mp4" yield name, HTTPStream(self.session, url, headers=headers)
def _get_show_streams(self, stream_data, show, episode, platform="desktop"): video_id = parse_json(stream_data.group(1), schema=self.vod_id_schema) res = http.get(self.vod_api, params={ "platform": platform, "id": video_id }) # create a unique list of the stream manifest URLs streams = [] urldups = [] for stream in parse_xml(res.text, schema=self._vod_api_schema): if stream["url"] not in urldups: streams.append(stream) urldups.append(stream["url"]) mapper = StreamMapper(lambda fmt, strm: strm["url"].endswith(fmt)) mapper.map(".m3u8", self._make_hls_hds_stream, HLSStream.parse_variant_playlist) mapper.map(".f4m", self._make_hls_hds_stream, HDSStream.parse_manifest, is_akamai=True) mapper.map( ".mp4", lambda s: (s["bitrate"] + "k", HTTPStream(self.session, s["url"]))) for q, s in mapper(streams): yield q, s
def _get_streams(self): # Get video ID and channel from URL match = self._url_re.match(self.url) video_id = match.group('video_id') if video_id is None: # Retrieve URL page and search for video ID res = http.get(self.url) match = self._video_id_re.search(res.text) if match is None: return video_id = match.group('video_id') res = http.get(self.API_URL.format(video_id)) videos = http.json(res, schema=self._api_schema) parsed = [] headers = {'User-Agent': self._user_agent} # Some videos may be also available on Dailymotion (especially on CNews) if videos['ID_DM'] != '': for stream in self.session.streams('https://www.dailymotion.com/video/' + videos['ID_DM']).items(): yield stream for quality, video_url in list(videos['MEDIA']['VIDEOS'].items()): # Ignore empty URLs if video_url == '': continue # Ignore duplicate video URLs if video_url in parsed: continue parsed.append(video_url) try: # HDS streams don't seem to work for live videos if '.f4m' in video_url and 'LIVE' not in videos['TYPE']: for stream in HDSStream.parse_manifest(self.session, video_url, params={'hdcore': self.HDCORE_VERSION}, headers=headers).items(): yield stream elif '.m3u8' in video_url: for stream in HLSStream.parse_variant_playlist(self.session, video_url, headers=headers).items(): yield stream elif '.mp4' in video_url: # Get bitrate from video filename match = self._mp4_bitrate_re.match(video_url) if match is not None: bitrate = match.group('bitrate') else: bitrate = quality yield bitrate, HTTPStream(self.session, video_url, params={'secret': self.SECRET}, headers=headers) except IOError as err: if '403 Client Error' in str(err): self.logger.error('Failed to access stream, may be due to geo-restriction')
def _resolve_playlist(self, res, playlist_all): """ yield for _resolve_res Args: res: Content from self._res_text playlist_all: List of streams Returns: yield every stream """ # m_base is used for .f4m files that doesn't have a base_url m_base = self._stream_base_re.search(res) if m_base: stream_base = m_base.group("base") else: stream_base = "" playlist_list = self._make_url_list(playlist_all, self.url, stream_base) self.logger.debug("Found URL: {0}".format(", ".join(playlist_list))) endswith_blacklist = (".mp3", ".mp4", ".vtt") for url in playlist_list: if ".m3u8" in url and not url.endswith(endswith_blacklist): try: streams = HLSStream.parse_variant_playlist( self.session, url, headers=self.headers).items() if not streams: yield "live", HLSStream(self.session, url, headers=self.headers) for s in streams: yield s except Exception: self.logger.error("Skipping hls_url: {0}".format(url)) elif ".f4m" in url and not url.endswith(endswith_blacklist): try: for s in HDSStream.parse_manifest( self.session, url, headers=self.headers).items(): yield s except Exception: self.logger.error("Skipping hds_url: {0}".format(url)) elif self.list_in_item(url, [ ".mp3", ".mp4" ]) and not self.list_in_item(url, [".f4m", ".m3u8", ".mpd"]): try: name = "live" m = self._httpstream_bitrate_re.search(url) if m: name = "{0}k".format(m.group("bitrate")) yield name, HTTPStream(self.session, url, headers=self.headers) except Exception: self.logger.error("Skipping http_url: {0}".format(url)) elif ".mpd" in url and not url.endswith(endswith_blacklist): try: self.logger.info("Found mpd: {0}".format(url)) except Exception: self.logger.error("Skipping mpd_url: {0}".format(url))
def _get_streams(self): data = http.get(self.url, schema=self.config_schema) for info in data["files"].values(): stream_url = update_scheme(self.url, info["url"]) # pick the smaller of the two dimensions, for landscape v. portrait videos res = min(info["width"], info["height"]) yield "{0}p".format(res), HTTPStream(self.session, stream_url)
def _get_qq_streams(self, vid): res = http.get(QQ_STREAM_INFO_URL % (vid, 1)) info = http.json(res, schema=_qq_schema) yield "live", HTTPStream(self.session, info) res = http.get(QQ_STREAM_INFO_URL % (vid, 2)) info = http.json(res, schema=_qq_schema) yield "live", HLSStream(self.session, info)
def _create_adaptive_streams(self, info, streams, protected): adaptive_streams = {} best_audio_itag = None # Extract audio streams from the DASH format list for stream_info in info.get("adaptive_fmts", []): if stream_info.get("s"): protected = True continue stream_params = dict(parse_qsl(stream_info["url"])) if "itag" not in stream_params: continue itag = int(stream_params["itag"]) # extract any high quality streams only available in adaptive formats adaptive_streams[itag] = stream_info["url"] stream_type, stream_format = stream_info["type"] if stream_type == "audio": stream = HTTPStream(self.session, stream_info["url"]) name = "audio_{0}".format(stream_format) streams[name] = stream # find the best quality audio stream m4a, opus or vorbis if best_audio_itag is None or self.adp_audio[ itag] > self.adp_audio[best_audio_itag]: best_audio_itag = itag if best_audio_itag and adaptive_streams and MuxedStream.is_usable( self.session): aurl = adaptive_streams[best_audio_itag] for itag, name in self.adp_video.items(): if itag in adaptive_streams: vurl = adaptive_streams[itag] self.logger.debug( "MuxedStream: v {video} a {audio} = {name}".format( audio=best_audio_itag, name=name, video=itag, )) streams[name] = MuxedStream(self.session, HTTPStream(self.session, vurl), HTTPStream(self.session, aurl)) return streams, protected
def _get_streams(self): streams = [] content_id = self._get_content_id() if content_id: self.logger.debug("Found content with id: {0}", 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 url.endswith("m3u8"): try: streams.extend( HLSStream.parse_variant_playlist( self.session, url).items()) except (IOError, OSError): self.logger.debug("Failed to load m3u8 url: {0}", url) elif ((url.endswith("mp4") or url.endswith("mov") or url.endswith("avi")) and 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 _get_clips(self): quality_options = self.api.clip_status(self.channel, self.clip_name, schema=_quality_options_schema) streams = {} for quality_option in quality_options: streams[quality_option["quality"]] = HTTPStream( self.session, quality_option["source"]) return streams
def _get_video_stream(self, video_id): url = self.video_api.format(id=video_id) self.logger.debug("Video API call: {0}", url) data = http.get(url, schema=self.video_schema) self.logger.debug("Got video {0} playback items", len(data["playback"])) res = data["resolution"]["height"] for playback in data["playback"]: yield "{0}p".format(res), HTTPStream(self.session, playback["uri"])
def _get_http_streams(self, info): name = QUALITY_MAP.get(info["_quality"], "vod") urls = info["_stream"] if not isinstance(info["_stream"], list): urls = [urls] for url in urls: stream = HTTPStream(self.session, url) yield name, stream
def _get_vod_stream(self): """ Find the VOD video url :return: video url """ res = http.get(self.url) video_urls = self._re_vod.findall(res.text) if len(video_urls): return dict(vod=HTTPStream(self.session, video_urls[0]))
def _get_plu_streams(self, cid): res = http.get(PLU_STREAM_INFO_URL % cid) info = http.json(res, schema=_plu_schema) for source in info["playLines"][0]["urls"]: quality = self._get_quality(source["resolution"]) if source["ext"] == "m3u8": yield quality, HLSStream(self.session, source["securityUrl"]) elif source["ext"] == "flv": yield quality, HTTPStream(self.session, source["securityUrl"])
def _get_streams(self): is_live = False info = self._get_stream_info(self.url) if not info: return if info.get("livestream") == '1' or info.get("live_playback") == '1': self.logger.debug("This video is live.") is_live = True formats = info.get("fmt_list") streams = {} protected = False for stream_info in info.get("url_encoded_fmt_stream_map", []): if stream_info.get("s"): protected = True continue stream = HTTPStream(self.session, stream_info["url"]) name = formats.get(stream_info["itag"]) or stream_info["quality"] if stream_info.get("stereo3d"): name += "_3d" streams[name] = stream if is_live is False: streams, protected = self._create_adaptive_streams( info, streams, protected) hls_playlist = info.get("hlsvp") if hls_playlist: parsed = urlparse(self.url) params = parse_query(parsed.query) time_offset = params.get("t") if time_offset: self.session.set_option("hls-start-offset", time_to_offset(params.get("t"))) try: hls_streams = HLSStream.parse_variant_playlist( self.session, hls_playlist, headers=HLS_HEADERS, namekey="pixels") streams.update(hls_streams) except IOError as err: self.logger.warning("Failed to extract HLS streams: {0}", err) if not streams and protected: raise PluginError("This plugin does not support protected videos, " "try youtube-dl instead") return streams
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 _get_streams(self): room_id = url_re.search(self.url).group("room_id") html = http.get(mobile_url.format(room_id)) stream_id = self.get_stream_id(html.text) stream_info = self.get_stream_info(html.text) streams = {} for info in stream_info: streams[info[2]] = HTTPStream(self.session, info[0] + stream_id + info[1] + ".flv") return streams
def _get_source_streams(self): res = http.get(self.url) streams = {} sources = _source_re.findall(res.text) for source in sources: src = _source_src_re.search(source).group("src") pixels = _source_type_re.search(source).group("type") streams[pixels] = HTTPStream(self.session, src) return streams
def _get_streams(self): match = self._url_re.match(self.url) video_id = match.group('video_id') if video_id is not None: # VOD live = False player_url = self.VOD_PLAYER_URL.format(video_id) else: # Live live = True player_url = self.LIVE_PLAYER_URL res = http.get(player_url) playlist = re.findall(self._playlist_re, res.text) index = 0 if not live: # Get the index for the video on the playlist match = self._vod_video_index_re.search(res.text) if match is None: return index = int(match.group('video_index')) if not playlist: return videos = self._video_schema.validate(playlist[index]) for video in videos: video_url = video['file'] # Ignore non-supported MSS streams if 'isml/Manifest' in video_url: continue try: if '.m3u8' in video_url: for stream in HLSStream.parse_variant_playlist( self.session, video_url).items(): yield stream elif '.mp4' in video_url: match = self._mp4_bitrate_re.match(video_url) if match is not None: bitrate = '%sk' % match.group('bitrate') else: bitrate = 'vod' yield bitrate, HTTPStream(self.session, video_url) except IOError as err: if '403 Client Error' in str(err): self.logger.error( 'Failed to access stream, may be due to geo-restriction' ) raise