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。

b. 在 Product Name 一栏输入 Extension 的名字,如 ScreenShare-Extension,然后点击 Finish。

创建完成后,你会在项目中看到该 Extension 的文件夹,用于存放屏幕共享功能的实现代码。

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. 配置证书

b. 通知

开发注意事项:

  • Broadcast Upload Extension 的内存使用限制为 50 MB,请确保屏幕共享的 Extension 内存使用不超过 50 MB。
  • 如果在屏幕共享时需要同时分享 app 的音频,可以通过自定义音频采集实现,具体代码可以参考 AgoraAudioTube.mm。
  • 屏幕共享的进程中,需要调用 muteAllRemoteVideoStreams 和 muteAllRemoteAudioStreams 方法取消接收远端用户的流,避免重复订阅。

详细使用:请一定参照demo、具体app,使用可以参考声网api。