美文网首页
视频录制一 UIImagePickerController

视频录制一 UIImagePickerController

作者: 成语笔记 | 来源:发表于2017-10-24 22:57 被阅读15次

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

    1. 录制视频的大致思路
    • 创建捕捉会话
    • 设置视频的输入
    • 设置音频的输入
    • 输出源设置,这里视频,音频数据会合并到一起输出,在代理方法中国也可以单独拿到视频或者音频数据,给AVCaptureMovieFileOutput指定路径,开始录制之后就会向这个路径写入数据
    • 添加视频预览层
    • 开始采集数据,这个时候还没有写入数据,用户点击录制后就可以开始写入数据
    注意:在开始之前需要在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];
    

    相关文章

      网友评论

          本文标题:视频录制一 UIImagePickerController

          本文链接:https://www.haomeiwen.com/subject/mihfpxtx.html