You need to enable JavaScript to run this app.
导航
PC 端屏幕共享
最近更新时间:2023.08.28 12:05:25首次发布时间:2021.07.18 15:07:10

在实时通信中,如果你希望用户可以分享本端设备的屏幕和设备播放的音频,可以使用 RTC 内建的屏幕采集功能,也可以自行实现屏幕采集逻辑(自定义采集),并通过屏幕共享功能,与远端用户共享。

仅可见的用户可以发布屏幕流。

适用场景

你可以在多种行业的多种场景下使用到屏幕共享功能:

行业场景
在线教育老师共享屏幕给学生上课;美术老师共享屏幕给学生教画画。
游戏直播主播共享屏幕给观众,展现自己的游戏画面。
互动直播主播共享自己的屏幕和观众互动。
视频会议会议成员共享屏幕观看 PPT 或者文档。

前提条件

  • 操作系统版本要求如下:
    • Windows 7+
    • MacOS 10.8+
    • Linux
  • 你已经在 Windows/macOS/Linux 端上集成了 RTC SDK,并实现了基本的音视频通话

对于 Linux 系统,你需要判断其显示协议使用的是 X11 协议还是 Wayland 协议。如果是 X11 协议,你可以使用 资源获取 中的 Linux SDK;如果是 Wayland 协议,你需要联系技术支持人员,获取对应版本的 Linux SDK。要判断系统使用的协议,可以在系统命令行中运行以下命令:echo $XDG_SESSION_TYPE

功能实现

使用 RTC SDK 内部采集模块采集屏幕音视频流

API 调用的逻辑如下图:

API flow

图中以 Windows SDK 为例。不同的系统有一些差异。

预览可选共享对象

对使用 Wayland 协议的 Linux 系统,SDK 无法获取可选共享对象信息。当用户调用 SDK API 发起屏幕共享时,系统会显示弹窗,展示可选共享对象的相关信息:

  • 屏幕名称;
  • 窗口名称,窗口对应的应用名称,窗口的应用图标。

对 Windows 系统或使用 X11 协议的 Linux 系统,调用以下接口,以便用户在发起共享前,看到可以共享的屏幕/窗口的缩略图等信息,并指定共享对象。

  1. 调用 getScreenCaptureSourceList 接口获取共享对象列表:
    • 应用窗体:kScreenCaptureSourceTypeWindow
    • 显示器屏幕:kScreenCaptureSourceTypeScreen。 Windows 端的虚拟桌面的 source_id-1

ScreenCaptureSourceInfo 中的 region_rect 为采集源的坐标,在以主屏左上角为原点的坐标系下,的采集源的逻辑坐标和分辨率信息

  1. 调用 getThumbnail 接口获取共享对象缩略图,并支持设置宽、高。
    如果采集源为应用窗体,还可以通过 getWindowAppIcon 获取应用图标。
    • 缩略图尺寸:保持采集对象本身的宽高比不变,将缩略图缩放到指定范围内的最大宽高。
    • 应用图标尺寸:将应用图标按照指定的边长进行缩放,始终为正方形。
