在实时通信中,如果你希望用户可以分享本端设备的屏幕和设备播放的音频,可以使用 RTC 内建的屏幕采集功能,也可以自行实现屏幕采集逻辑(自定义采集),并通过屏幕共享功能,与远端用户共享。
仅可见的用户可以发布屏幕流。
你可以在多种行业的多种场景下使用到屏幕共享功能:
| 行业 | 场景 |
|---|---|
| 在线教育 | 老师共享屏幕给学生上课;美术老师共享屏幕给学生教画画。 |
| 游戏直播 | 主播共享屏幕给观众,展现自己的游戏画面。 |
| 互动直播 | 主播共享自己的屏幕和观众互动。 |
| 视频会议 | 会议成员共享屏幕观看 PPT 或者文档。 |
对于 Linux 系统,你需要判断其显示协议使用的是 X11 协议还是 Wayland 协议。如果是 X11 协议,你可以使用 资源获取 中的 Linux SDK;如果是 Wayland 协议,你需要联系技术支持人员,获取对应版本的 Linux SDK。要判断系统使用的协议,可以在系统命令行中运行以下命令:
echo $XDG_SESSION_TYPE。
在 3.60 单路流版本中,存在如下变动:
createRTCVideo接口已变更为createRTCEngine。publishScreen和unpublishScreen接口已不存在。请使用publishStreamVideo和publishStreamAudio控制是否发布音视频。如果您已经调用startScreenCapture,那么设置publishStreamVideo(true)将会直接开始发布屏幕流。- 在屏幕准备好后,您会收到
onVideoDeviceStateChanged回调。onUserUnPublishScreen回调已不存在。请使用onUserPublishStreamVideo回调替代。使用streamInfo.isScreen来判断是否为屏幕流。
API 调用的逻辑如下图:

图中以 Windows SDK 为例。不同的系统有一些差异。
对使用 Wayland 协议的 Linux 系统,SDK 无法获取可选共享对象信息。当用户调用 SDK API 发起屏幕共享时,系统会显示弹窗,展示可选共享对象的相关信息:
对 Windows 系统或使用 X11 协议的 Linux 系统,调用以下接口,以便用户在发起共享前,看到可以共享的屏幕/窗口的缩略图等信息,并指定共享对象。
getScreenCaptureSourceList 接口获取共享对象列表:
kScreenCaptureSourceTypeWindowkScreenCaptureSourceTypeScreen。 Windows 端的虚拟桌面的 source_id 为 -1。
ScreenCaptureSourceInfo中的region_rect为采集源的坐标,在以主屏左上角为原点的坐标系下,的采集源的逻辑坐标和分辨率信息
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(); }
调用 setVideoEncoderConfig 进行设置:
startScreenVideoCapture 开启屏幕采集。如果您之前设置了 is_auto_publish_video = true,那么调用该接口后会直接开始发布屏幕流。否则,您需要调用 publishStreamVideo 方法来开始共享屏幕。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 强烈建议你使用内部采集。如果你仍然希望使用自定义采集,参看以下步骤。
setScreenAudioSourceType 和 setVideoSourceType 设置屏幕音视频自定义采集。pushScreenAudioFrame 将采集得到的音频帧推送到 RTC SDK 用于编码传输。远端用户发布屏幕音视频流后,RTC 通过 onUserPublishStreamVideo 通知本地用户。请通过 subscribeStreamVideo 和 subscribeStreamAudio 订阅音视频流,以确保屏幕共享开始后,屏幕音视频可以正常播放。
如果已经在进房时开启自动订阅,则无需进行手动订阅。
屏幕视频流正常解码后收到 onFirstRemoteVideoFrameDecoded 首帧解码回调。您可在此回调或 onUserPublishStreamVideo 回调中通过 setRemoteVideoSink 或者 setRemoteVideoCanvas 将屏幕视频渲染出来。建议您在 onFirstRemoteVideoFrameDecoded 回调中设置视频渲染,确保视频渲染在视频解码完成后进行,以避免卡顿。
以下是各个平台的相关API参考:
部分 Windows 7 设备在屏幕共享过程中,如果使用媒体播放器播放视频,例如, Windows 自带播放器或 QuickTime,远端无法在画面中看到正在播放的视频。
本文最近更新时的 SDK 版本为 3.50.1。如果你使用的 SDK 为之前版本,请查看以下变动,并进行相应适配。
3.50.3 版本
ScreenVideoEncoderConfig。getScreenCaptureSourceThumbnail:sourceId:maxWidth:maxHeight: 变更为 getThumbnail:sourceId:maxWidth:maxHeight:。startScreenCaptureSourceInfo:captureParameters: 变更为 startScreenVideoCapture:captureParameters: 。3.43.1 版本中
| 平台 | macOS | Windows | Linux |
|---|---|---|---|
| API | publishScreen: 和 unpublishScreen: 的类名由 ByteRTCEngineKit 变更为 RTCRoom。其他方法的类名变更为 RTCVideo。 | publishScreen 和 unpublishScreen 的类名由 IRtcEngine 变更为 IRTCRoom。其他方法的类名由 IRtcEngine 变更为 IRTCVideo。 | publishScreen 和 unpublishScreen 的类名由 IRtcEngine 变更为 IRTCRoom。其他方法的类名由 IRtcEngine 变更为 IRTCVideo。 |
| 回调 | 回调类名由 ByteRTCEngineDelegate 变更为 RTCVideoDelegate。 | 回调类名由 IRtcEngineEventHandler 变更为 IRTCVideoEventHandler。 | 回调类名由 IRtcEngineEventHandler 变更为 IRTCVideoEventHandler。 |
3.42.1 版本,Windows 和 Linux 端所有 API 和回调命名风格由大驼峰更改为小驼峰
3.36.1 版本
SetVideoEncoderConfig 变更为 SetScreenVideoEncoderConfig。publishScreen 等 API 的参数有变更。