iOS屏幕录制ReplayKit10+系统版本
本篇⽂章仅针对iOS10+系统,如果需要⽀持iOS9请参考下⾯链接
iOS9屏幕录制请参考
因为10+部分涉及知识⾯较多,所以这篇⽂章主要围绕录屏,其他涉及到的我会另开篇幅。
将涉及其它知识⾯:
ension
upShare
3.H264与CMSampleBufferRef结构分析
oolBox硬编码
录屏整体流程如下:
1.触发录屏
2.准备⼯作
3.开始录屏
4.处理数据流保存到指定⽂件
5.结束录制
共享到主App中(或者直接对此⽂件进⾏操作)
进⼊正题:
苹果在iOS9已经⽀持了屏幕录制,但相⽐较安卓的来说开发者的可操作性⼜少⼜差。在iOS10之后,ReplayKit⼜开放了⼀系列的API,给了开发
者更多的操作空间,但从实际体验来说友好性并不理想。
iOS10之后的⼀些API更多地偏向于流数据的处理,通过AppExtension的配合完成屏幕数据流或者其他数据流的采集,通过对数据流的采集和处
理我们能做很多事情,⽐如进⾏推流直播或者编码保存信息,所以屏幕录制其实只是在此基础上延伸出了⼀个使⽤⽅式,⽽且我认为10-12之间使
⽤AppExtension的⽅式并不是⼀个好的录屏解决⽅案,相⽐iOS9他的流程更加繁琐和不可控,在使⽤⽅向上个⼈觉得更适合于直播的⽅向。
iOS10和iOS11屏幕录制
把这两个系统版本放在了⼀起是因为他们⾮常的相近。
1.创建AppExtension
选择File-New-Target,选择如下
下⼀步中勾选⼀下UI(不勾选也是可以的,勾选的话⽅便我们进⾏宿主App的验证)
创建好之后我们会发现⼯程中多了⼀些东西:
上⾯的⽂件夹包含的是主要的功能----录制状态的变化和数据流的获取都在这⾥⾯,下⾯的⽂件夹包含的主要是从选中Sheet的Item到开始录制中
的⼀个过渡VC,在这个VC中你可以加⼊⼀些账号验证或者其他想要做的事情,对整体功能来说可有可⽆。
2.选择AppExtension
在⼏年前,跨App的直播在苹果上是不存在,想做游戏直播⼀般都是电脑或者安卓机。玩过直播App的同学可能留意到,市⾯上的⼀些做直播的
App很多已经提供了直播Extension功能,即只使⽤其App的⼀个Extension功能进⾏跨App的游戏直播。
像下⾯这样这些App都提供了这个功能:
其实在操作完第⼀步之后,我们的App也具备展⽰在Sheet中的能⼒,下⾯我们来布局代码。
iOS10中在需要触发录屏按钮的地⽅触发这个⽅法:
-(void)startREC_showExtension{
[RPBroadcastActivityViewControllerloadBroadcastActivityViewControllerWithHandler:^(RPBroadcastActivityViewController*_NullablebroadcastActivityViewController,N
if(broadcastActivityViewController){
te=lf;
rentationStyle=UIModalPrentationPopover;
[lfprentViewController:broadcastActivityViewControlleranimated:YEScompletion:nil];
}
}];
}
点击之后效果如下:
这个⽅法将加载当前⽀持BroadcastUploadExtension的扩展,RPBroadcastActivityViewController是弹出的Sheet,设置好代理之后之后
我们选中了某个Item就会进⼊到过度的⼀个VC中,就是上⾯图中的BroadcastSetupViewController。
在这个VC中我们可以进⾏宿主App的校验或者账号信息的登陆(因为所有的需要直播的App都能调出我们的这个Extension)。
iOS11中我们可以直接启动对应的item跳过选择这⼀步:
+(void)loadBroadcastActivityViewControllerWithPreferredExtension:(NSString*_Nullable)preferredExtensionhandler:(nonnullvoid(^)(RPBroadcastActivityViewController*
上⾯这个⽅法中preferredExtension参数指的是我们创建的BroadcastVCExtension中的bundleID,你也可以从⼯程----Target----
BroadcastSetupUI(名称可能不⼀样)中找到这个ID。
我们我们操作停当之后需要触发urDidFinishSetup这个⽅法才能回调下⼀步,可以看下这个.m⽂件中urDidFinishSetup这个⽅法:
iOS10
-(void)completeRequestWithBroadcastURL:(NSURL*)broadcastURLbroadcastConfiguration:(RPBroadcastConfiguration*)broadcastConfigurationtupInfo:(nullableNSD
iOS11
-(void)completeRequest二年级我的妈妈
WithBroadcastURL:(NSURL*)broadcastURLtupInfo:(nullableNSDictionary
上⾯两个⼀样的作⽤,表⽰设置完成,urInfo可以传递设置的参数,⽅法完成后触发RPBroadcastActivityViewController的代理如下:
#pragmamarkRPBroadcastActivityViewControllerDelegate
-(void)broadcastActivityViewController:(RPBroadcastActivityViewController*)broadcastActivityViewControllerdidFinishWithBroadcastController:(nullableRPBroadcastCont
dispatch_async(dispatch_get_main_queue(),^{
[broadcastActivityViewControllerdismissViewControllerAnimat寄小读者作者 ed:YEScompletion:nil];
});
astController=broadcastController;
[broadcastControllerstartBroadcastWithHandler:^(NSError*_Nullableerror){
if(!error){
NSLog(@"启动");
}el{
NSLog(@"error:%@",error);
}
}];
}
到此为⽌,我们已经完成了从调出Sheet到触发屏幕录制这个阶段,下⾯进⾏屏幕录制数据流的处理。
请注意,在Extension⽂件中操作的调试需要选择对应的Target,因为他是⼯程中⼀个独⽴的Target,否则⽆法调试
选择Target----选择宿主App----进⾏调试
如下图:
以上⽅法在录屏的时候触发的录屏是在应⽤内,⽐如你下拉⼀下通知栏就会⾃动暂停,再次进⼊App内提⽰会⾃动提⽰你是否继续直播屏幕,⽽
iOS11触发的录屏可以是在App外,进⾏⼀个跨App的屏幕录制,所以iOS能进⾏跨App的录屏是在iOS11之后。
iOS11录屏要想在应⽤外使⽤下⾯的⽅法触发:
⾸先将录屏功能加到控制⾯板⾥:设置-控制中⼼-屏幕录制加上
然后上拉或下划调出控制中⼼,长按录制按钮,调出录屏控制⾯板,选择对应直播功能的Extensio鼠冲什么生肖 n,如下图:
iOS11有⼀组专门对屏幕录制的API,这组API和iOS9上的⼀组⾮常相似,不同的是数据是以流的形式返回,同样的,这组API只能对App内进⾏
屏幕录制,⽆法跨App进⾏录制(任何使App挂起的操作都会打断屏幕录制),好处是避开了Extension,简化了操作。
-(void)startCaptureWithHandler:(nullablevoid(^)(CMSampleBufferRefsampleBuffer,RPSampleBufferTypebufferType,NSError*_Nullableerror))captureHandlercompletio
-(void)stopCaptureWithHandler:(nullablevoid(^)(NSError*_Nullableerror))handlerAPI_AVAILABLE(ios(11.0),tvos(11.0));
两个⽅法⼀个是开始,另⼀个是结束,开始的⽅法中回调了屏幕的数据流,我们需要对这组数据流进⾏编码操作,推流或者保存。如果你只是要进
⾏App内屏幕录制,这组⽅法⽆疑是⾮常好的。
3.流程控制和数据流的采集处理
我们切到第⼀个⽂件夹中的SampleHandle.m⽂件中,可以看到.m中的⽅法分为两部分,⼀部分是对录制流程的控制另⼀部分是数据流的采集新员工评价 。
流程控制这部分代码:
-(void)broadcastStartedWithSetupInfo:(NSDictionary
NSLog(@"1");
//nfofromtheUIextensioncanbesuppliedbutoptional.
}
上⾯这个⽅法是对过度VC中参数的传递,我们可以在这个⽅法中拿到过度页⾯的传值。
-(void)broadcastPaud{
NSLog(@励志的歌曲 "2");
//swillstopbeingdelivered.
}
-(void)broadcastResumed{
NSLog(@"3");
//sdeliverywillresume.
}
-(void)broadcastFinished{
NSLog(@"4");
//Urhasrequestedtofinishthebroadcast.
}
上⾯三个⽅法就很简单了,暂停、恢复和停⽌。
-(void)processSampleBuffer:(CMSampleBufferRef)sampleBufferwithType:(RPSampleBufferType)sampleBufferType{
switch(sampleBufferType){
caRPSampleBufferTypeVideo:
//Handlevideosamplebuffer
break;
caRPSampleBufferTypeAudioApp:
//Handleaudiosamplebufferforappaudio
break;
caRPSampleBufferTypeAudioMic:
//Handleaudiosamplebufferformicaudio
break;
default:
break;
}
}
我们在这个⽅法⾥销售计划书范本 拿到数据流,这⾥的数据流是未编码的,通常情况下如果要做推流或者⽂件保存,我们会将其进⾏⼀个H264的编码。
需要注意的是这个⽅法的回调是有限制的,仅当你的屏幕发⽣了实质性的变化才会触发,如果你的屏幕⼀直静⽌则不会触发,在调试的时候需要多
注意。
数据流的硬编码使⽤VideoToolBox,此处不再过多叙述会另开篇幅。
拿到编码后的流数据我们可以做⼀些推流或者⽂件写⼊的操作。
4.停⽌录屏
在上述App内屏幕录制时想要主动停⽌需要broadcastController调⽤下⾯这个⽅法
-(void)finishBroadcastWithHandler:(void(^)(NSError*_Nullableerror))handler;
(由于App内录制的特殊性,当你的App切换到后台被挂起时会⾃动暂停录制,当你激活App时会收到是否继续直播的提⽰,当你选择否时也会
停⽌录屏。)
录屏停⽌时在SampleHandler.m中会回调下⾯的⽅法:
-(void)broadcastFinished{
NSLog(@"STOP")杀猪菜 ;
//Urhasrequestedtofinishthebroadcast.
}
我们在这个⽅法中可以整理数据和进⾏收尾⼯作。
当你使⽤的是跨App的⽅式进⾏录制的时候,想要主动结束就需要⽤户⼿动点击关闭控制⾯板的录屏按钮(暂时没找到如何在程序中主动关
闭),在SampleHandler的实例⽅法中有⼀个下⾯的⽅法,似乎可以主动关闭录屏(但我测试的时候却⽆法真正关闭),⽽且我不知道如何通知
到这个Extension去关闭录屏(有同学提议⽤进程间通知的⽅式暂时还没尝试),这⾥Mark⼀下。
-(void)finishBroadcastWithError:(NSError*)error;
5.录屏⽂件数据的共享
每个Extension都需要⼀个宿主App,并且有⾃⼰的沙盒,当我们把录屏⽂件保存到沙盒中时宿主App是⽆法获取到的,那么只有采⽤共享的⽅
式才能让宿主App拿到录屏⽂件。
AppGroupShare帮我们解决了这个问题,通过设置组间共享的模式,使得同⼀个Group下⾯的App可以共享资源,解决了沙盒的限制。
到此为⽌,基于iOS10和11的录屏操作已经完整告⼀段落,二毛烧鸡 从中我们就可以看出,想⽤iOS10和11的API去进⾏录屏操作不但反⽤户操作⾏为⽽
且反开发⾏为,冗长的流程和各种限制使得录屏体验⾮常差,所以市⾯上使⽤这套API的⼤部分App只做直播⽅向。
iOS12屏幕录制
到了iOS12,苹果⼜开放了⼀部分API,这使得录屏变得可⾏并且易于操作。
给予我们极⼤帮助的是这个类
RPSystemBroadcastPickerView
点击去看:
@interfaceRPSystemBroadcastPickerView:UIView
/*@tisnilwhichmeansthatallextensionswillbeprented*/
@property(nonatomic,strong,nullable)NSString*preferredExtension;
/*@abstractIntisYES.*/
@property(nonatomic,assign)BOOLshowsMicrophoneButton;
@end
RPSystemBroadcastPickerView继承与UIView只有两个属性,第⼀个表⽰要启动的Extension标识,nil则全部弹出供选择,第⼆个标识是否显
⽰麦克风按钮,如果显⽰并且选择则会把声⾳⼀同录⼊。
_broadPickerView=[[RPSystemBroadcastPickerViewalloc]initWithFrame:CGRectMake(100,100,100,100)];
_redExtension=nil;
[dSubview:_broadPickerView];
请注意,这⾥有⼀点不同,当你preferredExtension=nil时你需要选择要倘若的反义词 ⽤的直播Extension,选择好之后进⼊了10和11对流处理的模式;当你
指定了preferredExtension=@“XXX”的时候,直接开始录制,开发者不进⾏流数据处理,录制完成之后⾃动保存到相册。
对于单纯的录屏来说,指定preferredExtension⽆意是最便捷的⽅式,虽然API并没有暴露录屏开始和结束的回调⽅法,但我们可以将
RPSystemBroadcastPickerView进⾏⼀个响应事件的传递从我们⾃定义的View中传递给RPSystemBroadcastPickerView。当然严格地来说
这样并不能精确地判断,还需要加⼊⼀些逻辑上的检测。例如:
[[RPScreenRecordersharedRecorder]isRecording];
最后总结⼀下,如果需要的只是App内录制,那么iOS9的API、iOS11的不包含Extension的API、iOS12的RPSystemBroadcastPickerView
是⽐较好的选择;如果你需要跨App的录屏,那么建议尽量从iOS12开始⽀持;⽽Extension这种,更多的是为了直播⽽进⾏的服务。
本文发布于:2023-03-18 06:27:41,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/1679092063296004.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:ios10.doc
本文 PDF 下载地址:ios10.pdf
留言与评论(共有 0 条评论) |