屏幕共享
更新时间: 2025/06/11 16:45:39
在大型会议或在线教育等场景中,为了满足提升沟通效率的需求,主讲人或老师需要将本端的屏幕内容分享给远端参会者或在线学生观看。NERTC 支持屏幕共享功能,帮助您实时分享本端设备的屏幕内容。
功能介绍
通过 NERTC SDK 可以在视频通话或互动直播过程中实现屏幕共享,主播或连麦者可以将自己的屏幕内容,以视频的方式分享给远端参会者或在线观众观看,从而提升沟通效率,一般适用于多人视频聊天、在线会议以及在线教育场景。
-
视频会议场景中,参会者可以在会议中将本地的文件、数据、网页、PPT 等画面分享给其他与会者,让其他与会者更加直观的了解讨论的内容和主题。
-
在线课堂场景中,老师可以通过屏幕共享将课件、笔记、教学内容等画面展示给远端的其他学生观看,降低传统教学模式下的沟通成本,提升教育场景的用户体验。
NERTC SDK 以辅流的形式实现屏幕共享,即单独为屏幕共享开启一路上行的视频流,摄像头的视频流作为主流,屏幕共享的视频流作为辅流,两路视频流并行,主播同时上行摄像头画面和屏幕画面两路画面。
音频共享 功能基于原先的 NERTC SDK 可以实现,需要您在应用开发中自行编码支持。如有相关需要,您可以 提交工单 联系网易云信技术支持工程师,索取 iOS 相关 Demo 的 SampleCode,参考 Demo 在您的开发环境中完成编码。
注意事项
- 在开始屏幕共享前,请确保已在您的项目中实现基本的 实时音视频功能。
- 自 V4.6.20 起,屏幕共享功能以 插件化 方式提供,对应的屏幕共享库为
NERtcReplayKit.xcframework
。ReplayKit 仅支持 iOS 11.0 以上共享系统屏幕。Sample 工程支持 iOS 12 及以上唤起系统录屏能力,若系统版本低于 iOS 12,需手动唤起系统录屏。 - 主 App 和系统录屏需使用相同的 App Group 名。
示例项目
网易云信提供 ScreenShare 示例项目源码,您可以参考该源码实现屏幕共享。
第一步:创建 App Group
本步骤为可选步骤,如果您已创建了 App Group,则可以跳过本步骤。App Group 用于在主 App 进程和扩展程序之间之间进行视频数据和控制指令的传输。
单击展开查看具体步骤。
-
参考《苹果官方文档》注册 App Group,在 Certificates, Identifiers & Profiles 页面中注册 App Group。
-
参考《苹果官方文档》启用 App Group,为您的 App ID 启用 App Group 功能。
-
重新下载 Provisioning Profile 并配置到 XCode 中。
第二步:创建 Extension 录屏进程
创建一个类型为 Broadcast Upload Extension 的 Target,用于存放屏幕共享功能的实现代码。
-
在 Xcode 中打开项目的工程文件。
-
在菜单中选择 Editor > Add Target...。
-
在 iOS 页签中,选择 Broadcast Upload Extension,并单击 Next。
-
在 Product Name 中为 Extension 命名,例如 NERtc-ScreenShare-Extension,单后单击 Finish。
第三步:引入 NERtcReplayKit
NERtcReplayKit.xcframework
可以与核心 SDK 搭配使用,您在集成 SDK 时可引入该 xcframework,详情请参考 集成 SDK。
工程引入 NERtcReplayKit
-
将 NERtcReplayKit FrameWork 引入工程,如下图:
-
设置相关 Frameworks Link Setting:
-
App target 设置为 Embed & Sign。
-
Broadcast Extension 设置为 Do not Embed。
-
Broadcast Extension 引入 NERtcReplayKit
-
在 SampleHandler 中,引入 NERtcReplayKit 头文件。
Objective-C
#import "NRSampleHandler.h" #import <NERtcReplayKit/NERtcReplayKit.h> #import "NETestHandler.h"
-
在 SampleHandler 中,完成相关流程编码。
Objective-C
- (void)broadcastStartedWithSetupInfo:(NSDictionary<NSString *,NSObject *> *)setupInfo ... - (void)broadcastPaused ... - (void)broadcastResumed ... - (void)broadcastFinished ... - (void)processSampleBuffer:(CMSampleBufferRef)sampleBuffer withType:(RPSampleBufferType)sampleBufferType ...
示例代码 如下:
Objective-C
- (void)broadcastStartedWithSetupInfo:(NSDictionary<NSString *,NSObject *> *)setupInfo { // User has requested to start the broadcast. Setup info from the UI extension can be supplied but optional. NEScreenShareBroadcasterOptions *options = [[NEScreenShareBroadcasterOptions alloc]init]; options.appGroup = kAppGroup; //设置采集帧率 15 帧 options.frameRate = 15; //设置需要采集系统音频数据 options.needAudioSampleBuffer = YES; [[NEScreenShareSampleHandler sharedInstance] broadcastStartedWithSetupInfo:options]; } - (void)broadcastPaused { // User has requested to pause the broadcast. Samples will stop being delivered. [[NEScreenShareSampleHandler sharedInstance] broadcastPaused]; } - (void)broadcastResumed { // User has requested to resume the broadcast. Samples delivery will resume. [[NEScreenShareSampleHandler sharedInstance] broadcastResumed]; } - (void)broadcastFinished { // User has requested to finish the broadcast. [[NEScreenShareSampleHandler sharedInstance] broadcastFinished]; } - (void)processSampleBuffer:(CMSampleBufferRef)sampleBuffer withType:(RPSampleBufferType)sampleBufferType { [[NEScreenShareSampleHandler sharedInstance] processSampleBuffer:sampleBuffer withType:sampleBufferType]; }
第四步:屏幕共享
您可以按照业务需求实现屏幕共享。
NERTC SDK 相关配置
- 屏幕共享设置为主流接入时,入会前设置为
[[NERtcEngine sharedEngine] setExternalVideoSource:YES isScreen:NO];
。 - 屏幕共享设置为辅流接入时,入会前设置为
[[NERtcEngine sharedEngine] setExternalVideoSource:YES isScreen:YES]
。 - 有关画布相关设置,与 NERTC SDK 的其他设置流程相同。
NERtcReplayKit 相关代码接入
-
在开启屏幕共享时,设置 NERtcReplayKit 相关启动参数,示例代码如下:
Objective-C
//设置 NERtcReplayKit 相关参数 NEScreenShareHostOptions *options = [[NEScreenShareHostOptions alloc] init]; options.appGroup = kAppGroup; options.delegate = self; [[NEScreenShareHost sharedInstance] setupScreenshareOptions:options];
-
监听事件 Delegate 回调。
Objective-C
- (void)onReceiveVideoFrame:(NEScreenShareVideoFrame *)videoFrame { NERtcVideoFrame *frame = [[NERtcVideoFrame alloc] init]; frame.format = kNERtcVideoFormatI420; frame.width = videoFrame.width; frame.height = videoFrame.height; frame.buffer = (void *)[videoFrame.videoData bytes]; frame.timestamp = videoFrame.timeStamp; frame.rotation = (NERtcVideoRotationType)videoFrame.rotation; int ret = [NERtcEngine.sharedEngine pushExternalVideoFrame:frame]; if (ret != 0 && ret != kNERtcErrFatal) { NSLog(@"发送视频流失败: %@", NERtcErrorDescription(ret)); } }
第五步:音频共享
您可以按照业务需求实现音频共享。
Broadcast Extension 设置
开启音频共享时,设置相关参数时,Broadcast 中需要显式指定 options.needAudioSampleBuffer = YES;
。
Objective-C - (void)broadcastStartedWithSetupInfo:(NSDictionary<NSString *,NSObject *> *)setupInfo {
// User has requested to start the broadcast. Setup info from the UI extension can be supplied but optional.
NEScreenShareBroadcasterOptions *options = [[NEScreenShareBroadcasterOptions alloc]init];
options.appGroup = kAppGroup;
//设置采集帧率 15 帧
options.frameRate = 15;
//设置需要采集系统音频数据
options.needAudioSampleBuffer = YES;
[[NEScreenShareSampleHandler sharedInstance] broadcastStartedWithSetupInfo:options];
}
NERTC SDK 相关设置
-
设置 NERTC SDK 的 AudioFrameObserver,此时音频共享需要依赖
onNERtcEngineAudioFrameDidRecord
回调进行混音。Objective-C
[[NERtcEngine sharedEngine] setAudioFrameObserver:self];
-
监听 NERTC SDK 的 AudioFrameObserver 事件回调。
Objective-C
- (void)onNERtcEngineAudioFrameDidRecord:(NERtcAudioFrame *)frame { uint32_t numChannels = frame.format.channels; uint32_t samplesPerChannel = frame.format.samplesPerChannel; const int originLen = samplesPerChannel * numChannels * sizeof(int16_t); if(!_tmpAudioBuffer) { return; } int pullDataSampleRate = 0; int pullDataChannels = 0; BOOL succ = [[NEScreenShareHost sharedInstance] pullAudioData:&_tmpAudioBuffer length:originLen sampleRate:&pullDataSampleRate channels:&pullDataChannels]; if(!succ) { return; } //需要将 NERTCReplayKit 与 NERTC SDK 的音频采样率和声道设置一致,避免音频重采样 if(pullDataSampleRate != frame.format.sampleRate || pullDataChannels != frame.format.channels) { // For audio recording NERtcEngine *coreEngine = NERtcEngine.sharedEngine; NERtcAudioFrameRequestFormat *format = [[NERtcAudioFrameRequestFormat alloc] init]; format.sampleRate = pullDataSampleRate; format.channels = pullDataChannels; format.mode = kNERtcAudioFrameOpModeReadWrite; [coreEngine setRecordingAudioFrameParameters:format]; return; } [NESrceenAudioMixerUtil MixAudioFrameData:(int16_t *)frame.data scr_data:(int16_t *)_tmpAudioBuffer samplesPerChannel:samplesPerChannel channels:numChannels]; }
更多示例代码,请参考 ScreenShare/ScreenShare-iOS-Objective-C.git。