如何获取MPV播放器窗口位置、尺寸或窗口移动/Resize事件?
获取MPV窗口位置/尺寸及变更事件的实用方案
嘿,刚好我之前做过类似的窗口位置记忆脚本,给你几个按推荐程度排序的解决思路:
1. 直接利用MPV内置的window-geometry属性(最优方案)
MPV较新的版本(v0.34+)已经支持直接读取和设置窗口几何属性,这是最省心的方法:
- 读取当前窗口信息:执行
mp.get_property("window-geometry"),会返回类似1810x1004+1953+48的字符串(格式为宽x高+X坐标+Y坐标) - 监听变更事件:通过属性监听回调,窗口位置/尺寸变化时自动触发保存:
// 初始化变量存储当前几何信息 let currentGeom = mp.get_property("window-geometry"); // 监听属性变更 mp.observe_property("window-geometry", "string", (name, newGeom) => { if (newGeom !== currentGeom) { currentGeom = newGeom; // 保存到配置文件 saveGeometry(newGeom); } }); // 保存函数 function saveGeometry(geom) { const configPath = mp.utils.join_path(mp.utils.get_user_config_dir(), "mpv_window_geom.txt"); mp.utils.write_file(configPath, geom); } - 启动时加载:脚本初始化时读取保存的文件,设置窗口位置:
const configPath = mp.utils.join_path(mp.utils.get_user_config_dir(), "mpv_window_geom.txt"); if (mp.utils.file_info(configPath)) { const savedGeom = mp.utils.read_file(configPath).trim(); mp.set_property("window-geometry", savedGeom); }
2. 监听MPV日志输出(兼容旧版本)
如果你的MPV版本不支持window-geometry属性,可以利用你提到的日志信息,通过JS脚本监听日志事件提取数据:
// 存储当前窗口的位置和尺寸 let currentX, currentY, currentW, currentH; // 注册日志监听事件 mp.register_event("log-message", (event) => { const msg = event.text; // 解析窗口移动日志 if (msg.includes("[d][vo/gpu/win32] move window:")) { const posPart = msg.split("move window: ")[1]; [currentX, currentY] = posPart.split(":").map(Number); // 保存完整几何信息 saveGeometry(currentX, currentY, currentW, currentH); } // 解析窗口尺寸变更日志 if (msg.includes("[v][vo/gpu] Window size:")) { const sizePart = msg.split("Window size: ")[1]; [currentW, currentH] = sizePart.split("x").map(Number); // 保存完整几何信息 saveGeometry(currentX, currentY, currentW, currentH); } }); // 保存函数(格式转为MPV可识别的几何字符串) function saveGeometry(x, y, w, h) { if (x && y && w && h) { const geom = `${w}x${h}+${x}+${y}`; const configPath = mp.utils.join_path(mp.utils.get_user_config_dir(), "mpv_window_geom.txt"); mp.utils.write_file(configPath, geom); } }
注意:需要在mpv.conf里添加log-level=debug,确保能看到move window这类调试级别的日志。
3. 调用系统工具获取窗口信息(兜底方案)
如果上面两种方法都不行,可以通过系统级工具直接查询窗口属性,JS脚本里用mp.command_native执行命令并解析输出:
- Windows平台:用PowerShell调用Win32 API获取窗口矩形
function getWindowGeometry() { const cmd = [ "powershell", "-Command", 'Get-Process mpv | ForEach-Object { $_.MainWindowHandle } | ForEach-Object { Add-Type @"using System;using System.Runtime.InteropServices;public class Win32 {[DllImport("user32.dll")]public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);public struct RECT { public int Left, Top, Right, Bottom; }}"@; $rect = New-Object Win32.RECT; [Win32]::GetWindowRect($_, [ref]$rect); Write-Output "$($rect.Left),$($rect.Top),$($rect.Right-$rect.Left),$($rect.Bottom-$rect.Top)" }' ]; const result = mp.command_native({name: "subprocess", args: cmd, capture_stdout: true}); if (result.stdout) { const [x, y, w, h] = result.stdout.trim().split(",").map(Number); return `${w}x${h}+${x}+${y}`; } return null; } - Linux平台:用
xdotool工具(需先通过包管理器安装)function getWindowGeometry() { const winIdCmd = ["xdotool", "search", "--class", "mpv"]; const winIdResult = mp.command_native({name: "subprocess", args: winIdCmd, capture_stdout: true}); if (winIdResult.stdout) { const winId = winIdResult.stdout.trim(); const geomCmd = ["xdotool", "getwindowgeometry", winId]; const geomResult = mp.command_native({name: "subprocess", args: geomCmd, capture_stdout: true}); if (geomResult.stdout) { // 解析输出,提取几何信息 const geomMatch = geomResult.stdout.match(/Geometry: (\d+x\d+\+\d+\+\d+)/); return geomMatch ? geomMatch[1] : null; } } return null; } - macOS平台:用AppleScript
function getWindowGeometry() { const cmd = ["osascript", "-e", 'tell application "mpv" to get bounds of window 1']; const result = mp.command_native({name: "subprocess", args: cmd, capture_stdout: true}); if (result.stdout) { const [x, y, x2, y2] = result.stdout.trim().split(",").map(Number); const w = x2 - x; const h = y2 - y; return `${w}x${h}+${x}+${y}`; } return null; }
这种方法可以定时轮询(比如每500ms调用一次),对比之前的值判断窗口是否变更,然后触发保存。
内容的提问来源于stack exchange,提问作者The Oddler
相关产品推荐
相关产品推荐

