录屏模块使用逻辑:
- 初始化录屏
- 开始用就完事了
实际开发应用
一. 初始化录屏
为了能在刚进到页面的时候就弹出权限提示,所以在视图出现的时候就初始化录屏模块
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self initScreenRecord];
}
#pragma mark - 录屏
- (void)initScreenRecord {
// 相机权限
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if (authStatus == AVAuthorizationStatusRestricted || authStatus ==AVAuthorizationStatusDenied) {
//无权限 需要跳转到设置里开启权限
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
}
} else {
// 录屏
if (![[RPScreenRecorder sharedRecorder] isAvailable]) {
// 无法开启录屏功能
} else {
NSLog(@"开始录屏了");
}
}
}
二、开始录屏
- (void)startScreenRecord:(void(^)(void))successRecord {
RPScreenRecorder *recorder = [RPScreenRecorder sharedRecorder];
recorder.microphoneEnabled = YES;
// 开始
[recorder startRecordingWithHandler:^(NSError * _Nullable error) {
if (error) {
// 无法开启录屏功能
} else {
successRecord();
}
}];
}
三. 停止录屏
- (void)stopScreenRecord {
if ([[RPScreenRecorder sharedRecorder] isRecording]) {
[[RPScreenRecorder sharedRecorder] stopRecordingWithHandler:nil];
}
}
四. 带存储的停止录屏
- (void)stopScreenRecoderWithSave {
if ([RPScreenRecorder sharedRecorder].isRecording) {
if (@available(iOS 14.0, *)) {
NSDateFormatter *dateformat = [NSDateFormatter new];
[dateformat setDateFormat:@"yyyy_MM_dd_HH_mm_ss"];
//文件名
NSString *fileName = [NSString stringWithFormat:@"record_screen_%@.mp4",[dateformat stringFromDate:[NSDate date]]];
NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *dirPath = [documentDirectory stringByAppendingPathComponent:@"record_screen_video"];
if (![[NSFileManager defaultManager] fileExistsAtPath:dirPath]) {
[[NSFileManager defaultManager] createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:nil error:nil];
}
NSString *filePath = [dirPath stringByAppendingPathComponent:fileName];
[[RPScreenRecorder sharedRecorder] stopRecordingWithOutputURL:[NSURL fileURLWithPath:filePath] completionHandler:^(NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
// 存储视频
UISaveVideoAtPathToSavedPhotosAlbum(filePath, self, @selector(video:didFinishSavingWithError:contextInfo:), nil);
});
}];
} else{
[[RPScreenRecorder sharedRecorder] stopRecordingWithHandler:^(RPPreviewViewController *previewViewController, NSError * error){
dispatch_async(dispatch_get_main_queue(), ^{
if (!error && [previewViewController respondsToSelector:@selector(movieURL)]) {
NSURL *videoURL = [previewViewController.movieURL copy];
BOOL compatible = UIVideoAtPathIsCompatibleWithSavedPhotosAlbum([videoURL path]);
if (videoURL && compatible) {
NSString *moviePath = [videoURL path];
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(moviePath)) {
// 存储视频
UISaveVideoAtPathToSavedPhotosAlbum(moviePath, self, @selector(video:didFinishSavingWithError:contextInfo:), nil);
}
} else {
// 未成功保存视频
}
} else {
// 未成功保存视频
}
});
}];
}
} else {
// 录屏失败
}
}
五. 取视频操作 (带压缩操作)
//保存视频完成之后的回调
- (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
if (error) {
// 未成功保存视频
} else {
//取出这个视频
PHFetchOptions *options = [[PHFetchOptions alloc] init];
options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]]; //按创建日期获取
PHFetchResult *assetsFetchResults = [PHAsset fetchAssetsWithOptions:options];
PHAsset *phasset = [assetsFetchResults lastObject];
if (phasset) {
if (phasset.mediaType == PHAssetMediaTypeVideo) {
//是视频文件
PHImageManager *manager = [PHImageManager defaultManager];
[manager requestAVAssetForVideo:phasset options:nil resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
AVURLAsset *urlAsset = (AVURLAsset *)asset;
NSURL *videoURL = urlAsset.URL;
NSDate* date = [NSDate dateWithTimeIntervalSinceNow:0];
NSTimeInterval time = [date timeIntervalSince1970] * 1000;
NSString *timeString = [NSString stringWithFormat:@"%.0f", time];
NSString *fileName = [NSString stringWithFormat:@"%@_%@",@"tmp",timeString];
dispatch_async(dispatch_get_main_queue(), ^{
NSString *outPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:[fileName stringByAppendingString:@".mp4"]];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:videoURL options:nil];
AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetMediumQuality];
session.outputURL = [NSURL fileURLWithPath:outPath];
session.outputFileType = AVFileTypeMPEG4; //压缩格式
[session exportAsynchronouslyWithCompletionHandler:^(void)
{
// 视频压缩工具
if (session.status == AVAssetExportSessionStatusCompleted) {
dispatch_async(dispatch_get_main_queue(), ^{
//视频已处理好可以对其进行操作
NSData *data = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:outPath]];
if (data) {
// 可以上传视频了
}
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
// 未成功保存视频
});
}
}];
});
}];
} else {
// 未成功保存视频
}
} else {
// 未成功保存视频
}
}
}
最后附上大佬原文链接:https://blog.csdn.net/CXLiao/article/details/123197749