视频录制一 UIImagePickerController

2017-10-24  本文已影响15人  成语笔记

短视频录制方法有很多,其中UIImagePickerController录制视频是系统封装好的,相对比较简单,不需要管理输入流和输出流以及相关的设备,只需要获取相应的录制结果即可,录制的画质也可以设置。利用这种方式录制视频中UI可以自己重新设置也可以用系统提供的UI(个人感觉系统提供的相对还不错)

  1. 录制视频的大致思路
注意:在开始之前需要在plist文件中添加几个权限,这也是在APP访问手机的相机相册时候需要添加的权限
1、Privacy - Camera Usage Description 使用相机
2、Privacy - Microphone Usage Description 使用麦克风
3、Privacy - Photo Library Usage Description 使用相册

以下是实现UIImagePickerController录制视频的部分

引入头文件

#import <MobileCoreServices/MobileCoreServices.h>
#import <AVFoundation/AVFoundation.h>

引入代理以及设置相关的属性

@interface AVImagePickerController ()<UINavigationControllerDelegate,UIImagePickerControllerDelegate>
@property(nonatomic,strong)UIImagePickerController * pickerView;
@property(nonatomic,assign)BOOL isVideo;
@property(nonatomic,strong) NSURL * videoURL;
@property(nonatomic,strong) UIView * camereaFace;
@property(nonatomic,assign) BOOL isCameraSupport;
@property(nonatomic,assign) BOOL isRearSupport;
@property(nonatomic,assign) BOOL isFontSupport;
@end

这是刚开始进入时候的页面,里边有两个按钮

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    UIButton * btn = [UIButton buttonWithType:UIButtonTypeSystem];
    [btn setTitle:@"录制" forState:UIControlStateNormal];
    btn.frame = CGRectMake(100, 100, 40, 40);
    [btn addTarget:self action:@selector(btnClick) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn];
    
    UIButton * btn1 = [UIButton buttonWithType:UIButtonTypeSystem];
    [btn1 setTitle:@"拍照" forState:UIControlStateNormal];
    btn1.frame = CGRectMake(100, 150, 40, 40);
    [btn1 addTarget:self action:@selector(btnClick1) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn1];
   
}
-(void)btnClick
{
    _isVideo = YES;
    //这里需要判断相机是否能正常使用
     if (self.isCameraSupport)
    {
        [self presentViewController:self.pickerView animated:YES completion:nil];
    }
}
-(void)btnClick1
{
    _isVideo = NO;
    //判断相机是否能正常使用
     if (self.isCameraSupport)
    {
        [self presentViewController:self.pickerView animated:YES completion:nil];
    }
}

视频录制结束以后会调用该方法

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
    //根据info中的属性获取数据的类型
    NSString * mediaType = [info objectForKey:UIImagePickerControllerMediaType];

    //kUTTypeImage 属于照片格式的一种
    if ([mediaType isEqualToString:(NSString * )kUTTypeImage]) {

        UIImage * image;

        if (self.pickerView.allowsEditing)//如果是编辑过的
        {
            image = [info objectForKey:UIImagePickerControllerEditedImage];
        }else
        {
            image = [info objectForKey:UIImagePickerControllerOriginalImage];
        }

        //保存到相册当中
        UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);

    //kUTTypeVideo 属于视频格式的一种
    }else if ([mediaType isEqualToString:(NSString *)kUTTypeVideo])
    {
        if (@available(iOS 11.0, *)) {
            //获取视频路径
            NSURL * url = [info objectForKey:UIImagePickerControllerImageURL];

            NSString * urlString = [url path];

            //保存视频到相册中
            if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(urlString)) {
                UISaveVideoAtPathToSavedPhotosAlbum(urlString, self, @selector(video:didFinishSavingWithError:contextInfo:), nil);

            }
        } else {
            // Fallback on earlier versions
        }
    }
}

视频保存后的回调

