簡介
webrtc的modules中有一個模塊desktop_capture,該模塊負責截屏,目前只支持windows和mac平臺,android,ios沒有實現。
desktop_capture中有兩種截屏方式,第一種是截單個窗口,叫做WindowCapturer,
第二種是截整個屏幕,叫做ScreenCapturer。
window_capture/screen_capture都繼承于基類DesktopCapturer:
// Abstract interface for screen and window capturers.
class DesktopCapturer {
public:
//初始化截屏,設置數據回調
virtual void Start(Callback* callback) = 0;
//截一張圖,數據直接進入callback
virtual void Capture(const DesktopRegion& region) = 0;
};
一、WindowCapture
WindowCapture主要增加了獲取窗口列表,和設置截屏窗口id的接口:
virtual bool GetWindowList(WindowList* windows);
virtual bool SelectWindow(WindowId id);
二、ScreenCapture
ScreenCapture主要增加了獲取屏幕列表,和設置截屏屏幕id的接口:
virtual bool GetScreenList(ScreenList* screens);
virtual bool SelectScreen(ScreenId id);
三、使用流程
接口都比較簡單,很容易使用,大概的流程如下:
- 創建對象
- 初始化截屏,設置回調函數
- 開啟線程循環截圖
screen_capture_ = webrtc::ScreenCapturer::Create(webrtc::DesktopCaptureOptions::CreateDefault());
screen_capture_->SelectScreen(0);
bool ImageCaptureThreadFunc(void* param)
{
webrtc::DesktopCapturer* capture = static_cast<webrtc::DesktopCapturer*>(param);
capture->Capture(webrtc::DesktopRegion(webrtc::DesktopRect()));
Sleep(100);
return true;
}
四、截屏數據處理
截屏后得到的數據格式是rgb,需要使用libyuv將數據從rgb轉換為yuv420,然后傳入編碼器和進行本地渲染。
轉換時注意填寫正確的原始數據類型,windows下格式為webrtc::kARGB
void OnCaptureCompleted(webrtc::DesktopFrame* frame) {
if (frame == NULL) {
//error,stop capture
StopImageCapture();
return;
}
int width = frame->size().width();
int height = frame->size().height();
int half_width = (width + 1) / 2;
webrtc::VideoFrame i420frame;
i420frame.CreateEmptyFrame(width, height, width, half_width, half_width);
int ret = webrtc::ConvertToI420(webrtc::kARGB, frame->data(), 0, 0, width, height, 4, webrtc::kVideoRotation_0, &i420frame);
if (ret != 0) {
return;
}
//后續處理
OnIncomingCapturedFrame(0, i420frame);
//需要釋放內存
delete frame;
}
五、傳遞給videoSendStream
通過VideoSendStream的input接口可以把采集到的圖像投遞進去,編碼發送。
video_stream_s_->Input()->IncomingCapturedFrame(videoFrame);