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): match = _url_re.match(self.url) channel_name = match.group("channel") form = { "cid": channel_name, "watchTime": 0, "firstConnect": 1, "ip": "NaN" } res = http.post(API_URL, data=form, headers=HEADERS) params = parse_query(res.text, schema=_schema) if params["status"] <= 0: return if params["block_type"] != 0: if params["block_type"] == BLOCK_TYPE_VIEWING_LIMIT: msg = BLOCKED_MSG_FORMAT.format( params.get("block_time", "UNKNOWN"), params.get("reconnect_time", "UNKNOWN")) raise PluginError(msg) elif params["block_type"] == BLOCK_TYPE_NO_SLOTS: raise PluginError("No free slots available") else: raise PluginError("Blocked for unknown reasons") if "token" not in params: raise PluginError("Server seems busy, retry again later") streams = {} stream_names = ["sd"] if params["multibitrate"]: stream_names += ["hd"] for stream_name in stream_names: playpath = params["playpath"] if stream_name == "hd": playpath += "HI" stream = RTMPStream( self.session, { "rtmp": "{0}/{1}".format(params["rtmp"], playpath), "pageUrl": self.url, "swfVfy": SWF_URL, "weeb": params["token"], "live": True }) streams[stream_name] = stream return streams
def _get_stream_info(self, url): match = _url_re.match(url) user = match.group("user") live_channel = match.group("liveChannel") if user: video_id = self._find_channel_video() elif live_channel: return self._find_canonical_stream_info() else: video_id = match.group("video_id") or match.group("video_id_2") if video_id == "live_stream": query_info = dict(parse_qsl(urlparse(url).query)) if "channel" in query_info: video_id = self._get_channel_video(query_info["channel"]) if not video_id: return # normal _params_1 = {"el": "detailpage"} # age restricted _params_2 = {"el": "embedded"} # embedded restricted _params_3 = { "eurl": "https://youtube.googleapis.com/v/{0}".format(video_id) } count = 0 for _params in (_params_1, _params_2, _params_3): count += 1 params = {"video_id": video_id} params.update(_params) res = http.get(API_VIDEO_INFO, params=params, headers=HLS_HEADERS) info_parsed = parse_query(res.text, name="config", schema=_config_schema) if info_parsed.get("status") == "fail": self.logger.debug("get_video_info - {0}: {1}".format( count, info_parsed.get("reason"))) continue self.stream_title = info_parsed.get("title") self.logger.debug("get_video_info - {0}: Found data".format(count)) break return info_parsed
def __init__(self, url): Plugin.__init__(self, url) self._hosted_chain = [] match = _url_re.match(url).groupdict() parsed = urlparse(url) self.params = parse_query(parsed.query) self.subdomain = match.get("subdomain") self.video_id = None self.video_type = None self._channel_id = None self._channel = None self.clip_name = None if self.subdomain == "player": # pop-out player if self.params.get("video"): try: self.video_type = self.params["video"][0] self.video_id = self.params["video"][1:] except IndexError: self.logger.debug("Invalid video param: {0}", self.params["video"]) self._channel = self.params.get("channel") elif self.subdomain == "clips": # clip share URL self.clip_name = match.get("channel") else: self._channel = match.get("channel") and match.get( "channel").lower() self.video_type = match.get("video_type") if match.get("videos_id"): self.video_type = "v" self.video_id = match.get("video_id") or match.get("videos_id") self.clip_name = match.get("clip_name") self.api = TwitchAPI(beta=self.subdomain == "beta", version=5) self.usher = UsherService()
def parse_stream_map(stream_map): if not stream_map: return [] return [parse_query(s) for s in stream_map.split(",")]
def _get_streams(self): info = self._get_stream_info(self.url) if not info: return 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 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] streams[name] = MuxedStream(self.session, HTTPStream(self.session, vurl), HTTPStream(self.session, aurl)) 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