klj
This commit is contained in:
@@ -5993,16 +5993,23 @@ mp.add_timeout(0, function()
|
|||||||
_lua_log('lyric-helper auto-start raised: ' .. tostring(lyric_err))
|
_lua_log('lyric-helper auto-start raised: ' .. tostring(lyric_err))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Try to re-register right-click after UOSC loads (might override its binding)
|
-- Force-claim mbtn_right so the Medios menu fires reliably regardless of
|
||||||
mp.add_timeout(1.0, function()
|
-- whether uosc has a cursor zone active at the click position.
|
||||||
_lua_log('[KEY] attempting to re-register mbtn_right after UOSC loaded')
|
-- mp.add_forced_key_binding has higher priority than uosc's force-group.
|
||||||
pcall(function()
|
-- Use complex=true to get the event type and fire only on button release.
|
||||||
mp.add_key_binding("mbtn_right", "medios-menu-right-click-late", function()
|
local ok_rclick, rclick_err = pcall(function()
|
||||||
_lua_log('[KEY] mbtn_right pressed (late registration attempt)')
|
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()
|
M.show_menu()
|
||||||
end, {repeatable=false})
|
end
|
||||||
end)
|
end, {complex = true, repeatable = false})
|
||||||
end)
|
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)
|
end)
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|||||||
@@ -1166,11 +1166,6 @@ class MPVIPCClient:
|
|||||||
rid = request["request_id"]
|
rid = request["request_id"]
|
||||||
payload = json.dumps(request) + "\n"
|
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
|
# Send command
|
||||||
self._write_payload(payload)
|
self._write_payload(payload)
|
||||||
|
|
||||||
@@ -1199,11 +1194,6 @@ class MPVIPCClient:
|
|||||||
continue
|
continue
|
||||||
resp = json.loads(line)
|
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
|
# Check if this is the response to our request
|
||||||
if resp.get("request_id") == request.get("request_id"):
|
if resp.get("request_id") == request.get("request_id"):
|
||||||
return resp
|
return resp
|
||||||
|
|||||||
@@ -1766,27 +1766,35 @@ def main(argv: Optional[list[str]] = None) -> int:
|
|||||||
# Keep trying.
|
# Keep trying.
|
||||||
time.sleep(0.10)
|
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:
|
def _send_helper_command(command: Any, label: str = "") -> bool:
|
||||||
with command_client_lock:
|
with command_client_lock:
|
||||||
|
target_client = client if use_shared_ipc_client else command_client
|
||||||
|
if target_client is None:
|
||||||
|
return False
|
||||||
try:
|
try:
|
||||||
if command_client.sock is None:
|
if target_client.sock is None:
|
||||||
if not command_client.connect():
|
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(
|
_append_helper_log(
|
||||||
f"[helper-ipc] connect failed label={label or '?'}"
|
f"[helper-ipc] connect failed label={label or '?'}"
|
||||||
)
|
)
|
||||||
_note_ipc_unavailable(f"helper-command-connect:{label or '?' }")
|
_note_ipc_unavailable(f"helper-command-connect:{label or '?' }")
|
||||||
return False
|
return False
|
||||||
_mark_ipc_alive(f"helper-command-connect:{label or '?'}")
|
_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:
|
if rid is None:
|
||||||
_append_helper_log(
|
_append_helper_log(
|
||||||
f"[helper-ipc] send failed label={label or '?'}"
|
f"[helper-ipc] send failed label={label or '?'}"
|
||||||
)
|
)
|
||||||
_note_ipc_unavailable(f"helper-command-send:{label or '?'}")
|
_note_ipc_unavailable(f"helper-command-send:{label or '?'}")
|
||||||
try:
|
try:
|
||||||
command_client.disconnect()
|
target_client.disconnect()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
return False
|
return False
|
||||||
@@ -1798,7 +1806,7 @@ def main(argv: Optional[list[str]] = None) -> int:
|
|||||||
)
|
)
|
||||||
_note_ipc_unavailable(f"helper-command-exception:{label or '?'}")
|
_note_ipc_unavailable(f"helper-command-exception:{label or '?'}")
|
||||||
try:
|
try:
|
||||||
command_client.disconnect()
|
target_client.disconnect()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
return False
|
return False
|
||||||
@@ -1906,19 +1914,24 @@ def main(argv: Optional[list[str]] = None) -> int:
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
_start_ready_heartbeat(
|
if use_shared_ipc_client:
|
||||||
str(args.ipc),
|
_append_helper_log(
|
||||||
stop_event,
|
"[helper] Windows single-client IPC mode enabled; auxiliary heartbeat/poll disabled"
|
||||||
_mark_ipc_alive,
|
)
|
||||||
_note_ipc_unavailable,
|
else:
|
||||||
)
|
_start_ready_heartbeat(
|
||||||
_start_request_poll_loop(
|
str(args.ipc),
|
||||||
str(args.ipc),
|
stop_event,
|
||||||
stop_event,
|
_mark_ipc_alive,
|
||||||
_process_request,
|
_note_ipc_unavailable,
|
||||||
_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
|
# 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).
|
# 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}")
|
_append_helper_log(f"[helper] exiting reason={shutdown_reason}")
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
try:
|
if command_client is not None:
|
||||||
command_client.disconnect()
|
try:
|
||||||
except Exception:
|
command_client.disconnect()
|
||||||
pass
|
except Exception:
|
||||||
|
pass
|
||||||
try:
|
try:
|
||||||
client.disconnect()
|
client.disconnect()
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ loop-file
|
|||||||
|
|
||||||
# Enable the screensaver when images are kept open forever.
|
# Enable the screensaver when images are kept open forever.
|
||||||
[screensaver]
|
[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
|
profile-restore=copy
|
||||||
stop-screensaver=no
|
stop-screensaver=no
|
||||||
|
|
||||||
|
|||||||
@@ -249,7 +249,7 @@ function TopBar:render()
|
|||||||
local button_fg = is_hover and (button.hover_fg or bg) or fg
|
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
|
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_size = self.size - margin
|
||||||
local bg_ax, bg_ay = rect.ax + (is_left and margin or 0), rect.ay + 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
|
if left_aligned then title_bx = rect.ax - margin else title_ax = rect.bx + margin end
|
||||||
|
|
||||||
-- Click action
|
-- 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
|
end
|
||||||
|
|
||||||
-- Skip rendering titles if there's not enough horizontal space
|
-- 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}
|
local title_rect = {ax = ax, ay = title_ay, bx = ax + rect_width, by = by}
|
||||||
|
|
||||||
if options.top_bar_alt_title_place == 'toggle' then
|
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
|
end
|
||||||
|
|
||||||
ass:rect(title_rect.ax, title_rect.ay, title_rect.bx, title_rect.by, {
|
ass:rect(title_rect.ax, title_rect.ay, title_rect.bx, title_rect.by, {
|
||||||
@@ -415,7 +415,7 @@ function TopBar:render()
|
|||||||
|
|
||||||
-- Click action
|
-- Click action
|
||||||
rect.bx = time_bx
|
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
|
title_ay = rect.by + self.title_spacing
|
||||||
end
|
end
|
||||||
|
|||||||
144
cmdnat/pipe.py
144
cmdnat/pipe.py
@@ -173,6 +173,89 @@ def _apply_log_filter(lines: Sequence[str], filter_text: Optional[str]) -> List[
|
|||||||
return filtered
|
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]:
|
def _slice_mpv_log_to_latest_run(lines: Sequence[str]) -> List[str]:
|
||||||
startup_pattern = re.compile(r"\bmpv v\d", re.IGNORECASE)
|
startup_pattern = re.compile(r"\bmpv v\d", re.IGNORECASE)
|
||||||
collected = list(lines)
|
collected = list(lines)
|
||||||
@@ -296,7 +379,7 @@ def _try_enable_mpv_file_logging(mpv_log_path: str, *, attempts: int = 3) -> boo
|
|||||||
{
|
{
|
||||||
"command": ["set_property",
|
"command": ["set_property",
|
||||||
"options/msg-level",
|
"options/msg-level",
|
||||||
"all=v"]
|
"cplayer=info,ffmpeg=error,ipc=warn"]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
ok = bool(
|
ok = bool(
|
||||||
@@ -1585,10 +1668,9 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
# Default: keep `.pipe` quiet even if debug is enabled.
|
# 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:
|
if log_requested:
|
||||||
set_debug(True)
|
|
||||||
set_thread_stream(sys.stdout)
|
|
||||||
try:
|
try:
|
||||||
log_dir = _repo_log_dir()
|
log_dir = _repo_log_dir()
|
||||||
mpv_log_path = str((log_dir / "medeia-mpv.log").resolve())
|
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
|
pass
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
debug(f"MPV log file: {mpv_log_path}")
|
|
||||||
|
|
||||||
# Try to enable mpv file logging on the currently running instance.
|
# Try to enable mpv file logging on the currently running instance.
|
||||||
# (If mpv wasn't started with --log-file, this may not work everywhere.)
|
# (If mpv wasn't started with --log-file, this may not work everywhere.)
|
||||||
try:
|
try:
|
||||||
@@ -1620,7 +1700,7 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
|
|||||||
mpv_live = MPV()
|
mpv_live = MPV()
|
||||||
if mpv_live.is_running():
|
if mpv_live.is_running():
|
||||||
mpv_live.set_property("options/log-file", mpv_log_path)
|
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:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@@ -2319,7 +2399,9 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
|
|||||||
break
|
break
|
||||||
|
|
||||||
latest_run_tail = _slice_mpv_log_to_latest_run(tail_lines)
|
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_heartbeat = _get_mpv_property("user-data/medeia-pipeline-ready")
|
||||||
helper_status = "not running"
|
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})"
|
helper_status = f"running ({helper_heartbeat})"
|
||||||
|
|
||||||
print(f"Pipeline helper: {helper_status}")
|
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): <no entries match filter '{log_filter_text}'>")
|
|
||||||
else:
|
|
||||||
print("MPV log (latest run tail): <empty>")
|
|
||||||
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)
|
# Print database logs for mpv module (helper + lua output)
|
||||||
try:
|
try:
|
||||||
@@ -2367,12 +2430,9 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
|
|||||||
if marker_msg:
|
if marker_msg:
|
||||||
print(f"Run marker: {marker_msg}")
|
print(f"Run marker: {marker_msg}")
|
||||||
if mpv_logs:
|
if mpv_logs:
|
||||||
for timestamp, level, _module, message in mpv_logs:
|
print("Medios MPV logs (latest run, focused):")
|
||||||
ts = str(timestamp or "").strip()
|
for line in _focus_db_log_rows(mpv_logs):
|
||||||
if ts:
|
print(line)
|
||||||
print(f"[{ts}] [{level}] {message}")
|
|
||||||
else:
|
|
||||||
print(f"[{level}] {message}")
|
|
||||||
else:
|
else:
|
||||||
if log_filter_text:
|
if log_filter_text:
|
||||||
print(f"(no latest-run mpv logs found matching '{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}")
|
debug(f"Could not fetch database logs: {e}")
|
||||||
pass
|
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: <no focused entries match filter '{log_filter_text}'>")
|
||||||
|
else:
|
||||||
|
print("MPV core log: <no focused entries>")
|
||||||
|
|
||||||
fallback_logs = [
|
fallback_logs = [
|
||||||
("Medeia Lua log file tail", str(_lua_log_file())),
|
("Medeia Lua log file tail", str(_lua_log_file())),
|
||||||
("Medeia helper log file tail", str(_helper_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)
|
lines = _tail_text_file(path, max_lines=120)
|
||||||
except Exception:
|
except Exception:
|
||||||
lines = []
|
lines = []
|
||||||
lines = _apply_log_filter(lines, log_filter_text)
|
lines = _collapse_repeated_log_lines(_apply_log_filter(lines, log_filter_text))
|
||||||
if not lines:
|
if not lines:
|
||||||
continue
|
continue
|
||||||
print(f"{title}:")
|
print(f"{title}:")
|
||||||
@@ -2481,7 +2555,7 @@ def _start_mpv(
|
|||||||
mpv_log_path = (start_opts or {}).get("mpv_log_path")
|
mpv_log_path = (start_opts or {}).get("mpv_log_path")
|
||||||
if isinstance(mpv_log_path, str) and mpv_log_path.strip():
|
if isinstance(mpv_log_path, str) and mpv_log_path.strip():
|
||||||
extra_args.append(f"--log-file={mpv_log_path}")
|
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.
|
# Always start MPV with the bundled Lua script via MPV class.
|
||||||
mpv.start(
|
mpv.start(
|
||||||
|
|||||||
Reference in New Issue
Block a user