能否通过访问FFPlay.exe的STDIN模拟'q'按键实现退出?
问题分析与解决方案
你的管道方式理论上可行,但ffplay的输入处理逻辑和普通控制台程序不同,这是导致无响应的核心原因:
普通控制台程序会主动从标准输入(stdin)读取用户输入,但ffplay默认是通过Win32窗口消息循环直接监听键盘硬件事件,根本不会读取标准输入流——所以你往管道里写的'q',ffplay根本没在处理。
两种可行的解决方法
方法一:模拟键盘事件发送给ffplay窗口
直接给ffplay的主窗口发送按键消息,模拟手动按'q'的操作:
- 找到ffplay的窗口:ffplay基于SDL开发,窗口类名通常是
SDL_app,也可以根据播放的视频标题查找窗口 - 发送WM_KEYDOWN和WM_KEYUP消息模拟按键
示例代码:
#include <windows.h> // 查找ffplay窗口 HWND hFFPlayWnd = FindWindowA("SDL_app", NULL); if (hFFPlayWnd) { // 模拟按下'q'键 SendMessage(hFFPlayWnd, WM_KEYDOWN, 'Q', 0); // 模拟松开'q'键 SendMessage(hFFPlayWnd, WM_KEYUP, 'Q', 0); }
方法二:强制ffplay监听标准输入
ffplay提供了-stdin启动参数,开启后会主动读取标准输入流的命令。启动ffplay时加上这个参数,再通过管道发送'q'就能触发退出:
- 启动ffplay时添加参数:
STARTUPINFO si = {0}; si.cb = sizeof(STARTUPINFO); si.hStdInput = hPipeRead; // 子进程的stdin绑定管道读端 si.dwFlags |= STARTF_USESTDHANDLES; // 命令行加上-stdin参数 char szCmdLine[] = "ffplay.exe -stdin test.mp4"; PROCESS_INFORMATION pi = {0}; CreateProcessA(NULL, szCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
- 往管道写入'q'(注意要确保数据被推送,可调用
FlushFileBuffers):
char exitCmd = 'q'; DWORD dwWritten; WriteFile(hPipeWrite, &exitCmd, 1, &dwWritten, NULL); FlushFileBuffers(hPipeWrite);
补充说明
- 用其他控制台程序测试有效,是因为它们的输入逻辑就是读取标准输入,和ffplay的窗口消息驱动逻辑完全不同
- 如果需要更可靠的窗口查找,可以结合
EnumWindows遍历所有窗口,匹配ffplay的窗口标题或类名
内容的提问来源于stack exchange,提问作者couldabin
相关产品推荐
相关产品推荐

