ios11录屏(iOS端屏幕录制开发指南)

2022-08-23 13:50:13 发布:网友投稿
热度:157

S11屏幕录制(iOS屏幕录制开发指南)

一、 概述

直播过程中实现屏幕共享有两个步骤:屏幕数据采集和流媒体数据推送。对于以前的iOS来说,屏幕采集需要系统的权限,这是受到iOS系统限制的。第三方应用没有直接录屏的权限,必须通过系统的有效性来实现。

本文将描述iOS系统中屏幕共享的应用、实现、局限性和实现细节的研究成果。(注:由于iOS 10及之前的系统仅支持应用内录制屏幕,因此仅做简单介绍,不做详细说明)

二、 运用

屏幕共享早在视频会议中就出现了,后来被广泛应用于一些直播游戏中。苹果前期并不支持屏幕共享,但随着直播的普及,苹果也根据用户需求支持屏幕共享,推出了ReplayKit库来取悦这一场景。

市场上屏幕共享的场景大致分类如下:

1.远程操作屏幕:帮助他人操作手机。比如年轻人可以帮助老人远程设置,客服可以帮助客户解决软件故障或者申请帮助组,可以有效解决语言表达效率低下的问题。

2.游戏直播:著名的游戏主播可以将自己手机上玩游戏的画面播放给其他人,还可以教授和讲解游戏,让其他人更好的学习游戏技巧。

三是视频会议,会议室向他人展示手机内容进行讲解,如邮件内容、图片、文档等。,从而方便参与者快速分享信息,提高沟通有效性。

三、 各体系实现屏幕共享

在iOS系统上实现屏幕共享的技巧在于不同版本系统的差异。下面将比较系统每个版本的实现方法和局限性。首先,由于需要使用手机的摄像头和麦克风,无法在模拟器上调试应用程序。先来了解一下目前各个版本的覆盖率。

体系笼罩率

根据苹果官网数据,截至2021年6月,iOS系统各版本的占用率大致如下图所示。可以看出,iOS13及以下系统的用户覆盖率不到2%,而iOS14系统的用户覆盖率约为90%,iOS13系统的用户覆盖率约为8%。为了配合旧版本,目前市面上的应用一般都兼容iOS 9。

iOS 8

在OS 8及之前的版本中,系统并没有提供相应的功效,这是通过破解系统的功效,调用私有API来实现的。因为iOS8太老了,运行iOS8系统的设备根本支持不了直播的效果,这里就不详细讨论了,有兴趣的可以讨论。

iOS 9体系

苹果在iOS 9中引入了ReplayKit框架,提供了屏幕录制功能,但限制是只能录制这个App中的屏幕。录制后会生成一个视频文件,只能由RPPreviewViewController预览,生成的文件会被编译。在录制过程中,无法获取数据,最终录制的所有mp4文件只能提供给开发者。所以其实并不是真正的屏幕直播分享,实时性无法保证。

iOS 10体系

IOS 10苹果推出广播上传扩展和广播设置UI扩展,解决屏幕录制问题。

首先介绍App Extension,官方文档(扩展的官方文档)。Extension是App的扩展,在一定程度上打破了沙盒的限制,提供了应用之间通信的可能。扩展是一个独立的过程,有自己的生命周期。如下所示:

虽然iOS 10系统解决了之前系统的一系列弊端,但仍然无法解决只能记录当前app的屏幕内容,会限制一些应用场景的问题。

iOS 11体系

在iOS 11宣布正式直播热潮的时代,为了满足市场需求,苹果提供了跨app录屏的效果,可以实现承认所有屏幕的效果。虽然ReplayKit2已经可以满足大部分开发者的需求,但是对于用户来说,在实现屏幕直播时,这个版本要求用户提前在手机设置中配置好屏幕录制的访问权限,这样屏幕录制按钮就可以显示在系统的上拉管理菜单中,录制时,上拉底部菜单即可调出快捷管理菜单,按住屏幕录制圆形按钮即可开始录制和直播。复杂的操作过程提高了用户应用的门槛。所以iOS 11上的屏幕共享功能也很弱。

iOS12体系

IOS 12在iOS11的基础上进行了优化,提供了RPSystemBroadcastPickerView,解决了录屏问题,用户无需在主中心手动启动。

总结

结合上面对各种iOS系统版本的录屏局限性的分析,从版本稳定性和公告可靠性来看,应该从iOS12系统开始提供录屏效果,而之前的系统版本并不兼容。如果只录制应用页面进行直播,那么系统可以兼容iOS 9。

四. 屏幕共享注意事项

由于iOS手机屏幕分辨率较高,考虑到内存占用和传输效率,需要优化图像采集和处理的流程,一般将分辨率限制在720P以内。

扩展子进程的内存限制为50M。当这个线程的内存超过50M,程序就会崩溃。正因为这个限制,业内类似的处置方案会将其视频质量限制在不超过720P,高端机型视频针数在30个以内,低端机型视频帧率在10个以内。

子流程折叠会导致页面一直弹出提醒框,所以用户只能重启手机来解决这个问题。

子流程和主机应用程序之间的通信取决于传输的内容。选择不同的情况:1。共享文件或用户默认情况下,配置应用程序组。2.流程间通知:CFNotificationCenter、一般开闭等。可以通过通知来实现。3.通过Socket传输,屏幕共享之类的场景就适合这样。

五. anyRTC 屏幕共享实现

AnyRTC视频屏幕共享可以通过两种方式实现:

一种是通过Extension子流程中的Socket传输将屏幕共享视频数据发送给主机app,主机app采用自收集Push的方式将SDK进行插拔。这种方法只能传输一个视频流,无论是屏幕共享还是摄像机视频流。

