FFmpeg无疑是音视频界的翘首,很多企业或个人都会拿来使用,具体怎么使用,在此不做赘述。这里仅仅讲述如何用C++调用ffmpeg指令,以及调用的控制台窗口的正常关闭(录像或转码等情况下,非正常关闭,直接导致文件损坏,不可用)
一、指令的执行
STARTUPINFOEX si;
SECURITY_ATTRIBUTES sa;
memset(&pi, 0, sizeof(pi));
memset(&si, 0, sizeof(si));
memset(&sa, 0, sizeof(sa));
si.StartupInfo.cb = sizeof(STARTUPINFOEX);
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
si.StartupInfo.wShowWindow = SW_SHOW;// SW_HIDE;
si.StartupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
//这里ffmpeg.exe必须执行路径,否则创建进程失败,错误码为2
CString strCommandLine = _T("D:\\ffmpeg.exe -f gdigrab -i desktop -q:v 0.01 -vcodec mpeg4 -f mp4 D:\\out.mp4");
bRet = CreateProcess(NULL, (LPTSTR)(LPCTSTR)strCommandLine, NULL, NULL, FALSE/*TRUE*/, EXTENDED_STARTUPINFO_PRESENT/*CREATE_NEW_CONSOLE*/, NULL, NULL/*(LPTSTR)(LPCTSTR)sPath*/, (STARTUPINFO*)&si, &pi);
if (!bRet)
return ;
//到这里,进程就创建成功了
二、窗口的关闭
创建进程之后,我们能会获取到进程ID,然后根据进程ID查找窗口的句柄,之后给窗口发送WM_CLOSE消息就可以正常关闭控制台窗口了。
struct FfmpegStruct
{
HWND hFfmpegWnd;
DWORD dwProcessId;
};
DWORD FindProcessId(HWND hWnd)
{
DWORD dwProcessId = 0;
::GetWindowThreadProcessId(hWnd, &dwProcessId);
return dwProcessId;
}
BOOL CALLBACK EnumWindowProc(HWND hWnd, LPARAM lParam)
{
struct FfmpegStruct *pFfmpegStruct = reinterpret_cast<struct FfmpegStruct*>(lParam);
if (FindProcessId(hWnd) == pFfmpegStruct->dwProcessId) {
pFfmpegStruct->hFfmpegWnd = GetParent(hWnd);
return FALSE;
}
return TRUE;
}
struct FfmpegStruct ffmpegStruct = { 0, pi.dwProcessId };
EnumWindows(EnumWindowProc, (LPARAM)&ffmpegStruct);
::PostMessage(ffmpegStruct.hFfmpegWnd, WM_CLOSE, 0, 0);
WaitForSingleObject(pi.hProcess, INFINITE);