You need to enable JavaScript to run this app.
导航
PC 端屏幕共享
最近更新时间:2025.11.10 17:12:09首次发布时间: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 内部采集模块采集屏幕音视频流

在 3.60 单路流版本中,存在如下变动:

  • createRTCVideo 接口已变更为 createRTCEngine
  • publishScreenunpublishScreen 接口已不存在。请使用 publishStreamVideopublishStreamAudio 控制是否发布音视频。如果您已经调用 startScreenCapture,那么设置 publishStreamVideo(true) 将会直接开始发布屏幕流。
  • 在屏幕准备好后,您会收到 onVideoDeviceStateChanged 回调。
  • onUserUnPublishScreen 回调已不存在。请使用 onUserPublishStreamVideo 回调替代。使用 streamInfo.isScreen 来判断是否为屏幕流。

API 调用的逻辑如下图:

图中以 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. (可选)设置屏幕视频流的采集帧率和编码分辨率

调用 setVideoEncoderConfig 进行设置:

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

开启设备音频采集

  • Windows:调用接口 startScreenAudioCapture 开启屏幕音频采集。参数 device_id 用于设置采集本地指定音频进程的音频。例如可将该参数设为某应用程序可执行文件的文件名(如 QQMusic.exe),此时 SDK 只会采集该应用程序的音频。传入 nullptr 或置空时即代表采集整个系统除本进程之外的所有应用程序的音频。当前,应用程序仅支持 QQ 音乐,网易云音乐,和酷狗音乐,采集其他进程可能会导致未知行为。

  • 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. 调用 pushScreenAudioFrame 将采集得到的音频帧推送到 RTC SDK 用于编码传输。

接收屏幕音视频

远端用户发布屏幕音视频流后,RTC 通过 onUserPublishStreamVideo 通知本地用户。请通过 subscribeStreamVideosubscribeStreamAudio 订阅音视频流,以确保屏幕共享开始后,屏幕音视频可以正常播放。

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

屏幕视频流正常解码后收到 onFirstRemoteVideoFrameDecoded 首帧解码回调。您可在此回调或 onUserPublishStreamVideo 回调中通过 setRemoteVideoSink 或者 setRemoteVideoCanvas 将屏幕视频渲染出来。建议您在 onFirstRemoteVideoFrameDecoded 回调中设置视频渲染,确保视频渲染在视频解码完成后进行,以避免卡顿。

API 参考

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

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

已知问题

部分 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 的参数有变更。