2

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


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

在日志中,它会在窗口移动时记录:

[  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,但这些只代表视频的大小,而不是整个窗口,也不是它的位置。

谢谢!

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

4

1 回答 1

2

我想出了一种方法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 对象,该对象具有窗口的位置和大小。然后您可以使用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 插件中调用这个 ps1 的 javascript 插件:

// 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-co​​nfig/tree/master/scripts但我不能保证这些将永远保持不变。

于 2019-08-24T06:39:36.573 回答