====== iOS 屏幕共享 ====== ===== 实现方式 ===== iOS 端的屏幕共享是通过在 Extension 中使用 iOS 原生的 ReplayKit 框架实现录制屏幕,然后将屏幕共享流作为一个用户加入频道实现的。由于 Apple 不支持 Extension 进程与主 app 进程通信,因此你需要为屏幕共享流单独创建一个进程。 **实现屏幕共享的主要步骤如下:** * 创建一个 Broadcast Upload Extension 用于开启屏幕共享的进程。 * 使用 Apple ReplayKit 框架进行屏幕录制。 * 将录屏数据作为自定义视频源发送给 SDK,并使用 SDK 进行视频流的传输。 * 本文的实现方法适用于 iOS 12.0 或更高版本。 **1. 创建屏幕共享 Extension** 参考以下步骤: a. 创建一个 Broadcast Upload Extension。 用 Xcode 打开项目的工程文件,在菜单栏中选择 Editor > Add Target...。 在弹出窗口中,选择 iOS 页的 Broadcast Upload Extension,点击 Next。 {{:cs:extension.jpg?nolink&800|}} b. 在 Product Name 一栏输入 Extension 的名字,如 ScreenShare-Extension,然后点击 Finish。 创建完成后,你会在项目中看到该 Extension 的文件夹,用于存放屏幕共享功能的实现代码。 {{:cs:存放屏幕共享功能的实现代码.jpg?nolink&600|}} c. 打开项目中的 Podfile,为 Extension 添加依赖项: 在项目根目录下运行 pod install 命令,安装依赖项。 target 'CustomerSystem-ScreenShare-Extension' do # Comment the next line if you don't want to use dynamic frameworks use_frameworks! # Pods for CustomerSystem-ScreenShare-Extension pod 'AgoraRtcEngine_iOS' end **2. 在项目中使用屏幕共享 Extension** 将 RPSystemBroadcastPickerView 作为启动屏幕录制的按钮添加到 app 的 view 中。 /// 初始化屏幕分享view - (void)initBroadPickerView{ if (@available(iOS 12.0, *)) { _broadPickerView = [[RPSystemBroadcastPickerView alloc] init]; _broadPickerView.preferredExtension = kScreenShareExtensionBundleId; } else { // Fallback on earlier versions } } **3. 设置自定义视频源** 通过 SDK 自定义视频采集的功能,实现将系统录制的屏幕数据发送给远端用户,进行屏幕共享;我们提供一个HDAgoraUploader 单利类 实现自定义视频的采集功能。 集成如下: //单利引擎 + (instancetype _Nullable )sharedAgoraEngine; /// 开始录屏 - (void)startBroadcast; /// 发送视频流 /// @param sampleBuffer CMSampleBufferRef - (void)sendVideoBuffer:(CMSampleBufferRef _Nullable )sampleBuffer; /// 发送音频流 /// @param sampleBuffer CMSampleBufferRef - (void)sendAudioAppBuffer:(CMSampleBufferRef _Nullable )sampleBuffer; /// 发送麦克风流 /// @param sampleBuffer CMSampleBufferRef - (void)sendAudioMicBuffer:(CMSampleBufferRef _Nullable )sampleBuffer; /// 停止录屏 - (void)stopBroadcast; **4. 获取屏幕数据** 使用 Apple 原生的 ReplayKit 框架实现屏幕录制。 在屏幕共享 Extension 的 Info.plist 文件中,将 RPBroadcastProcessMode 设置为 RPBroadcastProcessModeSampleBuffer。在 broadcastStarted 回调中开始录制屏幕。 **注意:** 示例代码中是通过环信 IM 作为信令通道拿到屏幕共享的参数如果需要两个进程通信 使用 App Group 将主进程的参数值传递给 Extension 最好。 具体实现可以参考demo 中的实现方式 demo中使用的是keychainGroup + 通知 的方式 如下简单截图 a. 配置证书 {{:cs:配置证书.jpg?nolink&1000|}} b. 通知 {{:cs:通知.jpg?nolink&800|}} 开发注意事项: * Broadcast Upload Extension 的内存使用限制为 50 MB,请确保屏幕共享的 Extension 内存使用不超过 50 MB。 * 如果在屏幕共享时需要同时分享 app 的音频,可以通过自定义音频采集实现,具体代码可以参考 AgoraAudioTube.mm。 * 屏幕共享的进程中,需要调用 muteAllRemoteVideoStreams 和 muteAllRemoteAudioStreams 方法取消接收远端用户的流,避免重复订阅。 详细使用:请一定参照demo、具体app,使用可以参考声网api。