屏幕共享是指在视频通话或互动直播过程中将屏幕内容以视频的方式分享给其他的观众,以增强互动体验,提高沟通效率。
屏幕共享在如下场景中应用广泛:
请参考 下载示例源码 获取源码。
相关源码请查看 "/ZegoExpressExample/Examples/Others/ScreenSharing" 目录下的文件。
ZegoExpressExample
...
├── Examples
...
│ ├── Others
...
│ │ ├── ScreenSharing
│ │ │ ├── ScreenCapture.storyboard
│ │ │ ├── ZGScreenCaptureViewController.h
│ │ │ ├── ZGScreenCaptureViewController.m
│ │ │ └── ZegoExpressExample-Broadcast
│ │ │ ├── Info.plist
│ │ │ ├── SampleHandler.h
│ │ │ ├── SampleHandler.m
│ │ │ └── ZegoExpressExample-Broadcast.entitlements
...
在实现屏幕共享功能之前,请确保:
iOS 平台是基于苹果的 Replaykit 框架实现屏幕录制,能够分享整个系统的屏幕内容。但需要当前 App (主 App 进程)额外提供一个 Extension 扩展组件(Extension 进程),用于录制屏幕,再结合 ZEGO Express SDK 相关 API 来实现屏幕共享功能。
实现屏幕共享的主要流程如下:
ZegoReplayKitExt
类中的对应方法,将录制的屏幕缓存数据发送给 ZEGO Express SDK。 详细的操作请参考下文。
如果您想自己实现屏幕共享功能,请参考 如何通过自定义采集实现屏幕共享?。
SDK 推流的视频源默认为摄像头源,如果需要推屏幕共享源,需要通过 setVideoSource 进行切换为屏幕共享。
[ZegoExpressEngine.shareEnigne setVideoSource:ZegoVideoSourceScreenCapture channel:ZegoPublishChannelMain];
SDK 推流的音频源默认为麦克风源,如果需要推屏幕共享源,需要通过 setAudioSource 进行切换为屏幕共享。
[ZegoExpressEngine.shareEnigne setAudioSource:ZegoAudioSourceTypeScreenCapture channel:ZegoPublishChannelMain];
若用户只在应用内共享画面与声音,可以调用 startScreenCaptureInApp 接口开启屏幕共享。
ZegoScreenCaptureConfig *config = [[ZegoScreenCaptureConfig alloc] init];
config.captureVideo = true;
config.captureAudio = true;
[ZegoExpressEngine.sharedEngine startScreenCaptureInApp:config];
若用户需要共享整个系统的画面与声音,可以调用 startScreenCapture 接口开启屏幕共享。
跨应用屏幕共享是由 iOS 系统通过 Extension 扩展进程进行录制的,所以需要再额外创建扩展进程,并启动。
ZegoScreenCaptureConfig *config = [[ZegoScreenCaptureConfig alloc] init];
config.captureVideo = true;
config.captureAudio = true;
[ZegoExpressEngine.sharedEngine startScreenCapture:config];
Broadcast Upload Extension 的内存使用限制为 50 MB,请勿在屏幕共享的 Extension 中进行额外的内存分配。
无需勾选 “Include UI Extension”。
创建完成后,您会在项目中看到该 Extension 的文件夹,结构类似如下,该文件夹用于存放屏幕共享功能的实现代码:
如下系统回调的实现可以在 下载示例源码 中的 “/ZegoExpressExample-iOS-OC/Topics/ScreenCapture/ZegoExpressExample-iOS-OC-Broadcast/SampleHandler.m” 文件中查看:
ZegoReplayKit
类中的如下接口创建数据传输通道:[ZegoReplayKitExt.sharedInstance setupWithDelegate:self];
在 processSampleBuffer 系统回调中,通过 ZegoReplayKit
类中的 sendSampleBuffer 接口发送给 ZEGO Express SDK。
[ZegoReplayKitExt.sharedInstance sendSampleBuffer:sampleBuffer withType:sampleBufferType];
系统通过 broadcastFinished 回调通知 Extension 屏幕录制已结束,您可以在该回调中,调用 ZegoReplayKit
类中的如下接口停止屏幕共享并断开数据传输通道:
[ZegoReplayKitExt.sharedInstance finished];
您需要在 iOS 系统的控制中心,长按录屏按钮后,选择对应的 Extension 来开启录制。
苹果在 iOS 12.0 中新增了 RPSystemBroadcastPickerView,可以从 App 应用弹出启动器,供用户确认启动屏幕分享。
RPSystemBroadcastPickerView *broadcastPickerView = [[RPSystemBroadcastPickerView alloc] initWithFrame:CGRectMake(0, 0, 44, 44)];
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"ZegoExpressExample-Broadcast" ofType:@"appex" inDirectory:@"PlugIns"];
if (bundlePath) {
NSBundle *bundle = [NSBundle bundleWithPath:bundlePath];
if (bundle) {
broadcastPickerView.preferredExtension = bundle.bundleIdentifier;
for (UIView *subView in broadcastPickerView.subviews) {
if ([subView isMemberOfClass:[UIButton class]]) {
UIButton *button = (UIButton *)subView;
[button sendActionsForControlEvents:UIControlEventAllEvents];
}
}
}
}
完成上述屏幕共享源的采集过程后,将采集到的数据源推送到云服务器。(推送数据源的通道必须与设置采集源的通道保持一致)
[ZegoExpressEngine.sharedEngine startPublishingStream:streamID channel:ZegoPublishChannelMain];
完成以上步骤后,其他用户可以使用 startPlayingStream 接口拉取屏幕共享流。
// 拉流播放,需传入发起屏幕共享的用户推流时所用的 streamID
[[ZegoExpressEngine sharedEngine] startPlayingStream:streamID canvas:[ZegoCanvas canvasWithView:self.playView]];
iOS 是否支持共享指定区域?
iOS 系统仅支持共享整个屏幕,不支持共享指定区域。
iOS 使用屏幕共享时进入后台,为什么会停止采集?
iOS 使用屏幕共享时出现音频播放异常,如何处理?
若使用屏幕共享功能采集并推流音频,同时又在本机使用拉流功能,会导致 iOS 系统重复采集拉流音频,导致音频播放异常,建议使用 muteAllPlayStreamAudio 禁止拉取所有音频流。
联系我们
文档反馈