因为项目里刚好需要录制屏幕的功能,就找了下iOS上的录制相关的SDK,由于我们的录制需求比较简单,所以选择官方的ReplayKit。
ReplayKit是苹果官方很晚(iOS 9)才推出的录制屏幕的SDK,所以整个SDK显得比较简单,而且可自定义的程度很低。如果你的APP只是需要录制功能,对界面和功能方面没有特别高的要求,那么这个SDK才会适合。
具体实现:
开始录制
- (void)beginRecord {
RPScreenRecorder* recorder = RPScreenRecorder.sharedRecorder;
if(!recorder.isAvailable) {
[self postMessage:@"您的手机无法使用录制功能"];
return;
}
if(recorder.isRecording) {
[self postMessage:@"正在录制中,请先暂停"];
return;
}
recorder.microphoneEnabled = YES;
recorder.cameraEnabled = YES; //录制期间摄像头和麦克风都保持开启状态
if (@available(iOS 10.0, *)) { //iOS9和iOS10的启动方法都是不一样的
[recorder startRecordingWithHandler:^(NSError * _Nullable error) {
if (!error) {
NSLog(@"启动成功");
}
}];
} else {
if (@available(iOS 9.0, *)) {
[recorder startRecordingWithMicrophoneEnabled:YES handler:^(NSError * _Nullable error) {
if (!error) {
NSLog(@"启动成功");
}
}];
}
}
}
通过kvo方式监听什么时候正式启动,启动时间和手机有关,不过都还是挺快的:
- (void)addRecordObserver {
RPScreenRecorder* recorder = RPScreenRecorder.sharedRecorder;
[recorder addObserver:self forKeyPath:@"recording" options:NSKeyValueObservingOptionNew context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
if([keyPath isEqualToString:@"recording"]) {
RPScreenRecorder* recorder = RPScreenRecorder.sharedRecorder;
if(recorder.isRecording) {
# 注意: ReplayKit的相关方法基本都不是在主线程执行,操作UI需要切换到主线程。
dispatch_async(dispatch_get_main_queue(), ^{
[_recordStartButton setTitle:@"录制中" forState:UIControlStateNormal];
_recordStartButton.backgroundColor = [UIColor redColor];
});
}
else {
dispatch_async(dispatch_get_main_queue(), ^{
_recordStartButton.backgroundColor = [UIColor whiteColor];
[_recordStartButton setTitle:@"录制" forState:UIControlStateNormal];
});
}
}
}
停止录制
- (void)recordStopClicked {
RPScreenRecorder* recorder = RPScreenRecorder.sharedRecorder;
if(!recorder.isRecording) {
return;
}
__weak typeof(self) weakSelf = self;
[recorder stopRecordingWithHandler:^(RPPreviewViewController * _Nullable previewViewController, NSError * _Nullable error) { //RPPreviewViewController是录制之后的预览界面
if(!error) {
[weakSelf showVideoPreviewController:previewViewController withAnimation:YES];
}
NSLog(@"已停止录屏");
}];
}
- (void)showVideoPreviewController:(RPPreviewViewController *)previewController withAnimation:(BOOL)animation {
previewController.previewControllerDelegate = self; //设置预览界面代理,主要是按钮点击后的回调
[self presentViewController:previewController animated:YES completion:^{
}];
}
实现代理方法:
#代理方法也很不友好,
#两个方法在点击保存和取消按钮的时候都会触发
#第二个方法可以知道点击了按钮的类型,但是每次都会携带曾经点击过得所有按钮的Types,所以很难对每个事件进行单独处理。
- (void)previewControllerDidFinish:(RPPreviewViewController *)previewController {
[previewController dismissViewControllerAnimated:YES completion:nil];
}
- (void)previewController:(RPPreviewViewController *)previewController didFinishWithActivityTypes:(NSSet <NSString *> *)activityTypes {
dispatch_async(dispatch_get_main_queue(), ^{
if ([activityTypes containsObject:@"com.apple.UIKit.activity.SaveToCameraRoll"]) { //点击了保存按钮
NSLog(@"已保存到相册");
}
});
}
总结
ReplayKit还很不成熟,优缺点也很明显。
优点:
1、使用简单,代码量很少。
2、性能高,录制期间感觉不到任何影响。
3、视频质量好,大小也能接受,iPhoneXS录制的7秒视频容量大概是500KB。
缺点:
1、自定义程度低,预览界面完全无法自定义。
2、开放方法很少,甚至连录制后的视频URL都没开放,不过知道属性名可以通过分类获取到,也可以通过KVC获取。
2、录制有时候会启动不了,此时可以测试系统自带的录制功能,如果也不行,那就只能重启手机,没有其他方案。