ReplayKit是苹果在iOS 9/tvOS 10推出的一个录制iOS设备屏幕的框架.由于和AirPlay用到了相同的技术,以及ReplayKit在系统中是一个录制进程,所以AirPlay和ReplayKit不能同时生效,以及其他的App开启ReplayKit的时候本App不能开启.
因为是iOS 9/tvOS 10开始的框架,并且每个版本基本上都有一些改动.所以我准备将此篇博客拆分为几篇来介绍.
iOS 9
在iOS 9
中ReplayKit还是比较简单的一个框架,在苹果的Session中是作为GameKit
的一个扩充来介绍的(主要功能就是为了录制游戏视频)
导入ReplayKit头文件
#import <ReplayKit/ReplayKit.h>
/// 录制视频用到的类
RPScreenRecorder
属性
RPScreenRecorder的代理
@property (nonatomic, weak, nullable) id<RPScreenRecorderDelegate> delegate;
/// 是否支持录制属性,也可以通过`delegate`去监听变化
@property (nonatomic, readonly, getter=isAvailable) BOOL available;
/// 是否正在录制,支持KVO监听
@property (nonatomic, readonly, getter=isRecording) BOOL recording;
/* @abstract Specify or query whether the microphone should be enabled during recording. Can be used for key value observing. Default is NO. */
/// 录制时是否开启麦克风(设备麦克风,录制音频).默认是NO.
@property (nonatomic, getter=isMicrophoneEnabled) BOOL microphoneEnabled API_UNAVAILABLE(tvos);
方法
/// 开始录制
- (void)startRecordingWithMicrophoneEnabled:(BOOL)microphoneEnabled handler:(nullable void(^)(NSError * _Nullable error))handler API_DEPRECATED("Use microphoneEnabaled property", ios(9.0, 10.0));
/// 停止录制
- (void)stopRecordingWithHandler:(nullable void(^)(RPPreviewViewController * _Nullable previewViewController, NSError * _Nullable error))handler;
/// 只能在stopRecordingWithHandler后执行此方法来丢弃录制的录像
- (void)discardRecordingWithHandler:(void(^)(void))handler;
RPScreenRecorderDelegate代理
/// 当因为错误或者是可用性更改而停止录制时会调用这个方法
- (void)screenRecorder:(RPScreenRecorder *)screenRecorder didStopRecordingWithError:(NSError *)error previewViewController:(nullable RPPreviewViewController *)previewViewController API_DEPRECATED("No longer supported", ios(9.0, 10.0), tvos(10.0,10.0));
/// 可用性更改(可能是开始录制)将会调用此方法
- (void)screenRecorderDidChangeAvailability:(RPScreenRecorder *)screenRecorder;
RPPreviewViewControllerDelegate (视频编辑VC)
属性
/// 代理
@property (nonatomic, weak, nullable) id<RPPreviewViewControllerDelegate>previewControllerDelegate;
RPPreviewViewControllerDelegate代理
/// 当这个预览(我比较喜欢称之为预览)Vc被释放时调用
- (void)previewControllerDidFinish:(RPPreviewViewController *)previewController;
/// 当取消/完成/保存按钮点击后会调用此方法
- (void)previewController:(RPPreviewViewController *)previewController didFinishWithActivityTypes:(NSSet <NSString *> *)activityTypes __TVOS_PROHIBITED;
**说明:**如果打开了RPPreviewViewController然后上面应该是取消,存储.不过,如果点击了左下角的分享的按钮,不论是否分享,左上角都会变成完成.
如果是取消,那么点击后的type应该是nil.存储的type是
UIActivityTypeSaveToCameraRoll
.分享的type是UIActivityTypeCopyToPasteboard
.这些type定义在<UIKit/UIActivity.h>
中
使用
因为iOS 9以上才支持,所以需要检测一下
if (@available(iOS 9.0, *)) {//code}
/// MARK: 录制有关
- (void)startOrStopRecord {
RPScreenRecorder *recorder = [RPScreenRecorder sharedRecorder];
recorder.delegate = self;
if (recorder.isAvailable) {
if (!recorder.isRecording) {
[recorder startRecordingWithMicrophoneEnabled:recorder.isMicrophoneEnabled?YES:NO handler:^(NSError * _Nullable error) {
if (error) {
NSLog(@"%@" ,error.description);
}
}];
} else {
[recorder stopRecordingWithHandler:^(RPPreviewViewController * _Nullable previewViewController, NSError * _Nullable error) {
if (!error) {
previewViewController.previewControllerDelegate = self;
[self presentViewController:previewViewController animated:YES completion:^{
}];
} else {
[recorder discardRecordingWithHandler:^{
}];
}
}];
}
} else {
NSLog(@"un available");
}
}
// MARK: 预览视图处理
- (void)previewControllerDidFinish:(RPPreviewViewController *)previewController {
[previewController dismissViewControllerAnimated:YES completion:^{
}];
}
- (void)previewController:(RPPreviewViewController *)previewController didFinishWithActivityTypes:(NSSet <NSString *> *)activityTypes __TVOS_PROHIBITED {
NSString *activityType = activityTypes.anyObject;
if ([activityType isEqualToString:UIActivityTypeSaveToCameraRoll]) {
/// 点击右边的存储
} else if ([activityType isEqualToString:UIActivityTypeCopyToPasteboard]) {
/// 分享完后点击了完成按钮
}
}
/// MARK: RPScreenRecorderDelegate
- (void)screenRecorder:(RPScreenRecorder *)screenRecorder didStopRecordingWithError:(NSError *)error previewViewController:(nullable RPPreviewViewController *)previewViewController API_DEPRECATED("No longer supported", ios(9.0, 10.0), tvos(10.0,10.0)) {
}
- (void)screenRecorderDidChangeAvailability:(RPScreenRecorder *)screenRecorder {
}
注意事项
ReplayKit在我看来是有设计缺陷的,就是ReplayKit是系统的一个进程负责录制的,有时候可能程序崩溃还是啥,然后想继续录制就会出现不能录制的情况,除非重启,不能解决这个问题.在隐私情况下,虽说我们将
startRecordingWithMicrophoneEnabled:
设置为YES.然后不设置info.plist中的麦克风权限Privacy - Microphone Usage Description
,ReplayKit录屏提醒我们选择有麦克风也不会有麦克风的声音(奇怪的是也不会报错…)