def test_supported_player_generic(self): self.assertEqual("vlc", PlayerOutput.supported_player("vlc")) self.assertEqual("mpv", PlayerOutput.supported_player("mpv")) self.assertEqual("potplayer", PlayerOutput.supported_player("potplayermini.exe"))
def test_supported_player_win32(self): self.assertEqual("mpv", PlayerOutput.supported_player("C:\\MPV\\mpv.exe")) self.assertEqual("vlc", PlayerOutput.supported_player("C:\\VLC\\vlc.exe")) self.assertEqual("potplayer", PlayerOutput.supported_player("C:\\PotPlayer\\PotPlayerMini64.exe"))
def test_supported_player_negative_win32(self): self.assertEqual(None, PlayerOutput.supported_player("C:\\mpc\\mpc-hd.exe")) self.assertEqual(None, PlayerOutput.supported_player("C:\\mplayer\\not-vlc.exe")) self.assertEqual(None, PlayerOutput.supported_player("C:\\NotPlayer\\NotPlayerMini64.exe"))
def output_stream_passthrough(formatter, stream): """Prepares a filename to be passed to the player.""" global output try: url = stream.to_url() except TypeError: console.exit("The stream specified cannot be translated to a URL") return False output = PlayerOutput( args.player, args=args.player_args, filename='"{0}"'.format(url), call=True, quiet=not args.verbose_player, title=formatter.title(args.title, defaults=DEFAULT_STREAM_METADATA) if args.title else args.url) try: log.info("Starting player: {0}".format(args.player)) output.open() except OSError as err: console.exit("Failed to start player: {0} ({1})", args.player, err) return False return True
def test_output_mpv_unicode_title_posix(popen): po = PlayerOutput("mpv", title=UNICODE_TITLE) popen().poll.side_effect = lambda: None po.open() popen.assert_called_with(['mpv', u"--title=" + UNICODE_TITLE, '-'], bufsize=ANY, stderr=ANY, stdout=ANY, stdin=ANY)
def test_output_mpv_unicode_title_windows_py3(popen): po = PlayerOutput("mpv.exe", title=UNICODE_TITLE) popen().poll.side_effect = lambda: None po.open() popen.assert_called_with("mpv.exe \"--title=" + UNICODE_TITLE + "\" -", bufsize=ANY, stderr=ANY, stdout=ANY, stdin=ANY)
def test_output_vlc_unicode_title_windows_py3(popen): po = PlayerOutput("vlc.exe", title=UNICODE_TITLE) popen().poll.side_effect = lambda: None po.open() popen.assert_called_with( f"vlc.exe --input-title-format \"{UNICODE_TITLE}\" -", bufsize=ANY, stderr=ANY, stdout=ANY, stdin=ANY)
def test_output_vlc_unicode_title_posix(popen): po = PlayerOutput("vlc", title=UNICODE_TITLE) popen().poll.side_effect = lambda: None po.open() popen.assert_called_with( ['vlc', u'--input-title-format', UNICODE_TITLE, '-'], bufsize=ANY, stderr=ANY, stdout=ANY, stdin=ANY)
def test_output_mpv_unicode_title_posix(popen): po = PlayerOutput("mpv", title=UNICODE_TITLE) popen().poll.side_effect = lambda: None po.open() popen.assert_called_with( ["mpv", f"--force-media-title={UNICODE_TITLE}", "-"], bufsize=ANY, stderr=ANY, stdout=ANY, stdin=ANY)
def test_output_vlc_unicode_title_windows_py2(popen): po = PlayerOutput("vlc.exe", title=UNICODE_TITLE) popen().poll.side_effect = lambda: None po.open() popen.assert_called_with("vlc.exe --input-title-format \"" + UNICODE_TITLE.encode(get_filesystem_encoding()) + "\" -", bufsize=ANY, stderr=ANY, stdout=ANY, stdin=ANY)
def _create_output(self): namedpipe = self._make_pipe() return PlayerOutput(self._player_stream_cmd, args='{filename}', quiet=False, kill=True, namedpipe=namedpipe, http=None)
def create_output(plugin): """Decides where to write the stream. Depending on arguments it can be one of these: - The stdout pipe - A subprocess' stdin pipe - A named pipe that the subprocess reads from - A regular file """ if (args.output or args.stdout) and (args.record or args.record_and_pipe): console.exit( "Cannot use record options with other file output options.") if args.output: if args.output == "-": out = FileOutput(fd=stdout) else: out = check_file_output(args.output, args.force) elif args.stdout: out = FileOutput(fd=stdout) elif args.record_and_pipe: record = check_file_output(args.record_and_pipe, args.force) out = FileOutput(fd=stdout, record=record) else: http = namedpipe = record = None if not args.player: console.exit("The default player (VLC) does not seem to be " "installed. You must specify the path to a player " "executable with --player.") if args.player_fifo: try: namedpipe = NamedPipe() except OSError as err: console.exit("Failed to create pipe: {0}", err) elif args.player_http: http = create_http_server() title = create_title(plugin) if args.record: record = check_file_output(args.record, args.force) log.info("Starting player: {0}".format(args.player)) out = PlayerOutput(args.player, args=args.player_args, quiet=not args.verbose_player, kill=not args.player_no_close, namedpipe=namedpipe, http=http, record=record, title=title) return out
def output_stream_passthrough(plugin, stream): """Prepares a filename to be passed to the player.""" global output title = create_title(plugin) filename = '"{0}"'.format(stream_to_url(stream)) output = PlayerOutput(args.player, args=args.player_args, filename=filename, call=True, quiet=not args.verbose_player, title=title) try: log.info("Starting player: {0}".format(args.player)) output.open() except OSError as err: console.exit("Failed to start player: {0} ({1})", args.player, err) return False return True
def output_stream_passthrough(stream, formatter: Formatter): """Prepares a filename to be passed to the player.""" global output filename = f'"{stream_to_url(stream)}"' output = PlayerOutput( args.player, args=args.player_args, filename=filename, call=True, quiet=not args.verbose_player, title=formatter.title(args.title, defaults=DEFAULT_STREAM_METADATA) if args.title else args.url) try: log.info(f"Starting player: {args.player}") output.open() except OSError as err: console.exit(f"Failed to start player: {args.player} ({err})") return False return True
def test_open_player_with_title_mpv_escape_16(self): self.assertEqual(PlayerOutput._mpv_title_escape(r'\$\$> $$$ \\$> $ showing "\$>" before escaping'), r'$$> $$$$$$ \$> $ showing "$>" before escaping')
def test_output_args_windows(): po_none = PlayerOutput("foo") assert po_none._create_arguments() == "foo -" po_implicit = PlayerOutput("foo", args="--bar") assert po_implicit._create_arguments() == "foo --bar -" po_explicit = PlayerOutput("foo", args="--bar {playerinput}") assert po_explicit._create_arguments() == "foo --bar -" po_fallback = PlayerOutput("foo", args="--bar {filename}") assert po_fallback._create_arguments() == "foo --bar -"
def test_supported_player_args_posix(self): self.assertEqual("mpv", PlayerOutput.supported_player("/usr/bin/mpv --argh")) self.assertEqual("vlc", PlayerOutput.supported_player("/usr/bin/vlc --argh"))
def test_supported_player_negative_posix(self): self.assertEqual(None, PlayerOutput.supported_player("/usr/bin/xmpvideo")) self.assertEqual(None, PlayerOutput.supported_player("/usr/bin/echo"))
def output_stream_http( plugin: Plugin, initial_streams: Dict[str, Stream], formatter: Formatter, external: bool = False, port: int = 0, ): """Continuously output the stream over HTTP.""" global output if not external: if not args.player: console.exit("The default player (VLC) does not seem to be " "installed. You must specify the path to a player " "executable with --player.") server = create_http_server() player = output = PlayerOutput( args.player, args=args.player_args, filename=server.url, quiet=not args.verbose_player, title=formatter.title(args.title, defaults=DEFAULT_STREAM_METADATA) if args.title else args.url ) try: log.info(f"Starting player: {args.player}") if player: player.open() except OSError as err: console.exit(f"Failed to start player: {args.player} ({err})") else: server = create_http_server(host=None, port=port) player = None log.info("Starting server, access with one of:") for url in server.urls: log.info(" " + url) initial_streams_used = False for req in iter_http_requests(server, player): user_agent = req.headers.get("User-Agent") or "unknown player" log.info(f"Got HTTP request from {user_agent}") stream_fd = prebuffer = None while not stream_fd and (not player or player.running): try: if not initial_streams_used: streams = initial_streams initial_streams_used = True else: streams = fetch_streams(plugin) for stream_name in (resolve_stream_name(streams, s) for s in args.stream): if stream_name in streams: stream = streams[stream_name] break else: log.info("Stream not available, will re-fetch streams in 10 sec") sleep(10) continue except PluginError as err: log.error(f"Unable to fetch new streams: {err}") continue try: log.info(f"Opening stream: {stream_name} ({type(stream).shortname()})") stream_fd, prebuffer = open_stream(stream) except StreamError as err: log.error(err) if stream_fd and prebuffer: log.debug("Writing stream to player") read_stream(stream_fd, server, prebuffer, formatter) server.close(True) if player: player.close() server.close()
def test_open_player_with_title_mpv_escape_16(self): self.assertEqual( PlayerOutput._mpv_title_escape( r'\$\$> $$$ \\$> $ showing "\$>" before escaping'), r'$$> $$$$$$ \$> $ showing "$>" before escaping')
def test_open_player_with_title_mpv_escape_7(self): self.assertEqual(PlayerOutput._mpv_title_escape("$> also not a valid way to escape $"), '$$> also not a valid way to escape $$')
def test_open_player_with_title_mpv_escape_4(self): self.assertEqual(PlayerOutput._mpv_title_escape(r'\$> $$ begins with escape and double \$> $$ escape codes'), '$> $$ begins with escape and double $> $$ escape codes')
def test_open_player_with_title_mpv_escape_11(self): self.assertEqual(PlayerOutput._mpv_title_escape(r'even leading $$\$\$> $$$$$'), 'even leading $$$$$$> $$$$$$$$$$') # will expand after \$> because eve)
def test_open_player_with_title_mpv_escape_10(self): self.assertEqual(PlayerOutput._mpv_title_escape(r'odd leading $$$\$> $$$ $>'), 'odd leading $$$$$$$> $$$ $>')
def test_open_player_with_title_mpv_escape_9(self): self.assertEqual(PlayerOutput._mpv_title_escape(r'Multiple $> \$> $> $$ \$> $$> $> \$> $> $> \$> \$> \$>\$>$$$$'), 'Multiple $$> $> $> $$ $> $$> $> $> $> $> $> $> $>$>$$$$')
def test_supported_player_generic(self): self.assertEqual("vlc", PlayerOutput.supported_player("vlc")) self.assertEqual("mpv", PlayerOutput.supported_player("mpv"))
def test_open_player_with_title_mpv_escape_8(self): self.assertEqual(PlayerOutput._mpv_title_escape("not valid $$$$$$> not a valid way to escape $"), 'not valid $$$$$$$$$$$$> not a valid way to escape $$')
def test_open_player_with_title_mpv_escape_3(self): self.assertEqual(PlayerOutput._mpv_title_escape(r'ends with escape code $$ \$>'), 'ends with escape code $$$$ $>')
def test_open_player_with_title_mpv_escape_2(self): self.assertEqual(PlayerOutput._mpv_title_escape(r'\$> begins with escape code $$'), '$> begins with escape code $$')
def test_open_player_with_title_mpv_escape_15(self): self.assertEqual( PlayerOutput._mpv_title_escape(r'even and odd \$\$> $$ $\$> $$'), 'even and odd $$> $$$$ $$$> $$')
def test_open_player_with_title_mpv_escape_1(self): self.assertEqual(PlayerOutput._mpv_title_escape("no escape $$ codes $"), 'no escape $$$$ codes $$')
def test_supported_player_negative_win32(self): self.assertEqual(None, PlayerOutput.supported_player("C:\\mpc\\mpc-hd.exe")) self.assertEqual(None, PlayerOutput.supported_player("C:\\mplayer\\not-vlc.exe"))
def output_stream_http(plugin, initial_streams, external=False, port=0): """Continuously output the stream over HTTP.""" global output if not external: if not args.player: console.exit("The default player (VLC) does not seem to be " "installed. You must specify the path to a player " "executable with --player.") title = create_title(plugin) server = create_http_server() player = output = PlayerOutput(args.player, args=args.player_args, filename=server.url, quiet=not args.verbose_player, title=title) try: log.info("Starting player: {0}".format(args.player)) if player: player.open() except OSError as err: console.exit("Failed to start player: {0} ({1})", args.player, err) else: server = create_http_server(host=None, port=port) player = None log.info("Starting server, access with one of:") for url in server.urls: log.info(" " + url) for req in iter_http_requests(server, player): user_agent = req.headers.get("User-Agent") or "unknown player" log.info("Got HTTP request from {0}".format(user_agent)) stream_fd = prebuffer = None while not stream_fd and (not player or player.running): try: streams = initial_streams or fetch_streams(plugin) initial_streams = None for stream_name in (resolve_stream_name(streams, s) for s in args.stream): if stream_name in streams: stream = streams[stream_name] break else: log.info("Stream not available, will re-fetch " "streams in 10 sec") sleep(10) continue except PluginError as err: log.error(f"Unable to fetch new streams: {err}") continue try: log.info("Opening stream: {0} ({1})".format( stream_name, type(stream).shortname())) stream_fd, prebuffer = open_stream(stream) except StreamError as err: log.error("{0}".format(err)) if stream_fd and prebuffer: log.debug("Writing stream to player") read_stream(stream_fd, server, prebuffer) server.close(True) player.close() server.close()
def test_supported_player_args_posix(self): self.assertEqual("mpv", PlayerOutput.supported_player("/usr/bin/mpv --argh")) self.assertEqual("vlc", PlayerOutput.supported_player("/usr/bin/vlc --argh"))
def test_open_player_with_title_mpv_escape_14(self): self.assertEqual(PlayerOutput._mpv_title_escape(r'odd and even $\$> $$ \$\$> $$'), 'odd and even $$$> $$ $$> $$')
def test_supported_player_negative_posix(self): self.assertEqual(None, PlayerOutput.supported_player("/usr/bin/xmpvideo")) self.assertEqual(None, PlayerOutput.supported_player("/usr/bin/echo"))
def test_open_player_with_title_mpv_escape_9(self): self.assertEqual( PlayerOutput._mpv_title_escape( r'Multiple $> \$> $> $$ \$> $$> $> \$> $> $> \$> \$> \$>\$>$$$$' ), 'Multiple $$> $> $> $$ $> $$> $> $> $> $> $> $> $>$>$$$$')
def test_output_args_posix(): po_none = PlayerOutput("foo") assert po_none._create_arguments() == ["foo", "-"] po_implicit = PlayerOutput("foo", args="--bar") assert po_implicit._create_arguments() == ["foo", "--bar", "-"] po_explicit = PlayerOutput("foo", args="--bar {playerinput}") assert po_explicit._create_arguments() == ["foo", "--bar", "-"] po_fallback = PlayerOutput("foo", args="--bar {filename}") assert po_fallback._create_arguments() == ["foo", "--bar", "-"]
def test_open_player_with_title_mpv_escape_10(self): self.assertEqual( PlayerOutput._mpv_title_escape(r'odd leading $$$\$> $$$ $>'), 'odd leading $$$$$$$> $$$ $>')
def test_supported_player_args_win32(self): self.assertEqual("mpv", PlayerOutput.supported_player("C:\\MPV\\mpv.exe --argh")) self.assertEqual("vlc", PlayerOutput.supported_player("C:\\VLC\\vlc.exe --argh"))
def test_open_player_with_title_mpv_escape_11(self): self.assertEqual( PlayerOutput._mpv_title_escape(r'even leading $$\$\$> $$$$$'), 'even leading $$$$$$> $$$$$$$$$$' ) # will expand after \$> because eve)
def test_open_player_with_title_mpv_escape_15(self): self.assertEqual(PlayerOutput._mpv_title_escape(r'even and odd \$\$> $$ $\$> $$'), 'even and odd $$> $$$$ $$$> $$')
def test_open_player_with_title_mpv_escape_13(self): self.assertEqual( PlayerOutput._mpv_title_escape( r'$$$$$\$> odd leading beginning $$'), r'$$$$$$$$$$$> odd leading beginning $$')
def create_output(formatter: Formatter): """Decides where to write the stream. Depending on arguments it can be one of these: - The stdout pipe - A subprocess' stdin pipe - A named pipe that the subprocess reads from - A regular file """ if (args.output or args.stdout) and (args.record or args.record_and_pipe): console.exit( "Cannot use record options with other file output options.") if args.output: if args.output == "-": out = FileOutput(fd=stdout) else: out = check_file_output( formatter.path(args.output, args.fs_safe_rules), args.force) elif args.stdout: out = FileOutput(fd=stdout) elif args.record_and_pipe: record = check_file_output( formatter.path(args.record_and_pipe, args.fs_safe_rules), args.force) out = FileOutput(fd=stdout, record=record) elif not args.player: console.exit("The default player (VLC) does not seem to be " "installed. You must specify the path to a player " "executable with --player, a file path to save the " "stream with --output, or pipe the stream to " "another program with --stdout.") else: http = namedpipe = record = None if args.player_fifo: try: namedpipe = NamedPipe() except OSError as err: console.exit(f"Failed to create pipe: {err}") elif args.player_http: http = create_http_server() if args.record: record = check_file_output( formatter.path(args.record, args.fs_safe_rules), args.force) log.info(f"Starting player: {args.player}") out = PlayerOutput( args.player, args=args.player_args, quiet=not args.verbose_player, kill=not args.player_no_close, namedpipe=namedpipe, http=http, record=record, title=formatter.title(args.title, defaults=DEFAULT_STREAM_METADATA) if args.title else args.url) return out
def test_open_player_with_title_mpv_escape_14(self): self.assertEqual( PlayerOutput._mpv_title_escape(r'odd and even $\$> $$ \$\$> $$'), 'odd and even $$$> $$ $$> $$')
def test_open_player_with_title_mpv_escape_7(self): self.assertEqual( PlayerOutput._mpv_title_escape( "$> also not a valid way to escape $"), '$$> also not a valid way to escape $$')
def test_open_player_with_title_mpv_escape_5(self): self.assertEqual(PlayerOutput._mpv_title_escape(r'\$> \\$> showing "\$>" after escaping'), r'$> \$> showing "$>" after escaping')
def test_open_player_with_title_mpv_escape_8(self): self.assertEqual( PlayerOutput._mpv_title_escape( "not valid $$$$$$> not a valid way to escape $"), 'not valid $$$$$$$$$$$$> not a valid way to escape $$')
def test_open_player_with_title_mpv_escape_13(self): self.assertEqual(PlayerOutput._mpv_title_escape(r'$$$$$\$> odd leading beginning $$'), r'$$$$$$$$$$$> odd leading beginning $$')