- (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{

    //将压缩后的文件保存到沙河路径当中,将来可以删除
    NSString * pathDocuments = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString * newVideoPath = [NSString stringWithFormat:@"%@/Image",pathDocuments];
    
    [self convertVideoQuailtyWithInputURL:[NSURL URLWithString:videoPath] outputURL:[NSURL URLWithString:newVideoPath]];
}

压缩视频

- (void) convertVideoQuailtyWithInputURL:(NSURL*)inputURL
                               outputURL:(NSURL*)outputURL
{
    //转码配置
    AVURLAsset * avAsset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
    
    AVAssetExportSession * exportSession = [[AVAssetExportSession alloc] initWithAsset:avAsset presetName:AVAssetExportPresetMediumQuality];
    
    exportSession.outputURL = outputURL;
    
    exportSession.outputFileType = AVFileTypeMPEG4;
    
    exportSession.shouldOptimizeForNetworkUse = YES;
    
    [exportSession exportAsynchronouslyWithCompletionHandler:^{
        switch (exportSession.status) {
            case AVAssetExportSessionStatusUnknown:
            {
                
            }
                break;
            case AVAssetExportSessionStatusCompleted:
            {
                //转码成功
                  NSData *data = [NSData dataWithContentsOfFile:outputURL];
                
                //将缓存删掉
                NSFileManager * file  = [NSFileManager defaultManager];
                [file removeItemAtPath:[outputURL path] error:nil];
                
            }
                break;
                
            default:
                break;
        }
    }];
}

初始化展示页面(在手机上显示相头拍到的内容)

#pragma mark - Getter and Setter
-(UIImagePickerController *)pickerView
{
    if (_pickerView == nil) {
        _pickerView = [[UIImagePickerController alloc] init];

        //imagePick 的来源,设置为相头
        _pickerView.sourceType = UIImagePickerControllerSourceTypeCamera;
        //使用哪个相头(后像头)
        _pickerView.cameraDevice = UIImagePickerControllerCameraDeviceRear;

        if (_isVideo) {
            _pickerView.mediaTypes = @[(NSString *)kUTTypeMovie];
            //拍照的质量
            _pickerView.videoQuality = UIImagePickerControllerQualityTypeIFrame1280x720;
            //设置摄像头模式
            _pickerView.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;
            //设置散光灯
            _pickerView.cameraFlashMode = UIImagePickerControllerCameraFlashModeAuto;
            //设置录制的最大时间
            _pickerView.videoMaximumDuration = 3;
        }else
        {
            _pickerView.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
        }
        _pickerView.allowsEditing = YES;//允许编辑(拍完之后添加一个方形的边框进行筛选)
        _pickerView.delegate = self;

        //该方法可将系统自带的UI关掉,自己进行UI设计,将设计好的view赋值给_pickerView的cameraOverlayView 属性即可,其中当关闭系统UI的时候会导致开始录制按钮和停止的按钮消失不见,此时可通过调用[_pickerView startVideoCapture]方法即可开始录制视频,再调用[_pickerView stopVideoCapture]可以停止录像
        //_pickerView.showsCameraControls = NO;
    }
    return _pickerView;
}

是否支持使用相机

-(BOOL)isCameraSupport
{
    return [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
}

是否支持使用后置相头

-(BOOL)isRearSupport
{
    return [UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceRear];
}

是否支持前置相头

-(BOOL)isFontSupport
{
    return [UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceFront];
}
  1. 如果想自定义UI的话,可以设置pickerView的showsCameraControls属性为NO,然后将自定义的View赋值给pickerView的cameraOverlayView属性即可,其中
 [_pickerView startVideoCapture];为录制视频
 [_pickerView stopVideoCapture];为停止视频录制
  1. UIImagePickerController静态方法判断设备是否支持照相机/图片库/相册功能
/*
 typedef NS_ENUM(NSInteger, UIImagePickerControllerSourceType) {
 UIImagePickerControllerSourceTypePhotoLibrary,
 UIImagePickerControllerSourceTypeCamera,
 UIImagePickerControllerSourceTypeSavedPhotosAlbum
 };
 */
BOOL isCameraSupport = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
  1. UIImagePickerController静态方法判断设备是否支持前置摄像头/后置摄像头
/*
 typedef NS_ENUM(NSInteger, UIImagePickerControllerCameraDevice) {
 UIImagePickerControllerCameraDeviceRear,
 UIImagePickerControllerCameraDeviceFront
 };
 */
BOOL isRearSupport = [UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceRear];
  1. UIImagePickerController静态方法判断设备是否支持前置摄像头闪光灯/后置摄像头闪光灯
/*
 typedef NS_ENUM(NSInteger, UIImagePickerControllerCameraDevice) {
 UIImagePickerControllerCameraDeviceRear,
 UIImagePickerControllerCameraDeviceFront
 };
 */
BOOL isFlushSupport = [UIImagePickerController isFlashAvailableForCameraDevice:UIImagePickerControllerCameraDeviceRear];
上一篇下一篇

猜你喜欢

热点阅读