【问题标题】:MPV: Get window position and size? Or window-moved/resized event?MPV:获取窗口位置和大小?还是窗口移动/调整大小的事件?
【发布时间】:2019-12-24 12:17:24
【问题描述】:

有没有办法获取 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's github上问过这个问题,但还没有回复。当我得到回复时,我会更新另一个。

【问题讨论】:

    标签: mpv


    【解决方案1】:

    我想出了一种使用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,但我不能保证这些脚本会永远保持不变。

    【讨论】:

    • 您能找到窗口移动/调整大小事件吗?
    • 这是前一阵子,但我想我只是在关闭mpv时保存了一次位置,并在打开它时加载了它。所以我不使用移动/调整大小事件。虽然查看[Window]::GetClientRect 的文档,但您可能可以在那里使用一些东西。
    • 我在 Ubuntu 中需要这个功能。
    猜你喜欢
    • 1970-01-01
    • 2014-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-13
    • 2017-04-26
    相关资源
    最近更新 更多