WebRTC 屏幕分享深度解析

前言

今天突然发现自己对 WebRTC 的屏幕分享的底层工作原理有一个误解,之前,我一直以为屏幕分享就是简单的采集桌面的画面,然后编码发送就行了。实时上并不是如此简单,本文就来为大家揭秘。

正文

一、想当然的认知

在正式开始前,我先问大家一个问题:在屏幕分享的时候,鼠标是不是桌面画面的一部分?答案是肯定的!但是,实际上采集的时候并不是我们认为的那样!采集屏幕的时候不会自动把鼠标也采集上!

二、揭开真相

WebRTC 在进行屏幕分享画面的采集时,屏幕画面和鼠标分别采集的。其中,屏幕画面可能是桌面窗口或者应用程序窗口,鼠标的话,还包括光标形状和光标位置信息。整体关系的示意图如下:

图片

实际上在进行屏幕采集时是可以选择是否包含鼠标的,只是一般情况下都默认包含鼠标。 先来看一下具体执行类的构造函数,代码如下:

DesktopAndCursorComposer::DesktopAndCursorComposer(
    std::unique_ptr<DesktopCapturer> desktop_capturer,
    const DesktopCaptureOptions& options)
    : DesktopAndCursorComposer(desktop_capturer.release(),
                               MouseCursorMonitor::Create(options).release()) {}

DesktopAndCursorComposer::DesktopAndCursorComposer(
    DesktopCapturer* desktop_capturer,
    MouseCursorMonitor* mouse_monitor)
    : desktop_capturer_(desktop_capturer), mouse_monitor_(mouse_monitor) {
  RTC_DCHECK(desktop_capturer_);
}

然后就是启动桌面采集时和执行桌面采集时的代码逻辑区分,如果设置了mouse_monitor,才进行鼠标的捕捉,代码如下:

void DesktopAndCursorComposer::Start(DesktopCapturer::Callback* callback) {
  callback_ = callback;
  if (mouse_monitor_)
    mouse_monitor_->Init(this, MouseCursorMonitor::SHAPE_AND_POSITION);
  desktop_capturer_->Start(this);
}

void DesktopAndCursorComposer::CaptureFrame() {
  if (mouse_monitor_)
    mouse_monitor_->Capture();
  desktop_capturer_->CaptureFrame();
}

三、屏幕采集流程

WebRTC 源码采集屏幕信息的过程如下图所示,其中包含了整个函数方法调用的全过程,涉及屏幕画面以及鼠标的相关内容(光标形状和位置)。

图片

有一点需要格外注意,DesktopAndCursorComposer类在决定多久采集一帧屏幕画面时,是根据如下公式算出来的:

每帧屏幕画面的采集时间间隔 = 1000 / 帧率(fps)

举个例子,如果设置的屏幕共享的帧率是 25fps,那么,每隔40毫秒(ms)就采集一帧屏幕画面。

作者简介: Data-Mining(liuzhen007),是一名典型的音视频技术爱好者,前后就职于传统广电巨头和音视频互联网公司,具有丰富的音视频直播和点播相关经验,对 WebRTC、FFmpeg 和 Electron 有非常深入的了解。同时也是 CSDN 博客专家(博客之星)、华为云享专家(共创编辑、十佳博主)、51CTO社区编辑、InfoQ 签约作者,欢迎关注我分享更多干货!

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

发表回复

登录后才能评论