This commit is contained in:
2026-01-12 17:55:04 -08:00
parent e45138568f
commit d0a68da1f5
8 changed files with 318 additions and 553 deletions

View File

@@ -190,11 +190,11 @@ def _ensure_lyric_overlay(mpv: MPV) -> None:
pass
def _send_ipc_command(command: Dict[str, Any], silent: bool = False) -> Optional[Any]:
def _send_ipc_command(command: Dict[str, Any], silent: bool = False, wait: bool = True) -> Optional[Any]:
"""Send a command to the MPV IPC pipe and return the response."""
try:
mpv = MPV()
return mpv.send(command, silent=silent)
return mpv.send(command, silent=silent, wait=wait)
except Exception as e:
if not silent:
debug(f"IPC Error: {e}", file=sys.stderr)
@@ -883,12 +883,14 @@ def _queue_items(
Any]] = None,
start_opts: Optional[Dict[str,
Any]] = None,
wait: bool = True,
) -> bool:
"""Queue items to MPV, starting it if necessary.
Args:
items: List of items to queue
clear_first: If True, the first item will replace the current playlist
wait: If True, wait for MPV to acknowledge the loadfile command.
Returns:
True if MPV was started, False if items were queued via IPC.
@@ -1125,8 +1127,8 @@ def _queue_items(
"request_id": 200
}
try:
debug(f"Sending MPV {command_name}: {target_to_send} mode={mode}")
resp = _send_ipc_command(cmd, silent=True)
debug(f"Sending MPV {command_name}: {target_to_send} mode={mode} wait={wait}")
resp = _send_ipc_command(cmd, silent=True, wait=wait)
debug(f"MPV {command_name} response: {resp}")
except Exception as e:
debug(f"Exception sending {command_name} to MPV: {e}", file=sys.stderr)
@@ -1249,6 +1251,7 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
list_mode = parsed.get("list")
play_mode = parsed.get("play")
pause_mode = parsed.get("pause")
replace_mode = parsed.get("replace")
save_mode = parsed.get("save")
load_mode = parsed.get("load")
current_mode = parsed.get("current")
@@ -1259,7 +1262,7 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
only_log = bool(
log_requested and not url_arg and index_arg is None and not clear_mode
and not list_mode and not play_mode and not pause_mode and not save_mode
and not load_mode and not current_mode
and not load_mode and not current_mode and not replace_mode
)
if only_log:
return 0
@@ -1302,10 +1305,19 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
# Handle URL queuing
mpv_started = False
if url_arg:
mpv_started = _queue_items([url_arg], config=config, start_opts=start_opts)
# Auto-play the URL when it's queued via .pipe "url" (without explicit flags)
# unless other flags are present
if not (clear_mode or play_mode or pause_mode or save_mode or load_mode):
# If -replace is used, or if we have a URL and -play is requested,
# we prefer 'replace' mode which starts playback immediately and avoids IPC overhead.
# NOTE: Use wait=False for URLs because yt-dlp resolution can be slow and
# would cause the calling Lua script to timeout.
queue_replace = bool(replace_mode)
if play_mode and not replace_mode:
# If -play is used with a URL, treat it as "play this now".
# For better UX, we'll replace the current playlist.
queue_replace = True
mpv_started = _queue_items([url_arg], clear_first=queue_replace, config=config, start_opts=start_opts, wait=False)
if not (clear_mode or play_mode or pause_mode or save_mode or load_mode or replace_mode):
if mpv_started:
# MPV was just started, wait a moment for it to be ready, then play first item
import time
@@ -1314,30 +1326,13 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
index_arg = "1" # 1-based index for first item
play_mode = True
else:
# MPV was already running, get playlist and play the newly added item
playlist = _get_playlist(silent=True)
if playlist and len(playlist) > 0:
# Auto-play the last item in the playlist (the one we just added)
# Use 1-based indexing
index_arg = str(len(playlist))
play_mode = True
else:
# Fallback: just list the playlist if we can't determine index
list_mode = True
# MPV was already running, just show the updated playlist.
list_mode = True
# If the user explicitly requested -play while queueing a URL, interpret that
# as "play the URL I just queued" (not merely "unpause whatever is currently playing").
if play_mode and index_arg is None:
if mpv_started:
# MPV was just started; give it a moment, then play first item.
import time
time.sleep(0.5)
index_arg = "1"
else:
playlist = _get_playlist(silent=True)
if playlist and len(playlist) > 0:
index_arg = str(len(playlist))
# If we used queue_replace, the URL is already playing. Clear play/index args to avoid redundant commands.
if queue_replace:
play_mode = False
index_arg = None
# Ensure lyric overlay is running (auto-discovery handled by MPV.lyric).
try:
@@ -2140,8 +2135,13 @@ CMDLET = Cmdlet(
description="Remove the selected item, or clear entire playlist if no index provided",
),
CmdletArg(name="list", type="flag", description="List items (default)"),
CmdletArg(name="play", type="flag", description="Resume playback"),
CmdletArg(name="play", type="flag", description="Resume playback or play specific index/URL"),
CmdletArg(name="pause", type="flag", description="Pause playback"),
CmdletArg(
name="replace",
type="flag",
description="Replace current playlist when adding index or URL",
),
CmdletArg(
name="save",
type="flag",