MPV:获取window位置和大小?还是 window-moved/resized 事件?

MPV: Get window position and size? Or window-moved/resized event?

有没有办法获取 MPV 媒体播放器 window 的当前位置和大小(或更改时触发的事件)?


我正在尝试制作一个脚本,自动保存 window 的最后位置,然后在播放器启动时加载它。 geometry可以设置启动时的位置,但是读取不行

在移动 windows 时记录在日志中:

[  34.308][d][vo/gpu/win32] move window: 1953:48

并调整大小:

[  37.990][v][vo/gpu] Resize: 1810x1004
[  37.990][v][vo/gpu] Window size: 1810x1004

有没有办法在 (javascript) 脚本中获取这些值或回调?遗憾的是我在文档中找不到该事件,还是我只是错过了它?

我能找到的只有 dwidthdheight,但它们仅代表视频的大小,而不是整个 window 或视频的位置。

谢谢!

注意:我也在 mpv's github 上问过这个问题,但还没有回复。当我在其中一个中得到回复时,我会更新另一个。

我找到了一种使用 mp.utils.subprocess 到 运行 一些 powershell 脚本的方法,因为 mpv 没有任何 API 可以直接获取位置。有点慢,但确实有效:

(ps1 脚本:)

Add-Type @"
using System;
using System.Runtime.InteropServices;
public class Window {
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
}
public struct RECT
{
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
}
"@

$Handle = (Get-Process -Id $Args[0]).MainWindowHandle
$WindowRect = New-Object RECT
$GotWindowRect = [Window]::GetWindowRect($Handle, [ref]$WindowRect)
ConvertTo-Json($WindowRect)

这将为您提供 json object,其位置和大小与 window 相同。然后您可以以类似的方式使用 SetWindowRect 再次设置位置。请注意,此矩形与您在 mpv 本身中使用 geometry 设置的内容不对应,因为此矩形还包括标题栏等。

编辑:

我做了一个更好的版本。

powershell 脚本现在获得 client-rect 可以与 geometry 一起使用,因此打开 mpv 现在更加顺畅。

所以新的 powershell 脚本:

Add-Type @"
using System;
using System.Runtime.InteropServices;
public class Window {
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool ClientToScreen(IntPtr hWnd, ref POINT lpPoint);
}
public struct RECT
{
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
}
public struct POINT
{
    public int x;
    public int y;
}
"@

$Handle = (Get-Process -Id $Args[0]).MainWindowHandle
$WindowRect = New-Object RECT
$ClientRect = New-Object RECT
$TopLeft = New-Object POINT
$BottomRight = New-Object POINT

[Window]::GetClientRect($Handle, [ref]$ClientRect) | out-null
$TopLeft.x = $ClientRect.Left
$TopLeft.y = $ClientRect.Top
$BottomRight.x = $ClientRect.Right
$BottomRight.y = $ClientRect.Bottom

[Window]::ClientToScreen($Handle, [ref]$TopLeft) | out-null
[Window]::ClientToScreen($Handle, [ref]$BottomRight) | out-null

$WindowRect.Left = $TopLeft.x
$WindowRect.Top = $TopLeft.y
$WindowRect.Right = $BottomRight.x
$WindowRect.Bottom = $BottomRight.y

ConvertTo-Json($WindowRect)

然后我有一个 javascript 插件在一个简单的 javascript 插件中调用这个 ps1:

// Some setup used by both reading and writing
var dir = mp.utils.split_path(mp.get_script_file())[0]
var rect_path = mp.utils.join_path(dir, "last_window_rect.txt")

// Read last window rect if present
try {
    var rect_json = mp.utils.read_file(rect_path)
    var rect = JSON.parse(rect_json)

    var width = rect.Right - rect.Left
    var height = rect.Bottom - rect.Top
    mp.set_property("screen", 0)
    mp.set_property("geometry", width + "x" + height + "+" + rect.Left + "+" + rect.Top)
}
catch (e) {
    dump(e)
}

// Save the rect at shutdown
function save_rect() {
    var ps1_script = mp.utils.join_path(dir, "Get-Client-Rect.ps1")
    var rect_json = mp.utils.subprocess({ args: ["powershell", "&(\"" + ps1_script + "\")", mp.utils.getpid()], cancellable: false }).stdout
    mp.utils.write_file("file://" + rect_path, rect_json)
}
mp.register_event("shutdown", save_rect)

您也可以在我的 github 上找到这些脚本:https://github.com/TheOddler/mpv-config/tree/master/scripts 但我不能保证它们会永远保持不变。