屏幕共享
在互动直播或视频通话中,主播或视频通话用户可以通过声网 SDK 中的屏幕共享特性,将自己的屏幕内容以视频的方式分享给其他用户或观众观看。
屏幕共享可以应用在以下场景中:
场景 | 描述 |
---|---|
在线教育 | 老师将自己的屏幕、教学课件、绘图软件或编程软件共享给学生,用于课堂示范 |
游戏直播 | 主播共享自己的游戏画面给观众 |
互动直播 | 主播共享自己的屏幕和观众互动 |
视频会议 | 会议成员共享屏幕观看 PPT 或者文档 |
远程控制 | 被控端向主控端展示自己的桌面 |
注意事项
- 在开启屏幕共享后,声网以屏幕共享视频流的分辨率作为计费标准。默认分辨率为 1920 x 1080,你也可以根据你的业务需求进行调整。详见如何确定屏幕共享视频流的分辨率?
- 如果要在屏幕共享时共享 4K 分辨率的超高清视频,你的设备需要满足一定要求,声网推荐的最低设备规格为:2021 年 M1 MacBook Pro 16 英寸。
前提条件
- 在实现屏幕共享前,请确保已在你的项目中实现基本的实时音视频功能。详见实现音视频互动。
- 要实现屏幕共享,请确保在集成 SDK 时不要手动删除屏幕共享动态库(
AgoraScreenCaptureExtension.xcframework
),否则会导致该功能无法正常使用。
实现屏幕共享
本节介绍如何在你的项目中实现屏幕共享,API 调用时序如下图所示。
开启屏幕共享有如下两种方案,你可以根据实际场景进行选择:
- 在加入频道前调用
startScreenCaptureByDisplayId
或startScreenCaptureByWindowId
,然后调用joinChannelByToken
[2/4] 加入频道并设置publishScreenTrack
或publishSecondaryScreenTrack
为true
,即可开始屏幕共享。 - 在加入频道后调用该
startScreenCaptureByDisplayId
或startScreenCaptureByWindowId
,然后调用updateChannelWithMediaOptions
设置publishScreenTrack
或publishSecondaryScreenTrack
为true
,即可开始屏幕共享。
本文中的流程图和步骤均以第一种方案为例。
参考如下具体步骤,实现屏幕共享。
获取资源列表
调用 getScreenCaptureSourcesWithThumbSize
,获取可共享的屏幕和窗口的对象列表,列表中包含窗口 ID 和屏幕 ID 等重要信息,方便用户通过列表中的缩略图选择共享某个显示器的屏幕或某个窗口。示例代码如下:
// 获取可用的屏幕信息
@IBAction func onScreentThumbnailButton(_ sender: NSButton) {
let result = agoraKit.getScreenCaptureSources(withThumbSize: NSScreen.main?.frame.size ?? .zero, iconSize: .zero, includeScreen: true)
saveThumbnailToDesktop(result: result, type: .screen)
}
// 获取可用的窗口信息
@IBAction func onWindowThumbnailButton(_ sender: NSButton) {
let result = agoraKit.getScreenCaptureSources(withThumbSize: selectedResolution?.size() ?? .zero, iconSize: .zero, includeScreen: true)
saveThumbnailToDesktop(result: result, type: .window)
}
开启屏幕共享
根据实际应用场景,在以下 3 种屏幕共享方式中任选一种。
共享整个屏幕
调用 startScreenCaptureByDisplayId
开始共享整个屏幕,参数设置如下:
- 将
displayId
设置为上一步获取到的sourceId
(屏幕 ID)。 - 在
captureParams
中设置你预期的视频编码属性。- 在文档场景或远程控制场景下,推荐将
dimensions
设置为 1920 × 1080;frameRate
设置为 10 fps。 - 在游戏场景或视频场景下,推荐将
dimensions
设置为 960 × 720;frameRate
设置为 15 fps。
- 在文档场景或远程控制场景下,推荐将
// 开始共享指定的屏幕
let result = agoraKit.startScreenCapture(byDisplayId: UInt32(screen.id), regionRect: .zero, captureParams: params)
共享 App 窗口
调用 startScreenCaptureByWindowId
开始共享整个 App 窗口,参数设置如下:
- 将
windowId
设置为上一步获取到的sourceId
(窗口 ID)。 - 在
captureParams
中设置你预期的视频编码属性。- 在文档场景或远程控制场景下,推荐将
dimensions
设置为 1920 × 1080;frameRate
设置为 10 fps。 - 在游戏场景或视频场景下,推荐将
dimensions
设置为 960 × 720;frameRate
设置为 15 fps。
- 在文档场景或远程控制场景下,推荐将
// 开始共享指定的 App 窗口
let result = agoraKit.startScreenCapture(byWindowId: UInt32(window.id), regionRect: .zero, captureParams: params)
共享指定区域
调用 startScreenCaptureByDisplayId
或 startScreenCaptureByWindowId
方法开始共享,并将 regionRect
设置为你想要共享的区域相对于整个屏幕或窗口的位置。示例代码如下:
// 设置你想要共享的区域参数
// 如果设置的共享区域超出了屏幕的边界,则只共享屏幕内的内容;如果宽或高设为 0,则共享整个屏幕
// 下一行代码指定了一个长度和宽度均为 100 px 的矩形,该矩形左上角的 x 坐标和 y 坐标均为 0
let captureRect = CGRect(x: 0, y: 0, width: 100, height: 100)
let result = agoraKit.startScreenCapture(byWindowId: UInt32(window.id), regionRect: captureRect, captureParams: params)
(可选)设置屏幕共享场景
调用 setScreenCaptureScenario
方法设置屏幕共享场景,按照实际使用场景,将 scenarioType
设置为以下任意一种:
AgoraScreenScenarioDocument
(1):文档场景AgoraScreenScenarioGaming
(2):游戏场景AgoraScreenScenarioVideo
(3):视频场景AgoraScreenScenarioRDC
(4):远程控制场景
示例代码如下:
agoraKit.setScreenCaptureScenario(.video)
(可选)采集系统音频
如果你想要同时采集并发布共享屏幕或窗口中播放的音频,可以调用 enableLoopbackRecording
方法开启声卡采集,系统播放的音频会被合入到本地音频流中。
调用该方法后,系统其他进程播放的音频也会被发布到远端,如果这并非你的预期,请再次调用该方法,关闭声卡采集。
加入频道并发布屏幕共享视频流
调用 joinChannelByToken
[2/4] 加入频道并设置频道媒体选项。示例代码如下:
// 设置频道场景
agoraKit.setChannelProfile(.liveBroadcasting)
// 设置用户角色
agoraKit.setClientRole(.broadcaster)
// 设置频道媒体选项
// 在频道中发布屏幕采集的视频
// 如果要在频道中发布第二个屏幕采集的视频,则将下一行代码替换为 mediaOptions.publishSecondaryScreenTrack = true
mediaOptions.publishScreenTrack = true
// 加入频道
let result = self.agoraKit.joinChannel(byToken: token, channelId: channel, uid: 0, mediaOptions: option)
本文以直接在频道中发布屏幕共享流、不发布摄像头采集的流为例,实际应用场景中的发流方式可能跟本文的描述不同,请结合实际应用场景调整你的代码逻辑。如果你需要同时发布摄像头采集的流和屏幕共享流,可参考以下步骤:
- 调用
joinChannelByToken
[2/4] 加入第一个频道,在该频道中发布摄像头采集的视频流。 - 调用
joinChannelEx
加入第二个频道,在该频道中发布屏幕共享流。
(可选)更新屏幕共享区域或参数
在频道中,你可以调用如下方法动态更新屏幕共享区域或参数:
-
如果你要更新屏幕共享的区域,调用
updateScreenCaptureRegion
方法,重新设置regionRect
参数、划定新的共享区域。 -
如果你要更新屏幕共享的参数(例如:视频编码分辨率、帧率、码率;对屏幕或 App 窗口描边;是否屏蔽指定窗口等),调用
updateScreenCaptureParameters
方法,更新captureParams
参数的配置。
示例代码如下:
// 更新屏幕共享区域
let rect = NSScreen.main?.frame
let region = NSMakeRect(0, 0, !toggleRegionalScreening ? rect!.width / 2 : rect!.width, !toggleRegionalScreening ? rect!.height / 2 : rect!.height)
agoraKit.updateScreenCaptureRegion(region)
// 设置新的屏幕采集参数
private lazy var screenParams: AgoraScreenCaptureParameters2 = {
let params = AgoraScreenCaptureParameters2()
params.captureVideo = true
params.captureAudio = true
let audioParams = AgoraScreenAudioParameters()
// 设置采集的系统音量
audioParams.captureSignalVolume = 70 // 更新音量
params.audioParams = audioParams
let videoParams = AgoraScreenVideoParameters()
// 更新共享屏幕的分辨率
videoParams.dimensions = CGSizeMake(1280, 960) // 更新为 1280 x 960
// 更新视频编码帧率
videoParams.frameRate = .fps30 // 更新为 30 fps
// 更新视频编码码率
videoParams.bitrate = 1500 // 更新为 1500 Kbps
params.videoParams = videoParams
return params
}()
// 更新屏幕共享参数
agoraKit.updateScreenCaptureParameters(captureParams)
(可选)对屏幕描边
根据实际使用场景,你可以通过以下两种方式对屏幕或窗口进行描边。
- 在开启屏幕共享时描边:调用
startScreenCaptureByDisplayId
或startScreenCaptureByWindowId
,将captureParams
中的highLighted
设置为true
,并同时设置highLightColor
和highLightWidth
来指定描边的颜色和宽度。 - 在开启屏幕共享后描边:调用
updateScreenCaptureParameters
,将captureParams
中的highLighted
设置为true
,并同时设置highLightColor
和highLightWidth
来指定描边的颜色和宽度。
let params = AgoraScreenCaptureParameters()
params.frameRate = fps
params.dimensions = resolution.size()
// 设置屏幕的描边宽度
params.highLightWidth = 5
// 设置屏幕的描边颜色
params.highLightColor = .green
// 开启屏幕描边
params.highLighted = true
let result = agoraKit.startScreenCapture(byDisplayId: UInt32(screen.id), regionRect: .zero, captureParams: params)
(可选)屏蔽窗口
根据实际使用场景,你可以通过以下两种方式屏蔽指定的窗口。
- 在开启屏幕共享时屏蔽窗口:调用
startScreenCaptureByDisplayId
,将captureParams
中的excludeWindowList
设置为你想要屏蔽的窗口列表。 - 在开启屏幕共享后屏蔽窗口:调用
updateScreenCaptureParameters
,将captureParams
中的excludeWindowList
设置为你想要屏蔽的窗口列表。
let captureParams = AgoraScreenCaptureParameters()
captureParams.excludeWindowList = windowlist.filter({ $0.id != window.id })
agoraKit.updateScreenCaptureParameters(captureParams)
停止屏幕共享
调用 stopScreenCapture
,在频道内停止屏幕共享。示例代码如下:
// 停止屏幕共享
agoraKit.stopScreenCapture()
参考信息
功能介绍
声网 SDK 的屏幕共享特性可提供以下功能,适用于各种场景下的屏幕共享。
屏幕共享功能在各平台的适用情况如下:
- 桌面端(Windows 和 macOS):支持上述所有屏幕共享功能。
- 移动端(Android 和 iOS):仅支持共享整个屏幕。
共享整个屏幕
将你的整个屏幕进行共享,包括屏幕中的所有信息,该功能支持同时采集两块屏幕的信息并共享。
共享 App 窗口
如果你不希望将整个屏幕内容分享给其他用户,可以只共享一个 App 窗口中的画面。
共享指定区域
如果你只希望共享屏幕或 App 窗口中的一部分,可以在开启屏幕共享时设置一个共享区域,只有该区域内的画面会被分享。
高级功能
除上述功能外,你还可以在开启屏幕共享时通过调整参数,实现以下高级共享功能:
- 屏蔽指定 App 窗口:在共享屏幕时,如果你不希望暴露某个 App 窗口,可以选择将该 App 窗口屏蔽,则该窗口将不会出现在共享的屏幕中。
- 描边:如果你需要勾勒出正在共享的范围,可以对指定的 App 窗口或屏幕进行描边,并自定义描边的宽度、颜色和透明度。
- 前置指定 App 窗口:如果你同时共享了多个 App 窗口,可能会出现窗口之间互相遮挡的情况,你可以指定一个 App 窗口并将其前置,即可避免它被其他窗口遮挡。
- 设置共享场景:SDK 会根据你设置的场景自动调节 QOE (Quality of Experience) 策略。
- 在共享文档、幻灯片、表格,或者远程控制时,你可以将共享场景设置为文档场景或远程控制场景,SDK 会优先保障画质,并降低接收端看共享视频的延时。
- 在共享游戏或电影、视频直播时,你可以将共享场景设置为游戏场景或视频场景,SDK 会优先保障流畅性。
优势介绍
声网提供的屏幕共享特性具备以下优势:
超高清画质体验
支持超高清视频(分辨率为 4K,帧率为 60 fps),给用户带来更加流畅、高清的极致画面体验。
多 App 支持
适配 WPS Office、Microsoft Office Power Point、Visual Studio Code、Adobe Photoshop、Windows Media Player 和 Scratch 等多款主流 App,方便用户在屏幕共享时直接共享指定 App、提升了功能易用性。
多设备支持
支持多设备同时共享,兼容 Windows 8 系统、无独立显卡的设备、双显卡设备、外接屏幕设备等,满足各种场景下的设备使用需求。
多平台适配
支持 iOS、Andriod、macOS、Windows、Web、Unity、Flutter、React Native、Unreal Engine 等平台。
高安全保障
支持仅共享 App 和屏幕中的部分区域内容,并支持屏蔽指定 App 窗口,有效保障用户信息安全。
示例项目
声网提供了开源的示例项目供你参考,你可以前往下载或查看其中的源代码。