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

fileapi::WriteFile() doesn't send an input, if processthreadsapi::STARTUPINFO::hStdError is set (ffmpeg)

我正在尝试在另一个线程中使用 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 进程,直到我为新的清除一些 space要输入的文本。这正在发生,因为 ffmpeg 不断输出记录信息。

我希望这对某人有用:)