def _get_stream_info(self): res = http.get(self.url) match = re.search("window.config = ({.+})", res.text) if match: config = match.group(1) return parse_json(config, "config JSON", schema=_stream_config_schema)
def _get_streams(self): res = http.get(self.url) match = (_stream_hls_re.search(res.text) or _stream_data_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 _find_channel_id(self, text): match = self._stream_id_re.search(text) if match: return match.group(1) match = self._site_data_re.search(text) if match: r_json = parse_json(match.group("data")) if r_json: mlg_channel_id = r_json.get("mlg_channel_id") if mlg_channel_id: res = http.get(self.CHANNEL_API.format(mlg_channel_id)) channel_id = http.json(res, schema=self._site_data_schema) return channel_id match = self._player_embed_re.search(text) if match: return match.group("channel_id")
def _get_streams(self): match = self._url_re.match(self.url) if not match: return room_id = match.group("room_id") res = http.get(self.api_url.format(room_id)) data = self._data_re.search(res.text) if not data: return try: hls_url = parse_json(data.group("data"), schema=self._data_schema) except Exception: raise NoStreamsError(self.url) self.logger.debug("URL={0}".format(hls_url)) return {"live": HLSStream(self.session, hls_url)}
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_live_stream(self, export_url): res = http.get(export_url) match = _live_json_re.search(res.text) if not match: return json = parse_json(match.group(1), schema=_live_schema) streams = {} for stream in json["streams"]: stream_name = stream["quality"] parsed = urlparse(stream["url"]) stream = RTMPStream( self.session, { "rtmp": stream["url"], "app": "{0}?{1}".format(parsed.path[1:], parsed.query), "playpath": stream["name"], "swfVfy": SWF_LIVE_URL, "pageUrl": self.url, "live": True }) streams[stream_name] = stream return streams
def _get_hls_streams(self, stream_type="live"): self.logger.debug("Getting {0} HLS streams for {1}".format( stream_type, self.channel)) self._authenticate() self._hosted_chain.append(self.channel) time_offset = self.params.get("t") if time_offset: self.session.set_option("hls-start-offset", time_to_offset(self.params.get("t"))) if stream_type == "live": hosted_channel = self._check_for_host() if hosted_channel and self.options.get("disable_hosting"): self.logger.info("hosting was disabled by command line option") elif hosted_channel: self.logger.info("switching to {0}", hosted_channel) if hosted_channel in self._hosted_chain: self.logger.error( u"A loop of hosted channels has been detected, " "cannot find a playable stream. ({0})".format( u" -> ".join(self._hosted_chain + [hosted_channel]))) return {} self.channel = hosted_channel return self._get_hls_streams(stream_type) # only get the token once the channel has been resolved sig, token = self._access_token(stream_type) url = self.usher.channel(self.channel, sig=sig, token=token) elif stream_type == "video": sig, token = self._access_token(stream_type) url = self.usher.video(self.video_id, nauthsig=sig, nauth=token) else: self.logger.debug( "Unknown HLS stream type: {0}".format(stream_type)) return {} try: # If the stream is a VOD that is still being recorded the stream should start at the # beginning of the recording streams = HLSStream.parse_variant_playlist( self.session, url, force_restart=not stream_type == "live") 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 _find_stream_id(self, text): match = self._player_config_re.search(text) if match: stream_id = parse_json(match.group(1), schema=self._player_config_schema) return stream_id
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 = crypto_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