gpt4 book ai didi

c++ - 如果设置了 processthreadsapi::STARTUPINFO::hStdError,则 fileapi::WriteFile() 不发送输入 (ffmpeg)

转载 作者:行者123 更新时间:2023-12-04 23:01:40 24 4
gpt4 key购买 nike

我正在尝试使用 ffmpeg 捕获我的屏幕在另一个线程中(我使用 processthreadsapi::CreateProcess()) 创建,因此我可以在主线程中执行其他操作,并重定向 ffmpeg 输出,因此它不会在控制台中弹出供用户查看。为了停止拍摄,我使用 WriteFile() 发送一个“q”输入,然后我想使用 ffmpeg 保存 ReadFile() 累积输出。
但是,如果我设置 STARTUPINFO::hStdError (注意,ffmpeg 输出到 stderr )到一个管道,我可以从中读取累积的数据,我使用 WriteFile() 发送的输入不再注册并且 ffmpeg.exe 继续运行。
我试过重定向 ffmpeg在一个简单的命令行中输出,但我仍然可以通过按 q 按钮来停止该过程。
此外,如果我录制的时间少于 8 秒,则输入已注册,ffmpeg.exe关闭。
我的代码有问题,还是 processthreadsapi 问题,任何提示都将不胜感激!
这是我尝试执行此操作的最小代码:


#include <iostream>

#include <conio.h>
#include <windows.h>

using namespace std;

HANDLE g_hChildStd_IN_Rd = NULL;
HANDLE g_hChildStd_IN_Wr = NULL;
HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL;

int main()
{
//Create IN and OUT pipes
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.lpSecurityDescriptor = NULL;


if (! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) )
cout<<"StdoutRd CreatePipe error"<<endl;

if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0) )
cout<<"Stdin CreatePipe error"<<endl;


PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;

ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );

siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = g_hChildStd_OUT_Wr;
siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
siStartInfo.hStdInput = g_hChildStd_IN_Rd;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;


//Start recording
if(!CreateProcess(NULL,
"ffmpeg -y -f gdigrab -framerate 2 -i desktop record.avi", // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo)) // receives PROCESS_INFORMATION
{
cout<<"Error create process"<<endl;
}
else
{
cout<<"Process created successfully"<<endl;
cout<<"Press k to stop recording"<<endl;
}

//Record for a while
while(getch() != 'k'){
cout<<"While press k"<<endl;
};

cout<<"Stop recording called"<<endl;

//Stop recording by emulating a Q button push
DWORD dwWritten;
CHAR chBufW[1] = {'q'};

if ( ! WriteFile(g_hChildStd_IN_Wr, chBufW, 1, &dwWritten, NULL) )
cout<<"Error write file"<<endl;

//Save stdError (ffmpeg) data
DWORD dwRead;
char stdErrorData[4096];
bool bSuccess;

bSuccess = ReadFile( g_hChildStd_OUT_Wr, stdErrorData, 4096, &dwRead, NULL);

if(!bSuccess || dwRead == 0)
cout<<"Read failed"<<endl;
else{
cout<<"Read success"<<endl;
}

cout<<"Press to exit"<<endl;
while(getch() != 'k');
return 0;
}

最佳答案

为了回答我自己的问题,问题是当 ffmpeg 输出将要到达的句柄管道填满时,它会停止 ffmpeg 进程,直到我为新文本腾出一些空间。这种情况正在发生,因为 ffmpeg 不断输出录音信息。
我希望这对某人有用:)

关于c++ - 如果设置了 processthreadsapi::STARTUPINFO::hStdError,则 fileapi::WriteFile() 不发送输入 (ffmpeg),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66686991/

24 4 0