void AppBusiLogic::SDKGetAppIconAndShow(bool show, int width, int height) {
    if (!show && mAppIconView) {
        mAppIconView->hide();
    } else if (show) {
        bytertc::ScreenCaptureSourceInfo info = mCurScreenSourceInfo;
        bytertc::IVideoFrame* videoFrame = mByteEngineWrapper->GetWindowAppIcon(info.source_id, width, height);
        if (info.type != bytertc::kScreenCaptureSourceTypeWindow || !videoFrame) {
            ToastForm::toast(TEXT("获取应用图标失败"), 2000, ToastForm::TipsToast,
                             WindowMgr::GetInstance().Find(WindowMgr::RTC_CALL_SETTTING));
            return;
        }

        QImage image;
        if (videoFrame->pixelFormat() == bytertc::kVideoPixelFormatRGBA) {
            image = QImage(videoFrame->getPlaneData(0), videoFrame->width(),
                videoFrame->height(), QImage::Format_RGBA8888);
        } else if (videoFrame->pixelFormat() == bytertc::kVideoPixelFormatARGB) {
            image = QImage(videoFrame->getPlaneData(0), videoFrame->width(),
                videoFrame->height(), QImage::Format_ARGB32);
        }

        if (!mAppIconView) {
            mAppIconView = new PixmapButton();
            auto settingWdg = WindowMgr::GetInstance().Find(WindowMgr::RTC_CALL_SETTTING);
            mAppIconView->move(settingWdg->x(), 0);
        }
        QString title = QString::number(videoFrame->width()) + "x" + QString::number(videoFrame->height());
        mAppIconView->setWindowTitle(title);
        mAppIconView->makePixmapBtn(QPixmap::fromImage(image));
        mAppIconView->setMinimumSize(200, 200);
        mAppIconView->show();

        videoFrame->release();
    }

开启设备屏幕视频采集

  1. (可选)设置屏幕视频流的采集帧率和编码分辨率

调用 setScreenVideoEncoderConfig 进行设置:

  • 当共享对象原始分辨率超过目标宽、高时,将保持视频帧宽高比,缩小到目标宽、高。
  • 当共享对象分辨率小于目标宽高时,将保持原始宽高,不进行“放大”。
  1. 调用 startScreenVideoCapture 开启屏幕采集
  • 对使用 Wayland 协议的 Linux 系统,开启屏幕采集时,系统自动弹窗显示相关信息,供用户选择共享的屏幕或窗口。边框高亮和窗口排除功能无法使用。
  • 对 Windows 和使用 X11 协议的 Linux 系统,ScreenCaptureParameters 对象中的 HighlightConfig 参数为共享的屏幕/窗口添加边框标志,用来向用户提示此窗口正在被共享。RTC 建议在屏幕共享时排除应用程序自身窗口。你可以通过设置 ScreenFilterConfig 参数排除指定窗口。

开启设备音频采集

设备音频默认为一路单独的音频流完成处理和发布。调用 setScreenAudioStreamIndex 可以将设备音频混入到主流的音频中。

  • Windows:调用接口 startScreenAudioCapture 开启屏幕音频采集,即声卡播放出来的声音。

  • Mac:v3.43.1 及以上版本 SDK 支持在 Mac 端共享设备音频。
    1. 安装虚拟声卡。推荐安装由 RTC 提供的 VeRTCVirtualSoundCard
    2. 调用接口 getDevice获取虚拟声卡设备 ID。
    3. 调用带参接口 startScreenAudioCapture 传入虚拟声卡设备 ID,开启设备音频采集。

  • Linux:暂不支持设备音频采集。

更新屏幕共享配置

开始发布屏幕流后,可以通过以下接口更新屏幕采集设置。

以下接口可以在 Windows 和各种 Linux 系统下使用:

  • 调用 updateScreenCaptureRegion 更新采集区域。如果要更新共享的屏幕/窗口,你需要重新发起共享。
  • 调用 updateScreenCaptureMouseCursor 更新是否采集鼠标信息的设置。

以下接口仅能在 Windows 和 Linux with X11 系统下使用:

  • 调用 updateScreenCaptureHighlightConfig 更新边框高亮设置。
  • 调用 updateScreenCaptureFilterConfig 更新需要过滤的窗口。

自定义采集屏幕

RTC 强烈建议你使用内部采集。如果你仍然希望使用自定义采集,参看以下步骤。

  1. 实现屏幕音视频流采集逻辑。
  2. 调用 setScreenAudioSourceTypesetVideoSourceType 设置屏幕音视频自定义采集。
  3. 调用 pushScreenAudioFramepushScreenVideoFrame 将采集得到的音视频帧推送到 RTC SDK 用于编码传输。

发布/停止发布屏幕共享流

  • 开始屏幕音视频采集后,调用 publishScreen 发布屏幕共享流。
    发布方式有三种:只发布音频、只发布视频、同时发布音视频。
  • 调用 unpublishScreen 关闭屏幕共享。

调用一次 publishScreen 同时发布音视频与多次调用该接口,分别只发布音频、只发布视频结果是相同的。

接收屏幕音视频

远端用户发布屏幕音视频流后,RTC 通过 onUserPublishScreen 通知本地用户。通过 subscribeScreen 手动订阅屏幕音视频流。订阅后,屏幕音频流即可正常播放。

如果已经在进房时开启自动订阅,则无需进行手动订阅。

屏幕视频流正常解码后收到 onFirstRemoteVideoFrameDecoded 首帧解码回调,并通过 setRemoteVideoSink 或者 setRemoteVideoCanvas 将屏幕视频渲染出来。

API 参考

以下是各个平台的相关API参考:

WindowsmacOSLinux with X11Linux with Wayland
获取共享对象getScreenCaptureSourceListgetScreenCaptureSourceListgetScreenCaptureSourceListX
获取共享对象缩略图getThumbnailgetThumbnail:sourceId:maxWidth:maxHeight:getThumbnailX
获取共享窗体程序图标getWindowAppIcongetWindowAppIcongetWindowAppIconX
设置屏幕流编码属性setScreenVideoEncoderConfigsetScreenVideoEncoderConfig:setScreenVideoEncoderConfig同左侧
开始屏幕采集startScreenVideoCapturestartScreenVideoCapture:captureParameters:startScreenVideoCapture同左侧
开始设备音频采集startScreenAudioCapturestartScreenAudioCapture:XX
更新采集区域updateScreenCaptureRegionupdateScreenCaptureRegion:updateScreenCaptureRegion同左侧
更新高亮控制项updateScreenCaptureHighlightConfigupdateScreenCaptureHighlightConfig:updateScreenCaptureHighlightConfigX
更新过滤选项updateScreenCaptureFilterConfigupdateScreenCaptureFilterConfig:XX
更新鼠标捕获选项updateScreenCaptureMouseCursorupdateScreenCaptureMouseCursor:updateScreenCaptureMouseCursor同左侧
发布屏幕流publishScreenpublishScreen:publishScreen同左侧
停止发布屏幕流unpublishScreenunpublishScreen:unpublishScreen同左侧
切换外部屏幕采集setScreenAudioSourceTypesetScreenAudioSourceType:XX
推送自定义设备音频采集数据pushScreenAudioFramepushScreenAudioFrame:XX
推送自定义屏幕采集数据pushScreenVideoFramepushScreenVideoFrame:time:rotation:pushScreenVideoFrame同左侧

已知问题

部分 Windows 7 设备在屏幕共享过程中,如果使用媒体播放器播放视频,例如, Windows 自带播放器或 QuickTime,远端无法在画面中看到正在播放的视频。

功能变更历史记录

本文最近更新时的 SDK 版本为 3.50.1。如果你使用的 SDK 为之前版本,请查看以下变动,并进行相应适配。

  • 3.50.3 版本

    • 设置共享流的编码参数类型名称变更为 ScreenVideoEncoderConfig
    • 自定义屏幕流相关的接口名称和行为有变更。
    • macOS 端获取共享对象缩略图的接口名称由 getScreenCaptureSourceThumbnail:sourceId:maxWidth:maxHeight: 变更为 getThumbnail:sourceId:maxWidth:maxHeight:
    • macOS 端开启屏幕采集接口名称由 startScreenCaptureSourceInfo:captureParameters: 变更为 startScreenVideoCapture:captureParameters:
  • 3.43.1 版本中

    平台macOSWindowsLinux
    APIpublishScreen:unpublishScreen: 的类名由 ByteRTCEngineKit 变更为 RTCRoom。其他方法的类名变更为 RTCVideopublishScreenunpublishScreen 的类名由 IRtcEngine 变更为 IRTCRoom。其他方法的类名由 IRtcEngine 变更为 IRTCVideopublishScreenunpublishScreen 的类名由 IRtcEngine 变更为 IRTCRoom。其他方法的类名由 IRtcEngine 变更为 IRTCVideo
    回调回调类名由 ByteRTCEngineDelegate 变更为 RTCVideoDelegate回调类名由 IRtcEngineEventHandler 变更为 IRTCVideoEventHandler回调类名由 IRtcEngineEventHandler 变更为 IRTCVideoEventHandler
  • 3.42.1 版本,Windows 和 Linux 端所有 API 和回调命名风格由大驼峰更改为小驼峰

  • 3.36.1 版本

    • 设置共享流的编码参数方法由 SetVideoEncoderConfig 变更为 SetScreenVideoEncoderConfig
    • publishScreen 等 API 的参数有变更。