是否可以获取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)脚本中获取这些值或回调?我很遗憾在文档中找不到该事件,或者只是想念它?
我只能找到dwidth
和dheight
,但是它们仅代表视频的大小,而不代表整个窗口或位置。
谢谢!
注意:我也在mpv's github上提出了此要求,但尚未回复。我会在任何一个回复时更新另一个。
答案 0 :(得分:0)
我想出了一种使用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
重新设置位置。请注意,此rect与您在mpv本身中用geometry
设置的内容不对应,因为该rect还包括标题栏等。
编辑:
我做了一个更好的版本。
现在,powershell脚本获得了可与geometry
一起使用的client-rect,因此现在打开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,但我不能保证它们会永远保持不变。