在实时通信中,如果你希望用户可以分享本端设备的屏幕和设备播放的音频,可以使用 RTC 内建的屏幕采集功能,也可以自行实现屏幕采集逻辑(自定义采集),并通过屏幕共享功能,与远端用户共享。
仅可见的用户可以发布屏幕流。
你可以在多种行业的多种场景下使用到屏幕共享功能:
行业 | 场景 |
---|---|
在线教育 | 老师共享屏幕给学生上课;美术老师共享屏幕给学生教画画。 |
游戏直播 | 主播共享屏幕给观众,展现自己的游戏画面。 |
互动直播 | 主播共享自己的屏幕和观众互动。 |
视频会议 | 会议成员共享屏幕观看 PPT 或者文档。 |
对于 Linux 系统,你需要判断其显示协议使用的是 X11 协议还是 Wayland 协议。如果是 X11 协议,你可以使用 资源获取 中的 Linux SDK;如果是 Wayland 协议,你需要联系技术支持人员,获取对应版本的 Linux SDK。要判断系统使用的协议,可以在系统命令行中运行以下命令:
echo $XDG_SESSION_TYPE
。
API 调用的逻辑如下图:
图中以 Windows SDK 为例。不同的系统有一些差异。
对使用 Wayland 协议的 Linux 系统,SDK 无法获取可选共享对象信息。当用户调用 SDK API 发起屏幕共享时,系统会显示弹窗,展示可选共享对象的相关信息:
对 Windows 系统或使用 X11 协议的 Linux 系统,调用以下接口,以便用户在发起共享前,看到可以共享的屏幕/窗口的缩略图等信息,并指定共享对象。
getScreenCaptureSourceList
接口获取共享对象列表:
kScreenCaptureSourceTypeWindow
kScreenCaptureSourceTypeScreen
。 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(); }
调用 setScreenVideoEncoderConfig
进行设置:
startScreenVideoCapture
开启屏幕采集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 强烈建议你使用内部采集。如果你仍然希望使用自定义采集,参看以下步骤。
setScreenAudioSourceType
和 setVideoSourceType
设置屏幕音视频自定义采集。pushScreenAudioFrame
和 pushScreenVideoFrame
将采集得到的音视频帧推送到 RTC SDK 用于编码传输。publishScreen
发布屏幕共享流。unpublishScreen
关闭屏幕共享。调用一次
publishScreen
同时发布音视频与多次调用该接口,分别只发布音频、只发布视频结果是相同的。
远端用户发布屏幕音视频流后,RTC 通过 onUserPublishScreen
通知本地用户。通过 subscribeScreen
手动订阅屏幕音视频流。订阅后,屏幕音频流即可正常播放。
如果已经在进房时开启自动订阅,则无需进行手动订阅。
屏幕视频流正常解码后收到 onFirstRemoteVideoFrameDecoded
首帧解码回调,并通过 setRemoteVideoSink
或者 setRemoteVideoCanvas
将屏幕视频渲染出来。
以下是各个平台的相关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 的参数有变更。