You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:13:40