在使用应用或者游戏的过程中录制回放,一直是iOS开发者绞尽脑汁想要实现的功能。但由于移动设备性能的限制,这一功能往往较难实现或者效果难以满足用户的需要。终于,随着iOS9的发布,苹果提供了ReplayKit框架来帮助开发者实现录制回放的功能。
在iOS 9中,ReplayKit 是一款全新的框架,它可以让玩家更便捷地记录游戏或者应用的画面,录制自己的声音。ReplayKit为用户或者玩家提供了一个全功能的交互界面,用户可用它来编辑或制作自己的视频剪辑。
ReplayKit不需要太大电量损耗和性能损耗就可以产出高清的视频记录。ReplayKit支持使用A7芯片以上,操作系统为iOS 9或更高版本的设备。
1、导入头文件#import
2、检测设备是否支持ReplayKit框架。ReplayKit只有在iOS9上才可以使用,所以使用前需要判断设备是否支持该项功能,然后通过"[RPScreenRecorder sharedRecorder].available"属性我们可以判断RPScreenRecorder是否可以工作。
3、开始录制。
调用RPScreenRecorder的- (void)startRecordingWithMicrophoneEnabled:(BOOL)microphoneEnabled handler:(nullable void(^)(NSError * __nullable error))handler
方法开始录制回放视频。当该方法调用时用户会收到权限请求警告,这个警告每次会在开始录制时出现。然而,一旦用户选择了其中一种偏好设置,系统会在接下来的8分钟记住这个选择。
4、停止录制。
通过调用RPScreenRecorder 的- (void)stopRecordingWithHandler:(nullable void(^)(RPPreviewViewController * __nullable previewViewController, NSError * __nullable error))handler;方法可以停止录制回放视频。在该方法中我们可以获取到一个RPPreviewViewController对象。预览和保存。将得到的RPPreviewViewController对象呈现给用户,就可以让用户预览已经录制的视频,并且自行选择是否保存录像。
1、为了满足让用户或者测试人员在发现问题的时候可以很好的非现场性复现
2、后期可为用户提供功能指导教学视频
开始考虑用第三方提供的录屏sdk进行跨app录屏,经过调研发现有几个问题:
1、提供录屏的sdk太少;
2、有提供的录屏相关功能的应用但是不能跨app进行录制;
3、有录屏功能的demo,但是问题太多,或者实现太复杂,风险太高
由于以上几个原因,并且点评管家最低支持的版本是8.0,而且dau中8.x的用户占比只有1%(900+/10w),故而选择系统源生提供的录屏功能库ReplayKit。
1、给app添加一个类似于AssistiveTouch的window来控制录屏开始和结束,采用单例
2、开启相关权限并录屏,录屏结束后选择上传至腾讯云,同时将视频保存一份至本地相册
全局单例实现透视window
控制透视window显示与否方法:
开始录屏:
结束录屏:
上传至腾讯云:
1、如何获取录屏视频的本地url
由于录屏结束后的回调返回的RPPreviewViewController的实例中存放了视频地址movieUrl,只能在debug状态下打印出来,却无法获取,因为movieUrl没有爆露在头文件。在网上找了好多资料,也看了官方文档,没有找到解决办法,花了好长一段时间一直没有解决此问题。后来尝试去给RPPreviewViewController写category的方式似乎可以获取。所以最终选择下面这个方式去获取:
1、先定义一个category:
2、拿到了movieUrl却拿不到视频,无法上传至腾讯云
由于ReplayKit这个库在录完频后,先把视频保存在replaykit私有下的沙盒里面,其他应用是无法获取的,所以想到以下两种方法去拿真实视频:
(1)先将movieUrl指定的视频保存至指定的沙盒文件,然后将文件上传腾讯云;
(2)将movieUrl指定的视频保存至相册,然后将文件上传至腾讯云。
由于本身功能里面需要我们保存至相册里面,所以决定采用第二种方案,并且由于第一种方案上传的时候缺少一些上传的必须参数,而且设置起来非常麻烦。
保存至本地相册:
3、iOS8.0系统启动crash问题
dyld: Library not loaded: /System/Library/Frameworks/ReplayKit.framework/ReplayKit
原因:代码在编译阶段的时候#import
修复办法:将ReplayKit库在project 下的buildphases下改成optional即可。