From 96f327e4dc22d706e4538d16390cb82e2463370d Mon Sep 17 00:00:00 2001 From: Nose Date: Mon, 23 Mar 2026 21:47:25 -0700 Subject: [PATCH] klj --- MPV/LUA/main.lua | 23 ++- MPV/mpv_ipc.py | 10 -- MPV/pipeline_helper.py | 60 +++++--- MPV/portable_config/mpv.conf | 2 +- .../uosc/scripts/uosc/elements/TopBar.lua | 8 +- cmdnat/pipe.py | 144 +++++++++++++----- 6 files changed, 166 insertions(+), 81 deletions(-) diff --git a/MPV/LUA/main.lua b/MPV/LUA/main.lua index 88aef48..8becba2 100644 --- a/MPV/LUA/main.lua +++ b/MPV/LUA/main.lua @@ -5993,16 +5993,23 @@ mp.add_timeout(0, function() _lua_log('lyric-helper auto-start raised: ' .. tostring(lyric_err)) end - -- Try to re-register right-click after UOSC loads (might override its binding) - mp.add_timeout(1.0, function() - _lua_log('[KEY] attempting to re-register mbtn_right after UOSC loaded') - pcall(function() - mp.add_key_binding("mbtn_right", "medios-menu-right-click-late", function() - _lua_log('[KEY] mbtn_right pressed (late registration attempt)') + -- Force-claim mbtn_right so the Medios menu fires reliably regardless of + -- whether uosc has a cursor zone active at the click position. + -- mp.add_forced_key_binding has higher priority than uosc's force-group. + -- Use complex=true to get the event type and fire only on button release. + local ok_rclick, rclick_err = pcall(function() + mp.add_forced_key_binding('mbtn_right', 'medios-mbtn-right-forced', function(e) + if e and e.event == 'up' then + _lua_log('[KEY] mbtn_right up -> show_menu') M.show_menu() - end, {repeatable=false}) - end) + end + end, {complex = true, repeatable = false}) end) + if ok_rclick then + _lua_log('[KEY] registered forced mbtn_right binding') + else + _lua_log('[KEY] forced mbtn_right failed: ' .. tostring(rclick_err) .. ' (falling back to input.conf)') + end end) return M diff --git a/MPV/mpv_ipc.py b/MPV/mpv_ipc.py index 80cd478..6c9afed 100644 --- a/MPV/mpv_ipc.py +++ b/MPV/mpv_ipc.py @@ -1166,11 +1166,6 @@ class MPVIPCClient: rid = request["request_id"] payload = json.dumps(request) + "\n" - # Debug: log the command being sent - from SYS.logger import debug as _debug - - _debug(f"[IPC] Sending: {payload.strip()}") - # Send command self._write_payload(payload) @@ -1199,11 +1194,6 @@ class MPVIPCClient: continue resp = json.loads(line) - # Debug: log responses - from SYS.logger import debug as _debug - - _debug(f"[IPC] Received: {line}") - # Check if this is the response to our request if resp.get("request_id") == request.get("request_id"): return resp diff --git a/MPV/pipeline_helper.py b/MPV/pipeline_helper.py index b641f0a..1e40667 100644 --- a/MPV/pipeline_helper.py +++ b/MPV/pipeline_helper.py @@ -1766,27 +1766,35 @@ def main(argv: Optional[list[str]] = None) -> int: # Keep trying. time.sleep(0.10) - command_client = MPVIPCClient(socket_path=str(args.ipc), timeout=0.75, silent=True) + use_shared_ipc_client = platform.system() == "Windows" + command_client = None if use_shared_ipc_client else MPVIPCClient(socket_path=str(args.ipc), timeout=0.75, silent=True) def _send_helper_command(command: Any, label: str = "") -> bool: with command_client_lock: + target_client = client if use_shared_ipc_client else command_client + if target_client is None: + return False try: - if command_client.sock is None: - if not command_client.connect(): + if target_client.sock is None: + if use_shared_ipc_client: + if note_ipc_unavailable is not None: + note_ipc_unavailable(f"helper-command-connect:{label or '?'}") + return False + if not target_client.connect(): _append_helper_log( f"[helper-ipc] connect failed label={label or '?'}" ) _note_ipc_unavailable(f"helper-command-connect:{label or '?' }") return False _mark_ipc_alive(f"helper-command-connect:{label or '?'}") - rid = command_client.send_command_no_wait(command) + rid = target_client.send_command_no_wait(command) if rid is None: _append_helper_log( f"[helper-ipc] send failed label={label or '?'}" ) _note_ipc_unavailable(f"helper-command-send:{label or '?'}") try: - command_client.disconnect() + target_client.disconnect() except Exception: pass return False @@ -1798,7 +1806,7 @@ def main(argv: Optional[list[str]] = None) -> int: ) _note_ipc_unavailable(f"helper-command-exception:{label or '?'}") try: - command_client.disconnect() + target_client.disconnect() except Exception: pass return False @@ -1906,19 +1914,24 @@ def main(argv: Optional[list[str]] = None) -> int: except Exception: pass - _start_ready_heartbeat( - str(args.ipc), - stop_event, - _mark_ipc_alive, - _note_ipc_unavailable, - ) - _start_request_poll_loop( - str(args.ipc), - stop_event, - _process_request, - _mark_ipc_alive, - _note_ipc_unavailable, - ) + if use_shared_ipc_client: + _append_helper_log( + "[helper] Windows single-client IPC mode enabled; auxiliary heartbeat/poll disabled" + ) + else: + _start_ready_heartbeat( + str(args.ipc), + stop_event, + _mark_ipc_alive, + _note_ipc_unavailable, + ) + _start_request_poll_loop( + str(args.ipc), + stop_event, + _process_request, + _mark_ipc_alive, + _note_ipc_unavailable, + ) # Pre-compute store choices at startup and publish to a cached property so Lua # can read immediately without waiting for a request/response cycle (which may timeout). @@ -2075,10 +2088,11 @@ def main(argv: Optional[list[str]] = None) -> int: _append_helper_log(f"[helper] exiting reason={shutdown_reason}") except Exception: pass - try: - command_client.disconnect() - except Exception: - pass + if command_client is not None: + try: + command_client.disconnect() + except Exception: + pass try: client.disconnect() except Exception: diff --git a/MPV/portable_config/mpv.conf b/MPV/portable_config/mpv.conf index 35d5ee0..e33814d 100644 --- a/MPV/portable_config/mpv.conf +++ b/MPV/portable_config/mpv.conf @@ -68,7 +68,7 @@ loop-file # Enable the screensaver when images are kept open forever. [screensaver] -profile-cond=p['current-tracks/video'].image and image_display_duration == math.huge +profile-cond=get('current-tracks/video', {}).image and image_display_duration == math.huge profile-restore=copy stop-screensaver=no diff --git a/MPV/portable_config/scripts/uosc/scripts/uosc/elements/TopBar.lua b/MPV/portable_config/scripts/uosc/scripts/uosc/elements/TopBar.lua index ecad7a1..4174f7a 100644 --- a/MPV/portable_config/scripts/uosc/scripts/uosc/elements/TopBar.lua +++ b/MPV/portable_config/scripts/uosc/scripts/uosc/elements/TopBar.lua @@ -249,7 +249,7 @@ function TopBar:render() local button_fg = is_hover and (button.hover_fg or bg) or fg local button_bg = is_hover and (button.hover_bg or fg) or bg - cursor:zone('primary_down', rect, button.command) + cursor:zone('primary_click', rect, button.command) local bg_size = self.size - margin local bg_ax, bg_ay = rect.ax + (is_left and margin or 0), rect.ay + margin @@ -302,7 +302,7 @@ function TopBar:render() if left_aligned then title_bx = rect.ax - margin else title_ax = rect.bx + margin end -- Click action - cursor:zone('primary_down', rect, function() mp.command('script-binding uosc/playlist') end) + cursor:zone('primary_click', rect, function() mp.command('script-binding uosc/playlist') end) end -- Skip rendering titles if there's not enough horizontal space @@ -325,7 +325,7 @@ function TopBar:render() local title_rect = {ax = ax, ay = title_ay, bx = ax + rect_width, by = by} if options.top_bar_alt_title_place == 'toggle' then - cursor:zone('primary_down', title_rect, function() self:toggle_title() end) + cursor:zone('primary_click', title_rect, function() self:toggle_title() end) end ass:rect(title_rect.ax, title_rect.ay, title_rect.bx, title_rect.by, { @@ -415,7 +415,7 @@ function TopBar:render() -- Click action rect.bx = time_bx - cursor:zone('primary_down', rect, function() mp.command('script-binding uosc/chapters') end) + cursor:zone('primary_click', rect, function() mp.command('script-binding uosc/chapters') end) title_ay = rect.by + self.title_spacing end diff --git a/cmdnat/pipe.py b/cmdnat/pipe.py index 70f4541..94cca7c 100644 --- a/cmdnat/pipe.py +++ b/cmdnat/pipe.py @@ -173,6 +173,89 @@ def _apply_log_filter(lines: Sequence[str], filter_text: Optional[str]) -> List[ return filtered +def _collapse_repeated_log_lines(lines: Sequence[str]) -> List[str]: + collapsed: List[str] = [] + last_line: Optional[str] = None + repeat_count = 0 + + def flush() -> None: + nonlocal last_line, repeat_count + if last_line is None: + return + if repeat_count > 1: + collapsed.append(f"{last_line} [repeated x{repeat_count}]") + else: + collapsed.append(last_line) + last_line = None + repeat_count = 0 + + for raw in lines: + line = str(raw or "") + if line == last_line: + repeat_count += 1 + continue + flush() + last_line = line + repeat_count = 1 + + flush() + return collapsed + + +def _is_noisy_mpv_log_line(line: str) -> bool: + text = str(line or "") + lower = text.lower() + noisy_tokens = ( + "client connected", + "client disconnected", + "destroying client handle", + "set property: options/log-file", + "set property: options/msg-level", + "run command: script-message-to, flags=64, args=[target=\"console\", args=\"log\"", + "run command: script-message-to, flags=64, args=[target=\"console\", args=\"print\"", + ) + if any(token in lower for token in noisy_tokens): + return True + + startup_prefixes = ( + "mpv v", + " built on ", + "libplacebo version:", + "ffmpeg version:", + "ffmpeg library versions:", + " libavcodec", + " libavdevice", + " libavfilter", + " libavformat", + " libavutil", + " libswresample", + " libswscale", + "configuration:", + "list of enabled features:", + "built with ndebug.", + ) + # Log lines look like [timestamp][level][module] content — strip 3 brackets. + stripped = lower.split(']', 3) + payload = stripped[-1].strip() if len(stripped) > 1 else lower.strip() + return any(prefix in payload for prefix in startup_prefixes) + + +def _focus_mpv_log_lines(lines: Sequence[str]) -> List[str]: + focused = [str(line) for line in lines if not _is_noisy_mpv_log_line(str(line))] + return _collapse_repeated_log_lines(focused) + + +def _focus_db_log_rows( + rows: Sequence[tuple[Any, Any, Any, Any]], +) -> List[str]: + rendered: List[str] = [] + for timestamp, level, _module, message in rows: + ts = str(timestamp or "").strip() + prefix = f"[{ts}] [{level}] " if ts else f"[{level}] " + rendered.append(prefix + str(message or "")) + return _collapse_repeated_log_lines(rendered) + + def _slice_mpv_log_to_latest_run(lines: Sequence[str]) -> List[str]: startup_pattern = re.compile(r"\bmpv v\d", re.IGNORECASE) collected = list(lines) @@ -296,7 +379,7 @@ def _try_enable_mpv_file_logging(mpv_log_path: str, *, attempts: int = 3) -> boo { "command": ["set_property", "options/msg-level", - "all=v"] + "cplayer=info,ffmpeg=error,ipc=warn"] } ) ok = bool( @@ -1585,10 +1668,9 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int: try: # Default: keep `.pipe` quiet even if debug is enabled. - # With -log: enable debug and route it to stdout (pipeable), plus enable mpv log-file. + # With -log: keep transport chatter quiet and print an explicit focused + # report later in this function. if log_requested: - set_debug(True) - set_thread_stream(sys.stdout) try: log_dir = _repo_log_dir() mpv_log_path = str((log_dir / "medeia-mpv.log").resolve()) @@ -1606,8 +1688,6 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int: pass except Exception: pass - debug(f"MPV log file: {mpv_log_path}") - # Try to enable mpv file logging on the currently running instance. # (If mpv wasn't started with --log-file, this may not work everywhere.) try: @@ -1620,7 +1700,7 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int: mpv_live = MPV() if mpv_live.is_running(): mpv_live.set_property("options/log-file", mpv_log_path) - mpv_live.set_property("options/msg-level", "all=v") + mpv_live.set_property("options/msg-level", "cplayer=info,ffmpeg=error,ipc=warn") except Exception: pass else: @@ -2319,7 +2399,9 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int: break latest_run_tail = _slice_mpv_log_to_latest_run(tail_lines) - filtered_tail = _apply_log_filter(latest_run_tail, log_filter_text) + filtered_tail = _focus_mpv_log_lines( + _apply_log_filter(latest_run_tail, log_filter_text) + ) helper_heartbeat = _get_mpv_property("user-data/medeia-pipeline-ready") helper_status = "not running" @@ -2327,25 +2409,6 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int: helper_status = f"running ({helper_heartbeat})" print(f"Pipeline helper: {helper_status}") - if filtered_tail: - title = "MPV log (latest run tail" - if log_filter_text: - title += f" filtered by '{log_filter_text}'" - title += "):" - print(title) - for ln in filtered_tail: - print(ln) - else: - if log_filter_text: - print(f"MPV log (tail): ") - else: - print("MPV log (latest run tail): ") - print( - "Note: On some Windows builds, mpv cannot start writing to --log-file after launch." - ) - print( - "If you need full [main2] logs, restart mpv so it starts with --log-file." - ) # Print database logs for mpv module (helper + lua output) try: @@ -2367,12 +2430,9 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int: if marker_msg: print(f"Run marker: {marker_msg}") if mpv_logs: - for timestamp, level, _module, message in mpv_logs: - ts = str(timestamp or "").strip() - if ts: - print(f"[{ts}] [{level}] {message}") - else: - print(f"[{level}] {message}") + print("Medios MPV logs (latest run, focused):") + for line in _focus_db_log_rows(mpv_logs): + print(line) else: if log_filter_text: print(f"(no latest-run mpv logs found matching '{log_filter_text}')") @@ -2382,6 +2442,20 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int: debug(f"Could not fetch database logs: {e}") pass + if filtered_tail: + title = "MPV core log (latest run, filtered)" + if log_filter_text: + title += f" for '{log_filter_text}'" + title += ":" + print(title) + for ln in filtered_tail: + print(ln) + else: + if log_filter_text: + print(f"MPV core log: ") + else: + print("MPV core log: ") + fallback_logs = [ ("Medeia Lua log file tail", str(_lua_log_file())), ("Medeia helper log file tail", str(_helper_log_file())), @@ -2391,7 +2465,7 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int: lines = _tail_text_file(path, max_lines=120) except Exception: lines = [] - lines = _apply_log_filter(lines, log_filter_text) + lines = _collapse_repeated_log_lines(_apply_log_filter(lines, log_filter_text)) if not lines: continue print(f"{title}:") @@ -2481,7 +2555,7 @@ def _start_mpv( mpv_log_path = (start_opts or {}).get("mpv_log_path") if isinstance(mpv_log_path, str) and mpv_log_path.strip(): extra_args.append(f"--log-file={mpv_log_path}") - extra_args.append("--msg-level=all=v") + extra_args.append("--msg-level=cplayer=info,ffmpeg=error,ipc=warn") # Always start MPV with the bundled Lua script via MPV class. mpv.start(