ReplayKit是iOS自帶的一個螢幕錄制的架構,其支援應用程式對目前應用内頁面進行錄屏,并将最終的視訊儲存到系統相冊中。ReplayKit在iOS 9之後引入,其接口簡介,可以非常友善的為應用添加錄屏功能。需要注意,在某些iOS 12系統上,開啟錄屏可能會失敗(通常需要重新開機裝置解決)。
在ReplayKit架構中,有兩個非常重要的類,分别是RPScreenRecorder類與RPPreviewViewController類。RPScreenRecorder是錄屏核心功能類,RPPreviewViewController是錄屏結束後的預覽控制器類。
下面,列舉了一個簡單的錄屏示例代碼:
@interface ViewController () <RPScreenRecorderDelegate, RPPreviewViewControllerDelegate>
@end
@implementation ViewController
-
(void)viewDidLoad {
self.view.backgroundColor = [UIColor whiteColor];
[super viewDidLoad];
// 擷取錄屏功能是否可用
NSLog(@"%d", [RPScreenRecorder sharedRecorder].available);
// 設定錄屏代理
[RPScreenRecorder sharedRecorder].delegate = self;
UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
[btn setTitle:@"Start" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(start) forControlEvents:UIControlEventTouchUpInside];
btn.frame = CGRectMake(100, 100, 100, 30);
[self.view addSubview:btn];
UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeSystem];
[btn2 setTitle:@"End" forState:UIControlStateNormal];
[btn2 addTarget:self action:@selector(stop) forControlEvents:UIControlEventTouchUpInside];
btn2.frame = CGRectMake(100, 150, 100, 30);
[self.view addSubview:btn2];
}
-
(void)stop {
// 結束錄屏
[[RPScreenRecorder sharedRecorder] stopRecordingWithHandler:^(RPPreviewViewController _Nullable previewViewController, NSError _Nullable error) {
}];NSLog(@"stopRecordingWithHandler"); if (!error) { previewViewController.previewControllerDelegate = self; // 到視訊預覽控制器 [self presentViewController:previewViewController animated:YES completion:nil]; }
// 開始錄屏
-
(void)start {
[[RPScreenRecorder sharedRecorder] startRecordingWithHandler:^(NSError * _Nullable error) {
NSLog(@"startRecordingWithHandlerError:%@", error);
-
(void)touchesBegan:(NSSet)touches withEvent:(UIEvent )event {
self.view.backgroundColor = [UIColor colorWithRed:arc4random()%255/255.0 green:arc4random()%255/255.0 blue:arc4random()%255/255.0 alpha:1];
// 錄屏結束的回調
-
(void)screenRecorder:(RPScreenRecorder )screenRecorder didStopRecordingWithPreviewViewController:(nullable RPPreviewViewController )previewViewController error:(nullable NSError *)error {
NSLog(@"didStopRecordingWithPreviewViewControllerError:%@", error);
// 錄屏可用性改變的回調
-
(void)screenRecorderDidChangeAvailability:(RPScreenRecorder *)screenRecorder {
NSLog(@"screenRecorderDidChangeAvailability:%d", screenRecorder.available);
// 錄屏預覽控制器的代理回調
-
(void)previewControllerDidFinish:(RPPreviewViewController *)previewController {
[previewController dismissViewControllerAnimated:YES completion:nil];
-
(void)previewController:(RPPreviewViewController )previewController didFinishWithActivityTypes:(NSSet )activityTypes {
NSLog(@"didFinishWithActivityTypes %@", activityTypes);
其中,RPScreenRecorder類中提供了豐富的接口可以使用,列舉如下:
@interface RPScreenRecorder : NSObject
// 擷取單例
- (RPScreenRecorder *)sharedRecorder;
// iOS 10 之前使用,可以通知是否開啟麥克風
- (void)startRecordingWithMicrophoneEnabled:(BOOL)microphoneEnabled handler:(nullable void(^)(NSError * _Nullable error))handler;
// iOS 10 之後使用 開啟錄屏
- (void)startRecordingWithHandler:(nullable void(^)(NSError * _Nullable error))handler;
// 結束錄屏
- (void)stopRecordingWithHandler:(nullable void(^)(RPPreviewViewController _Nullable previewViewController, NSError _Nullable error))handler;
// 放棄錄屏
- (void)discardRecordingWithHandler:(void(^)(void))handler;
// 開啟錄屏,可以擷取到視訊流資料 iOS 11後可用
- (void)startCaptureWithHandler:(nullable void(^)(CMSampleBufferRef sampleBuffer, RPSampleBufferType bufferType, NSError _Nullable error))captureHandler completionHandler:(nullable void(^)(NSError _Nullable error))completionHandler;
// 結束視訊流捕獲
- (void)stopCaptureWithHandler:(nullable void(^)(NSError * _Nullable error))handler;
// 設定代理對象
@property (nonatomic, weak, nullable) id delegate;
// 錄屏功能是否可用
@property (nonatomic, readonly, getter=isAvailable) BOOL available;
// 是否正在錄制中
@property (nonatomic, readonly, getter=isRecording) BOOL recording;
// 是否使用麥克風
@property (nonatomic, getter=isMicrophoneEnabled) BOOL microphoneEnabled;
// 是否可以使用相機
@property (nonatomic, getter=isCameraEnabled) BOOL cameraEnabled;
// 設定攝像頭模式 前置/後置
@property (nonatomic) RPCameraPosition cameraPosition;
// 相機預覽視圖
@property (nonatomic, readonly, nullable) UIView *cameraPreviewView;
在錄屏的時候,也支援調用系統的麥克風和攝像頭共同完成錄制。RPScreenRecorderDelegate協定中定義了一些回調方法,如下:
// 停止錄屏後的回調 iOS 10 之前使用
- (void)screenRecorder:(RPScreenRecorder )screenRecorder didStopRecordingWithError:(NSError )error previewViewController:(nullable RPPreviewViewController *)previewViewController;
// 停止錄屏後的回調 iOS 10 之後使用
- (void)screenRecorder:(RPScreenRecorder )screenRecorder didStopRecordingWithPreviewViewController:(nullable RPPreviewViewController )previewViewController error:(nullable NSError *)error;
// 錄屏權限更改的回調
- (void)screenRecorderDidChangeAvailability:(RPScreenRecorder *)screenRecorder;
RPPreviewViewController類是視訊預覽控制器類,這個控制器沒有暴露太多的屬性給開發者使用,其中預覽模式可以選擇分享模式或編輯模式,除此之外,其中還提供了一個代理協定給開發者進行使用,用來對使用者的操作進行處理,如下:
@protocol RPPreviewViewControllerDelegate
@optional
// 預覽結束
- (void)previewControllerDidFinish:(RPPreviewViewController *)previewController;
// 使用者行為回調
- (void)previewController:(RPPreviewViewController )previewController didFinishWithActivityTypes:(NSSet )activityTypes;