一种是在Extension子流程中初始化SDK,拉流设置为发送方,而不是订阅别人的音视频。该方法实现了客户端只需用两个uid进入同一个频道,就可以发送自己相机的视频流或屏幕共享的流。

本地Socket传输到host app

想法:博客

总体思路是:本地启动一个套接字,通过tcp传输到主机app,在主机app中进行复杂的操作,有效解决了Extension 50M的限制问题。

子过程中直接应用SDK

想法:在扩展中直接应用SDK,只发送流,不吸收流。同时也要注意Extension 50M的问题(1:利用横屏和竖屏直播的限制,无论是横屏还是竖屏,使用横屏和竖屏切换很容易导致内存突然增加。2.低性能机器限制视频的帧速率(1~10帧))

1.初始化

将频道属性设置为直播模式,并设置为主播角色,启用视频模块。

//实例化rtc对象rtcKit=[ARtcEngineKitsharedEngineWithAppId:appIddelegate:self]资源网;[rtcKitsetChannelProfile:ARChannelProfileLiveBroadcasting];[rtcKitsetClientRole:ARClientRoleBroadcaster];[rtcKitenableVideo];2.设置屏幕共享的分辩率

由于子流程有50M的限制,为了系统的稳定性,建议分辨率不要超过720P。

根据屏幕的宽度和高度,用分辨率做转换,计算出最佳分辨率输出。

视频帧率,如果在低端机型,建议设置5帧,高端机不宜超过30帧。

共享屏幕的清晰度可以适当调整。建议不要超过1800。

//获取当前屏幕的最佳分辩率CGSizescreenSize=[[UIScreenmainScreen]currentMode].size;CGSizeboundingSize=CGSizeMake(720,1280);CGFloatmW=boundingSize.width/screenSize.width;CGFloatmH=boundingSize.height/screenSize.height;if(mH mW){boundingSize.width=boundingSize.height/screenSize.height*screenSize.width;}elseif(mW mH){boundingSize.height=boundingSize.width/screenSize.width*screenSize.height;}//视频编码配置ARVideoEncoderConfiguration*config=[[ARVideoEncoderConfigurationalloc]init];config.dimensions=boundingSize;config.bitrate=1500;config.frameRate=10;config.orientationMode=ARVideoOutputOrientationModeAdaptative;[rtcKitsetVideoEncoderConfiguration:config];3.设置应用外部音视频源

设置外部视频源采集,开启后,内部采集会主动关闭。

设置外部音频源采集,开启后,内部音频采集会主动关闭。

//配置外部视频源[rtcKitsetExternalVideoSource:YESuseTexture:YESpushMode:YES];//推送外部音频帧[rtcKitenableExternalAudioSourceWithSampleRate:48000channelsPerFrame:2];4.制止吸收音视频

作为屏幕共享终端,你只需要发送流,不需要吸收流。

//制止吸收所有音视频流[rtcKitmuteAllRemoteVideoStreams:YES];[rtcKitmuteAllRemoteAudioStreams:YES];5.参加频道

在主机app中获取用户Id,该Id正在第一层组装并标记为某人的辅助流。

获取正在主机app中应用的频道Id,在开始屏幕共享时以用户辅助流的形式输入频道。

//获取hostapp中的用户Id,在进行一层组装,标志为某个人的辅流NSString*uid=[NSStringstringWithFormat:@ %@_sub ,self.userId];//参加频道[rtcKitjoinChannelByToken:nilchannelId:self.channelIduid:uidjoinSuccess:^(NSString*_Nonnullchannel,NSString*_Nonnulluid,NSIntegerelapsed){NSLog(@ joinSuccess }];6.发流

RPSampleBufferTypeVideo:通过外部插件接口获取视频数据并发送出去。

RPSampleBufferTypeAudioApp:获取正在使用的音源,利用外部插件接口发送音频数据。

RPSampleBufferTypeAudioMic:获取麦克风音源,利用外部插件接口发送音频数据。

视频塞流需要组装视频数据、视频类型、时间戳、旋转角度等信息。

-(void)processSampleBuffer:(CMSampleBufferRef)sampleBufferwithType:(RPSampleBufferType)sampleBufferType{switch(sampleBufferType){caseRPSampleBufferTypeVideo:{//处置视频数据CVPixelBufferRefpixelBuffer=CMSampleBufferGetImageBuffer(sampleBuffer);if(pixelBuffer){CMTimetimestamp=CMSampleBufferGetPresentationTimeStamp(sampleBuffer);ARVideoFrame*videoFrame=[[ARVideoFramealloc]init];videoFrame.format=12;videoFrame.time=timestamp;videoFrame.textureBuf=pixelBuffer;videoFrame.rotation=[selfgetRotateByBuffer:sampleBuffer];[rtcKitpushExternalVideoFrame:videoFrame];}}break;caseRPSampleBufferTypeAudioApp://处置音频数据,音频由App发生[rtcKitpushExternalAudioFrameSampleBuffer:sampleBuffertype:ARAudioTypeApp];break;caseRPSampleBufferTypeAudioMic://处置音频数据,音频由麦克风发生[rtcKitpushExternalAudioFrameSampleBuffer:sampleBuffertype:ARAudioTypeMic];break;default:break;}}

通过以上步骤,可以实现屏幕共享效果。为了方便开发者更快上手,可以参考demo快速上手。

IOS屏幕共享

安卓屏幕共享

下一篇:瓦尔登湖作者(瓦尔登湖的作者梭罗是躺平青年吗?)
上一篇:扬州万科(万科彩虹汇)