第11课 利用windows API捕获桌面图像并通过FFmpeg分享
2024-01-08 08:30:37
在上一章,我们已经实现了一对一音视频对话功能。在实际应用中,我们常需要把自己的电脑桌面分享给他人以实现桌面共享功能,这种功能在视频会议、在线教学等场景中很常见,这种功能如何实现呢?这节课我们就来解决这个问题。
1.备份demo9并修改demo9为demo11。
2.在fmle.cpp的init函数中添加捕获屏幕的线程:
//capCamHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)capCamThread, (LPVOID)this, 0, NULL);
capScrHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)capScrThread, (LPVOID)this, 0, NULL);
3.添加捕获桌面的功能:
cv::Mat hwndToMat(HWND hwnd)
{
HDC hwindowDC, hwindowCompatibleDC;
int height, width, srcheight, srcwidth;
HBITMAP hbwindow;
cv::Mat src;
BITMAPINFOHEADER bi;
hwindowDC = GetDC(hwnd);
hwindowCompatibleDC = CreateCompatibleDC(hwindowDC);
SetStretchBltMode(hwindowCompatibleDC, COLORONCOLOR);
RECT windowsize;
GetClientRect(hwnd, &windowsize);
srcheight = windowsize.bottom;
srcwidth = windowsize.right;
height = windowsize.bottom;
width = windowsize.right;
src.create(height, width, CV_8UC4);
hbwindow = CreateCompatibleBitmap(hwindowDC, width, height);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = width;
bi.biHeight = -height;
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
SelectObject(hwindowCompatibleDC, hbwindow);
StretchBlt(hwindowCompatibleDC, 0, 0, width, height, hwindowDC, 0, 0, srcwidth, srcheight, SRCCOPY | CAPTUREBLT);
GetDIBits(hwindowCompatibleDC, hbwindow, 0, height, src.data, (BITMAPINFO *)&bi, DIB_RGB_COLORS);
DeleteObject(hbwindow); DeleteDC(hwindowCompatibleDC); ReleaseDC(hwnd, hwindowDC);
return src;
}
int fmle::capScr(){
HWND hwnd = GetDesktopWindow();
cv::Mat scrMat;
while (true)
{
scrMat = hwndToMat(hwnd);
if (scrMat.cols != backWidth || scrMat.rows != backHeight){
resize(scrMat, scrMat, cv::Size(backWidth, backHeight));
}
if (scrMat.data&&!scrMat.empty()){
cvtColor(scrMat, scrMat, CV_BGRA2BGR);
mainDlg->drawMatOfPub(scrMat);
EnterCriticalSection(&videoQueLock);
tmpVideoQueObj.type = 1;
tmpVideoQueObj.tmpMat = scrMat;
tmpVideoQueObj.dataLen = scrMat.cols*scrMat.rows * 3;
inVideoQue.push(tmpVideoQueObj);
if (inVideoQue.size() >videoDataArrNum){
inVideoQue.front().dataLen = 0;
inVideoQue.front().tmpMat.release();
inVideoQue.front().dataLen = NULL;
inVideoQue.pop();
}
LeaveCriticalSection(&videoQueLock);
}
Sleep(40);
}
scrMat.release();
return 0;
}
4.调试运行,如能正常发送和播放桌面流则表示成功。
文章来源:https://blog.csdn.net/XiBuQiuChong/article/details/135395907
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!