diff --git a/TOOLS/umpv b/TOOLS/umpv index 2593e63a7b..da4a767d57 100755 --- a/TOOLS/umpv +++ b/TOOLS/umpv @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """ -This script emulates "unique application" functionality on Linux. When starting +This script emulates "unique application" functionality. When starting playback with this script, it will try to reuse an already running instance of mpv (but only if that was started with umpv). Other mpv instances (not started by umpv) are ignored, and the script doesn't know about them. @@ -33,6 +33,7 @@ import string import subprocess import sys from collections.abc import Iterable +from typing import BinaryIO def is_url(filename: str) -> bool: @@ -45,6 +46,9 @@ def is_url(filename: str) -> bool: return all(c in allowed_symbols for c in prefix) def get_socket_path() -> str: + if os.name == "nt": + return r"\\.\pipe\umpv" + base_dir = ( os.getenv("UMPV_SOCKET_DIR") or os.getenv("XDG_RUNTIME_DIR") or @@ -57,20 +61,21 @@ def get_socket_path() -> str: "Ensure that one of the following environment variables is set: " "UMPV_SOCKET_DIR, XDG_RUNTIME_DIR, HOME or TMPDIR.") - return os.path.join(base_dir, ".umpv_socket") + return os.path.join(base_dir, ".umpv") -def send_files_to_mpv(sock: socket.socket, files: Iterable[str]) -> None: +def send_files_to_mpv(conn: socket.socket | BinaryIO, files: Iterable[str]) -> None: try: + send = conn.send if isinstance(conn, socket.socket) else conn.write for f in files: - # escape: \ \n " f = f.replace("\\", "\\\\").replace('"', '\\"').replace("\n", "\\n") - sock.send(f'raw loadfile "{f}" append-play\n'.encode()) + send(f'raw loadfile "{f}" append-play\n'.encode()) except Exception: print("mpv is terminating or the connection was lost.", file=sys.stderr) sys.exit(1) def start_mpv(files: Iterable[str], socket_path: str) -> None: - mpv_command = shlex.split(os.getenv("MPV", "mpv")) + mpv = "mpv" if os.name != "nt" else "mpv.exe" + mpv_command = shlex.split(os.getenv("MPV", mpv)) mpv_command.extend([ "--profile=builtin-pseudo-gui", f"--input-ipc-server={socket_path}", @@ -84,9 +89,13 @@ def main() -> None: socket_path = get_socket_path() try: - with socket.socket(socket.AF_UNIX) as sock: - sock.connect(socket_path) - send_files_to_mpv(sock, files) + if os.name == "nt": + with open(socket_path, "r+b", buffering=0) as pipe: + send_files_to_mpv(pipe, files) + else: + with socket.socket(socket.AF_UNIX) as sock: + sock.connect(socket_path) + send_files_to_mpv(sock, files) except (FileNotFoundError, ConnectionRefusedError): start_mpv(files, socket_path)