在上一章,我们已经实现了一对一音视频对话功能。在实际应用中,我们常需要把自己的电脑桌面分享给他人以实现桌面共享功能,这种功能在视频会议、在线教学等场景中很常见,这种功能如何实现呢?这节课我们就来解决这个问题。
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.调试运行,如能正常发送和播放桌面流则表示成功。