开启屏幕共享
基于 Android 平台
腾讯云 TRTC 在 Android 系统上支持屏幕分享,即将当前系统的屏幕内容通过 TRTC SDK 分享给房间里的其他用户。关于此功能,有两点需要注意:
移动端 TRTC Android 8.6 之前的版本屏幕分享并不像桌面端版本一样支持“辅路分享”,因此在启动屏幕分享时,摄像头的采集需要先被停止,否则会相互冲突;8.6 及之后的版本支持“辅路分享”,则不需要停止摄像头的采集。
当一个 Android 系统上的后台 App 在持续使用 CPU 时,很容易会被系统强行杀掉,而且屏幕分享本身又必然会消耗 CPU。要解决这个看似矛盾的冲突,我们需要在 App 启动屏幕分享的同时,在 Android 系统上弹出悬浮窗。由于 Android 不会强杀包含前台 UI 的 App 进程,因此该种方案可以让您的 App 可以持续进行屏幕分享而不被系统自动回收。
启动屏幕分享
添加 Activity
在 manifest 文件中粘贴如下 activity(若项目代码中存在则不需要添加)。
<activityandroid:name="com.tencent.rtmp.video.TXScreenCapture$TXScreenCaptureAssistantActivity"android:theme="@android:style/Theme.Translucent"/>
设定视频编码参数
通过设置 startScreenCapture() 中的首个参数
encParams
,您可以指定屏幕分享的编码质量。如果您指定 encParams
为 null,SDK 会自动使用之前设定的编码参数,我们推荐的参数设定如下:参数项 | 参数名称 | 常规推荐值 | 文字教学场景 |
分辨率 | videoResolution | 1280 × 720 | 1920 × 1080 |
帧率 | videoFps | 10 FPS | 8 FPS |
最高码率 | videoBitrate | 1600 kbps | 2000 kbps |
分辨率自适应 | enableAdjustRes | NO | NO |
说明:
由于屏幕分享的内容一般不会剧烈变动,所以设置较高的 FPS 并不经济,推荐10 FPS即可。
如果您要分享的屏幕内容包含大量文字,可以适当提高分辨率和码率设置。
最高码率(videoBitrate)是指画面在剧烈变化时的最高输出码率,如果屏幕内容变化较少,实际编码码率会比较低。
基于 iOS 平台
应用内分享
即只能分享当前 App 的画面,该特性需要 iOS 13 及以上版本的操作系统才能支持。由于无法分享当前 App 之外的屏幕内容,因此适用于对隐私保护要求高的场景。
跨应用分享
基于苹果的 Replaykit 方案,能够分享整个系统的屏幕内容,但需要当前 App 额外提供一个 Extension 扩展组件,因此对接步骤也相对应用内分享要多一点。
方案1:iOS 平台应用内分享
应用内分享的方案非常简单,只需要调用 TRTC SDK 提供的接口 startScreenCapture 并传入编码参数
TRTCVideoEncParam
和 参数appGroup
设置为''
。TRTCVideoEncParam
参数可以设置为 null,此时 SDK 会沿用开始屏幕分享之前的编码参数。我们推荐的用于 iOS 屏幕分享的编码参数是:
参数项 | 参数名称 | 常规推荐值 | 文字教学场景 |
分辨率 | videoResolution | 1280 × 720 | 1920 × 1080 |
帧率 | videoFps | 10 FPS | 8 FPS |
最高码率 | videoBitrate | 1600 kbps | 2000 kbps |
分辨率自适应 | enableAdjustRes | NO | NO |
说明:
由于屏幕分享的内容一般不会剧烈变动,所以设置较高的 FPS 并不经济,推荐10 FPS即可。
如果您要分享的屏幕内容包含大量文字,可以适当提高分辨率和码率设置。
最高码率(videoBitrate)是指画面在剧烈变化时的最高输出码率,如果屏幕内容变化较少,实际编码码率会比较低。
方案2:iOS 平台跨应用分享
示例代码
├── Broadcast.Upload //录屏进程 Broadcast Upload Extension 代码详见步骤2│ ├── Broadcast.Upload.entitlements //用于设置进程间通信的 AppGroup 信息│ ├── Broadcast.UploadDebug.entitlements //用于设置进程间通信的 AppGroup 信息(debug环境)│ ├── Info.plist│ └── SampleHandler.swift // 用于接收来自系统的录屏数据├── Resource // 资源文件├── Runner // TRTC 精简化 Demo├── TXLiteAVSDK_ReplayKitExt.framework //TXLiteAVSDK_ReplayKitExt SDK
对接步骤
iOS 系统上的跨应用屏幕分享,需要增加 Extension 录屏进程以配合主 App 进程进行推流。Extension 录屏进程由系统在需要录屏的时候创建,并负责接收系统采集到屏幕图像。因此需要:
1. 创建 App Group,并在 XCode 中进行配置(可选)。这一步的目的是让 Extension 录屏进程可以同主 App 进程进行跨进程通信。
2. 在您的工程中,新建一个 Broadcast Upload Extension 的 Target,并在其中集成 SDK 压缩包中专门为扩展模块定制的
TXLiteAVSDK_ReplayKitExt.framework
。3. 对接主 App 端的接收逻辑,让主 App 等待来自 Broadcast Upload Extension 的录屏数据。
4. 编辑
pubspec.yaml
文件引入 replay_kit_launcher
插件 ,实现类似TRTC Demo Screen中点击一个按钮即可唤起屏幕分享的效果(可选)。# 引入 trtc sdk和replay_kit_launcherdependencies:tencent_trtc_cloud: ^0.2.1replay_kit_launcher: ^0.2.0+1
注意:
步骤1:创建 App Group
1. 单击 Certificates, IDs & Profiles。
2. 在右侧的界面中单击加号。
3. 选择 App Groups,单击 Continue。
4. 在弹出的表单中填写 Description 和 Identifier, 其中 Identifier 需要传入接口中的对应的 AppGroup 参数。完成后单击 Continue。
5. 回到 Identifier 页面,左上边的菜单中选择 App IDs,然后单击您的 App ID(主 App 与 Extension 的 AppID 需要进行同样的配置)。
6. 选中 App Groups 并单击 Edit。
7. 在弹出的表单中选择您之前创建的 App Group,单击 Continue 返回编辑页,单击 Save 保存。
8. 重新下载 Provisioning Profile 并配置到 XCode 中。
步骤2:创建 Broadcast Upload Extension
1. 在 Xcode 菜单依次单击 File > New > Target...,选择 Broadcast Upload Extension。
2. 在弹出的对话框中填写相关信息,不用勾选 Include UI Extension,单击 Finish 完成创建。
3. 将下载到的 SDK 压缩包中的 TXLiteAVSDK_ReplayKitExt.framework 拖动到工程中,勾选刚创建的 Target。
4. 选中新增加的 Target,依次单击+ Capability,双击 App Groups,如下图:
操作完成后,会在文件列表中生成一个名为 Target名.entitlements
的文件,如下图所示,选中该文件并单击 + 号填写上述步骤中的 App Group 即可。
5. 选中主 App 的 Target ,并按照上述步骤对主 App 的 Target 做同样的处理。
6. 在新创建的 Target 中,Xcode 会自动创建一个名为 "SampleHandler.swift" 的文件,用如下代码进行替换。需将代码中的 APPGROUP 改为上文中的创建的 App Group Identifier。
import ReplayKitimport TXLiteAVSDK_ReplayKitExtlet APPGROUP = "group.com.tencent.comm.trtc.demo"class SampleHandler: RPBroadcastSampleHandler, TXReplayKitExtDelegate {let recordScreenKey = Notification.Name.init("TRTCRecordScreenKey")override func broadcastStarted(withSetupInfo setupInfo: [String : NSObject]?) {// User has requested to start the broadcast. Setup info from the UI extension can be supplied but optional.TXReplayKitExt.sharedInstance().setup(withAppGroup: APPGROUP, delegate: self)}override func broadcastPaused() {// User has requested to pause the broadcast. Samples will stop being delivered.}override func broadcastResumed() {// User has requested to resume the broadcast. Samples delivery will resume.}override func broadcastFinished() {// User has requested to finish the broadcast.TXReplayKitExt.sharedInstance() .finishBroadcast()}func broadcastFinished(_ broadcast: TXReplayKitExt, reason: TXReplayKitExtReason) {var tip = ""switch reason {case TXReplayKitExtReason.requestedByMain:tip = "屏幕共享已结束"breakcase TXReplayKitExtReason.disconnected:tip = "应用断开"breakcase TXReplayKitExtReason.versionMismatch:tip = "集成错误(SDK 版本号不相符合)"breakdefault:break}let error = NSError(domain: NSStringFromClass(self.classForCoder), code: 0, userInfo: [NSLocalizedFailureReasonErrorKey:tip])finishBroadcastWithError(error)}override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) {switch sampleBufferType {case RPSampleBufferType.video:// Handle video sample bufferTXReplayKitExt.sharedInstance() .sendVideoSampleBuffer(sampleBuffer)breakcase RPSampleBufferType.audioApp:// Handle audio sample buffer for app audiobreakcase RPSampleBufferType.audioMic:// Handle audio sample buffer for mic audiobreak@unknown default:// Handle other sample buffer typesfatalError("Unknown type of sample buffer")}}}
步骤3:对接主 App 端的接收逻辑
按照如下步骤,对接主 App 端的接收逻辑。也就是在用户触发屏幕分享之前,要让主 App 处于“等待”状态,以便随时接收来自 Broadcast Upload Extension 进程的录屏数据。
1. 确保 TRTCCloud 已经关闭了摄像头采集,如果尚未关闭,请调用 stopLocalPreview 关闭摄像头采集。
2. 调用 startScreenCapture 方法,并传入 步骤1 中设置的 AppGroup,让 SDK 进入“等待”状态。
3. 等待用户触发屏幕分享。如果不实现 步骤4 中的“触发按钮”,屏幕分享就需要用户在 iOS 系统的控制中心,通过长按录屏按钮来触发。
4. 通过调用 stopScreenCapture 接口可以随时中止屏幕分享。
// 开始屏幕分享,需要将 APPGROUP 替换为上述步骤中创建的 App GrouptrtcCloud.startScreenCapture(TRTCVideoEncParam(videoFps: 10,videoResolution: TRTCCloudDef.TRTC_VIDEO_RESOLUTION_1280_720,videoBitrate: 1600,videoResolutionMode: TRTCCloudDef.TRTC_VIDEO_RESOLUTION_MODE_PORTRAIT,),iosAppGroup,);// 停止屏幕分享await trtcCloud.stopScreenCapture();// 屏幕分享的启动事件通知,可以通过 TRTCCloudListener 进行接收onRtcListener(type, param){if (type == TRTCCloudListener.onScreenCaptureStarted) {//屏幕分享开始}}
步骤4:增加屏幕分享的触发按钮(可选)
1. 将
replay_kit_launcher
插件加入到您的工程中。2. 在您的界面上放置一个按钮,并在按钮的响应函数中调用
ReplayKitLauncher.launchReplayKitBroadcast(iosExtensionName);
函数,就可以唤起屏幕分享功能了。// 自定义按钮响应方法onShareClick() async {if (Platform.isAndroid) {if (await SystemAlertWindow.requestPermissions) {MeetingTool.showOverlayWindow();}} else {//屏幕分享功能只能在真机测试ReplayKitLauncher.launchReplayKitBroadcast(iosExtensionName);}}
基于 Windows 平台
Windows 平台下的屏幕分享支持主路分享和辅路分享两种方案:
辅路分享
在 TRTC 中,我们可以单独为屏幕分享开启一路上行的视频流,并称之为“辅路(substream)”。辅路分享即主播同时上行摄像头画面和屏幕画面两路画面。这是腾讯会议的使用方案,您可以在调用
startScreenCapture
接口时,通过将TRTCVideoStreamType
参数指定为TRTCVideoStreamTypeSub
来启用该模式。主路分享
在 TRTC 中,我们一般把摄像头走的通道叫做“主路(bigstream)”,主路分享即用摄像头通道分享屏幕。该模式下,主播只有一路上行视频流,要么上行摄像头画面,要么上行屏幕画面,两者是互斥的。您可以在调用
startScreenCapture
接口时,通过将TRTCVideoStreamType
参数指定为 TRTCVideoStreamTypeBig
来启用该模式。步骤一:获取分享目标
说明:
Windows 里的桌面屏幕也是一个窗口,叫桌面窗口(Desktop),有两台显示器时,每一台显示器都有一个对应的桌面窗口。所以,getScreenCaptureSources 返回的窗口列表里也会有 Desktop 窗口。
根据获取到的窗口信息,您可以实现一个简单的列表页面,将可以分享的目标罗列出来供用户选择。
步骤二:选择分享目标
步骤三:开始屏幕分享
选取分享目标后,使用startScreenCapture 接口可以启动屏幕分享。
分享过程中,您依然可以通过调用selectScreenCaptureTarget更换分享目标。
pauseScreenCapture和 stopScreenCapture的区别在于 pause 会停止屏幕内容的采集,并以暂停那一刻的画面垫片,所以在远端看到一直都是最后一帧画面,直到 resume。
设定视频编码参数
清晰度级别 | 分辨率 | 帧率 | 码率 |
超高清(HD+) | 1920 × 1080 | 10 | 800kbps |
高清(HD) | 1280 × 720 | 10 | 600kbps |
标清(SD) | 960 × 720 | 10 | 400kbps |
如果您指定
encParams
为 null,SDK 会自动使用之前设定的编码参数。观看屏幕分享
观看 Android / iOS 屏幕分享
若用户通过 Android / iOS 进行屏幕分享,会通过主流进行分享。房间里的其他用户会通过 TRTCCloudListener 中的 onUserVideoAvailable 事件获得这个通知。
希望观看屏幕分享的用户可以通过 startRemoteView 接口来启动渲染远端用户主流画面。
常见问题
一个房间里可以同时有多路屏幕分享吗?
目前一个 TRTC 音视频房间只能有一路屏幕分享。