def main(): if len(sys.argv) < 3: exit("Usage: {0} <url> <quality>".format(sys.argv[0])) # Initialize and check GStreamer version gi.require_version("Gst", "1.0") gobject.threads_init() gst.init(None) # Collect arguments url = sys.argv[1] quality = sys.argv[2] # Create the Livecli session livecli = Livecli() # Enable logging livecli.set_loglevel("info") livecli.set_logoutput(sys.stdout) # Attempt to fetch streams try: streams = livecli.streams(url) except NoPluginError: exit("Livecli is unable to handle the URL '{0}'".format(url)) except PluginError as err: exit("Plugin error: {0}".format(err)) if not streams: exit("No streams found on URL '{0}'".format(url)) # Look for specified stream if quality not in streams: exit("Unable to find '{0}' stream on URL '{1}'".format(quality, url)) # We found the stream stream = streams[quality] # Create the player and start playback player = LivecliPlayer() # Blocks until playback is done player.play(stream)
def _play_stream(HTTPBase, redirect=False): """Creates a livecli session and plays the stream.""" session = Livecli() session.set_logprefix("[ID-{0}]".format(str(int(time()))[4:])) logger = session.logger.new_module("livecli-server") session.set_loglevel("info") logger.info("User-Agent: {0}".format( HTTPBase.headers.get("User-Agent", "???"))) logger.info("Client: {0}".format(HTTPBase.client_address)) logger.info("Address: {0}".format(HTTPBase.address_string())) # Load custom user plugins if os.path.isdir(PLUGINS_DIR): session.load_plugins(PLUGINS_DIR) old_data = parse_qsl(urlparse(HTTPBase.path).query) data = [] for k, v in old_data: data += [(unquote_plus(k), unquote_plus(v))] data_other, session = command_session(session, data) url = data_other.get("url") if not url: HTTPBase._headers(404, "text/html") logger.error("No URL provided.") return quality = (data_other.get("q") or data_other.get("quality") or data_other.get("stream") or data_other.get("default-stream") or "best") try: cache = data_other.get("cache") or 4096 except TypeError: cache = 4096 loglevel = data_other.get("l") or data_other.get("loglevel") or "debug" session.set_loglevel(loglevel) try: if redirect is True: streams = session.streams(url, stream_types=["hls", "http"]) else: streams = session.streams(url) except Exception as e: HTTPBase._headers(404, "text/html") logger.error("No Stream Found!") return if not streams: HTTPBase._headers(404, "text/html") return # XXX: only one quality will work currently try: stream = streams[quality] except KeyError: stream = streams["best"] quality = "best" if isinstance(stream, HTTPStream) is False and isinstance( stream, HDSStream) is False: # allow only http based streams: HDS HLS HTTP # RTMP is not supported HTTPBase._headers(404, "text/html") return if redirect is True: logger.info("301 - URL: {0}".format(stream.url)) HTTPBase.send_response(301) HTTPBase.send_header("Location", stream.url) HTTPBase.end_headers() logger.info("301 - done") return hls_session_reload = data_other.get("hls-session-reload") if hls_session_reload: livecli_cache = Cache(filename="streamdata.json", key_prefix="cache:{0}".format(stream.url)) livecli_cache.set("cache_stream_name", quality, (int(hls_session_reload) + 60)) livecli_cache.set("cache_url", url, (int(hls_session_reload) + 60)) session.set_option("hls-session-reload", int(hls_session_reload)) try: fd = stream.open() except StreamError as err: HTTPBase._headers(404, "text/html") logger.error("Could not open stream: {0}".format(err)) return HTTPBase._headers(200, "video/unknown") try: logger.debug("Pre-buffering {0} bytes".format(cache)) while True: buff = fd.read(cache) if not buff: logger.error("No Data!") break HTTPBase.wfile.write(buff) HTTPBase.wfile.close() except socket.error as e: if isinstance(e.args, tuple): if e.errno == errno.EPIPE: # remote peer disconnected logger.info("Detected remote disconnect") pass else: logger.error(str(e)) else: logger.error(str(e)) fd.close() logger.info("Stream ended") fd = None