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.subprocessmpv には位置を直接取得するための API がないため、powershell スクリプトを実行する方法を見つけました。少し遅いですが、動作します:

(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その後、同様の方法で を使用して、位置を再度設定できます。geometryこの四角形はタイトルバーなども含むため、mpv 自体で設定するものとは対応していないことに注意してください。

編集:

より良いバージョンを作りました。

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 に答える