MFC实现ffmpeg流媒体数据推送与接收(2.推流)
上篇:MFC实现ffmpeg流媒体数据推送与接收(1.获取设备)
上篇我们获取到了我们要推流的设备名称。接下来我们就通过ffmpeg.exe推送rtmp到nginx服务器。
这是我们用到的命令:
桌面:ffmpeg -f gdigrab -i desktop -vcodec libx264 -r 15 -preset ultrafast -tune zerolatency -b 800000 -f flv rtmp://127.0.0.1:1935/live/desktop
视频:ffmpeg.exe -f dshow -i video=设备名 -vcodec libx264 -r 15 -preset ultrafast -tune zerolatency -b 250000 -f flv rtmp://127.0.0.1:1935/live/video
语音:ffmpeg.exe -f dshow -i audio=设备名 -acodec mp3 -f gdigrab -video_size 1x1 -i desktop -vcodec libx264 -r 15 -preset:v ultrafast -tune:v zerolatency -b 200000 -f flv rtmp://127.0.0.1:1935/live/audio
这里只解释几项,使用-b为了控制网络传输速度。语音项加入了1x1桌面解决语音接收问题,不使用摄像头跟语音结合为了保证不存在摄像头的情况。接下来我们通过线程启动ffmpeg进程来推流。我们使用匿名管道重定向实时检测ffmpeg.exe的动态信息。这里我只贴桌面的代码,其他代码类似,后面提供源码下载。
//启动进程发送远程桌面
CString strLine =_T("ffmpeg -f gdigrab -i desktop -vcodec libx264 -r 15 -preset ultrafast -tune zerolatency -b 800000 -f flv rtmp://127.0.0.1:1935/live/desktop");
//匿名管道重定向movescu.exe
SECURITY_ATTRIBUTES sa;
HANDLE hRead,hWrite;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if (!CreatePipe(&hRead,&hWrite,&sa,0))
{
return false;
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = hWrite;
si.hStdOutput = hWrite;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
CString SCU = _T("ffmpeg.exe");
if (!CreateProcess(SCU,strLine.GetBuffer()
,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))
{
return false;
}
m_DesktopWindowPI = pi;
CloseHandle(hWrite);
char buffer[1024] = {0};
DWORD bytesRead;
while(true)
{
if(m_bThreadDesktopWindowClose||(ReadFile(hRead,buffer,1023,&bytesRead,NULL) == NULL))
break;
}
至此我们就实现了设备数据流的推送。关于线程这块也不做解释,想必这块也没什么问题。可以使用ffplay进行分别测试:ffplay rtmp://127.0.0.1:1935/live/desktop ffplay rtmp://127.0.0.1:1935/live/video ffplay rtmp://127.0.0.1:1935/live/audio,由于加入-b会有清晰度的下降,流量的下降。至于延迟问题会在接下来的章节解决。以下提供源码下载:
源代码:http://download.csdn.net/detail/u011736517/9926025