iOS 屏幕共享
该章节主要介绍和屏幕共享相关的功能。 包括:建立屏幕共享、开启屏幕共享、关闭屏幕共享;ReplayKit 2仅支持iOS 11.0 以上共享系统屏幕。基本流程是添加ReplayKit扩展、云信SDK创建加入房间并使用自定义采集、使用Socket在宿主App(主工程,这里是教育Demo)和扩展ReplayKit程序之间进行视频数据(音频使用宿主APP中云信SDK采集)和控制指令传输;
添加ReplayKit
1. 添加 Broadcast Upload Extension
选择Target,添加 Extension
2. 在宿主App和Extension之间建立Socket连接,用于进程间通信
宿主App
- (void)setupServerSocket
{
if (replayKitCapture) {
self.serverSocket = [[NTESSocket alloc] initWithPort:@"8898" IP:@"127.0.0.1"];
// 收到的数据通过 Delegate 接收
self.serverSocket.delegate = self;
// 开始接受客户端的连接请求
[self.serverSocket startAcceptClient];
}
}
SampleHandler 创建Socket用于发送视频数据
// 连接到宿主 Socket
- (BOOL)connectToHostApp {
self.clientSocket = [[NTESSocket alloc] initWithPort:self.clientPort IP:self.ip];
// 设置委托对象,用于接受对端数据
self.clientSocket.delegate = self;
// 向Server Socket发起连接
BOOL success = [self.clientSocket connectToServerWithPort:@"8898"
IP:@"127.0.0.1"];
if (success) {
// 开始接收控制命令数据
[self.clientSocket startRecv];
}
return success;
}
3. 压缩裁剪采集图片,发送到宿主App
ReplayKit 采集到的屏幕视频数据通过 processSampleBuffer:withType:给用户,忽略音频数据回调(我们使用云信SDK音频采集),将视频数据通过Socket发送到宿主App,然后再通过SDK自定义视频数据进行发送,
- (void)processSampleBuffer:(CMSampleBufferRef)sampleBuffer withType:(RPSampleBufferType)sampleBufferType {
switch (sampleBufferType) {
case RPSampleBufferTypeVideo:
if(!self.connected) {
return;
}
[self sendVideoBufferToHostApp:sampleBuffer];
break;
case RPSampleBufferTypeAudioApp:
// Handle audio sample buffer for app audio
break;
case RPSampleBufferTypeAudioMic:
// Handle audio sample buffer for mic audio
break;
default:
break;
}
}
- (void)sendVideoBufferToHostApp:(CMSampleBufferRef)sampleBuffer {
CFRetain(sampleBuffer);
CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
// 原始视频数据过大(ReplayKit限制内存50M),裁剪视频数据
NTESI420Frame *videoFrame = nil;
videoFrame = [NTESYUVConverter pixelBufferToI420:pixelBuffer
withCrop:self.cropRate
targetSize:self.targetSize
andOrientation:self.orientation];
CFRelease(sampleBuffer);
// To Host App
if (videoFrame) {
[self.clientSocket sendData:[videoFrame bytes]];
}
}
4. 宿主App 通过SDK发送视频数据
#pragma mark - NTESSocketDelegate
- (void)onRecvData:(NSData *)data
{
NTESI420Frame *frame = [NTESI420Frame initWithData:data];
CMSampleBufferRef sampleBuffer = [frame convertToSampleBuffer];
// SDK自定义视频数据发送接口
[[NIMAVChatSDK sharedSDK].netCallManager sendVideoSampleBuffer:sampleBuffer];
CFRelease(sampleBuffer);
}
云信SDK自定义采集
自定义采集开启并加入房间后,再启动ReplayKit
- (void)start {
// _meeting 一些基本设置
...
if(replayKitCapture) {
// SDK采集对象置nil
_meeting.option.videoCaptureParam = nil;
// 创建自定义采集
_meeting.option.customVideoParam = [[NIMNetCallCustomVideoParam alloc] init];
_meeting.option.customVideoParam.videoFrameRate = 15;
}
// 加入房间
[[NIMAVChatSDK sharedSDK].netCallManager joinMeeting:_meeting completion:nil];
}
应用置于后台
当发起屏幕共享的应用处于后台时,需要确保当前视频编码处于软编模式。
通话发起时指定为软编:指定NIMNetCallOption
的preferredVideoEncoder
为NIMNetCallVideoCodecSoftware
。
通话过程中切换为软编:通过NIMNetCallManager
协议的switchVideoEncoder
方法来切换至软编。
开启屏幕共享
控制中心 -> 屏幕共享 -> 长按选择云信屏幕录制
如果没有该按钮,则去系统设置-> 控制中心-> 自定义控制里添加上,
选择扩展,开启(Demo上的逻辑:需要先加入房间,再开启ReplayKit)
关闭屏幕共享
控制中心 -> 屏幕共享 -> 点击退出
本篇文档内容是否对您有帮助?
有帮助
我要吐槽
此文档对你是否有帮助
×
有帮助
我要吐槽
×