如何将FFPlay窗口定位到屏幕指定坐标位置
问题原因
- 固定等待100ms的逻辑不可靠:ffplay启动后需要先完成流媒体拉流初始化、SDL渲染环境创建流程,才会弹出实际的播放窗口。等待100ms时窗口还未完成创建,此时拿到的
MainWindowHandle要么是空值,要么是进程启动的临时占位句柄,调用MoveWindow自然不会生效。 - 句柄获取逻辑错误:ffplay的播放窗口是SDL库创建的独立渲染窗口,不是进程启动时的初始主窗口,直接读取进程启动瞬间的
MainWindowHandle属性,大概率抓不到实际承载播放内容的窗口。
解决方案
方案1:直接使用ffplay原生启动参数(推荐)
你之前翻文档没找到位置配置项,是因为相关参数归类在视频输出选项下,没有和宽高配置放在同一块主选项区域。ffplay本身内置了窗口位置配置参数,属于SDL渲染层的原生透传配置,不需要额外写Win32调用逻辑,兼容性最好:
-left <数值>:指定窗口距离屏幕左侧的像素坐标-top <数值>:指定窗口距离屏幕顶部的像素坐标
举个例子,要把窗口放到200×400的坐标位置,直接修改启动参数即可:
ffplay -left 200 -top 400 udp://@127.0.0.1:5004?pkt_size=1316
使用这个方案不会出现窗口移动后被渲染层重置位置的问题,是最稳定的实现方式。
方案2:修正C#代码动态移动窗口
如果需要在ffplay启动后动态调整窗口位置,可以把原来固定等待+直接读取初始句柄的逻辑改成轮询校验窗口特征,找到真实的SDL播放窗口后再调用移动接口,修正后的代码如下:
using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; using System.Text; class Program { [DllImport("user32.dll", SetLastError = true)] internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); static void Main(string[] args) { Process process = new Process(); process.StartInfo.WindowStyle = ProcessWindowStyle.Normal; process.StartInfo.FileName = "C:\\ffmpeg\\x64\\ffplay.exe"; process.StartInfo.Arguments = "udp://@127.0.0.1:5004?pkt_size=1316"; process.Start(); IntPtr playWindowHandle = IntPtr.Zero; // 最多等待3秒查找窗口,避免死循环 for (int i = 0; i < 30; i++) { process.Refresh(); if (process.MainWindowHandle != IntPtr.Zero) { // ffplay的SDL播放窗口类名固定为"SDL_app",用这个特征精准定位窗口 StringBuilder classNameBuilder = new StringBuilder(256); GetClassName(process.MainWindowHandle, classNameBuilder, classNameBuilder.Capacity); if (classNameBuilder.ToString() == "SDL_app") { playWindowHandle = process.MainWindowHandle; break; } } Thread.Sleep(100); } if (playWindowHandle != IntPtr.Zero) { // 移动到指定坐标,同时设置窗口大小为500×500 MoveWindow(playWindowHandle, 0, 0, 500, 500, true); } else { Console.WriteLine("未找到ffplay播放窗口"); } Console.Read(); } }
内容的提问来源于stack exchange,提问作者bill
相关产品推荐
相关产品推荐

