美文网首页iOS今日看点iOS开发
视频的录制、截图和压缩

视频的录制、截图和压缩

作者: Jimmy_P | 来源:发表于2016-12-30 14:25 被阅读564次

    什么是视频录制

    视频录制其实就是一个类似于拍电影的过程,通过手机的摄像头和麦克风,录入声音和画面,然后经过一个加工厂加工,然后导出,就变成了我们口中定义的视频。接下来,我会带大家看一下,iOS中的视频录制到底是怎么做的,让大家能初步地写出一个录制视频的小demo。当然,还会教大家怎么进行视频图像的捕获还有压缩。

    iOS如何进行视频录制

    1. 视频录制需要导入一个框架--AVFoundation框架
    #import <AVFoundation/AVFoundation.h>
    
    1. 根据前言的分析,所以我们需要设置四个属性来进行视频录制的相关配置
    //输入声音     
    @property (nonatomic, strong) AVCaptureDeviceInput *inputAudio; 
    //输入画面     
    @property (nonatomic, strong) AVCaptureDeviceInput *inputVideo; 
    //会话属性     
    @property (nonatomic, strong) AVCaptureSession *session;
    //导出   
    @property (nonatomic, strong) AVCaptureMovieFileOutput *output;
    
    1. 我们就做一个简单点的demo,在touchesBegan方法中进行视频录制相关操作
        // 3.创建对象,并且实例化
        // 3.1创建一个设备
        // 声音
       AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
       self.inputAudio = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:nil];
       
       // 3.2画面
       AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
       
       self.inputVideo = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:nil];
       
       // 3.3会话
       self.session = [[AVCaptureSession alloc] init];
       
       // 3.4 导出
       self.output = [[AVCaptureMovieFileOutput alloc] init];
    
    1. 添加到加工厂(输入&输出)
        if ([self.session canAddInput:self.inputAudio]) {
            [self.session addInput:self.inputAudio];
        }
        if ([self.session canAddInput:self.inputVideo]) {
            [self.session addInput:self.inputVideo];
        }
        if ([self.session canAddOutput:self.output]) {
            [self.session addOutput:self.output];
        }
        // 添加一个预览的图层
        AVCaptureVideoPreviewLayer *prelayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
        prelayer.frame = self.view.bounds;
    //    [self.view.layer addSublayer:prelayer];
        [self.view.layer insertSublayer:prelayer atIndex:0];
    
    1. 开启加工厂
        [self.session startRunning];
    
    1. 添加视频录制开关按钮
      // 视频录制的开关
     - (IBAction)startOrClose:(id)sender {
        if ([self.output isRecording]) {
            // 正在录制
            [self.output stopRecording];
        } else {
            // 没有录制
            // 获取沙盒路径,用于存储
            NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"录制的视频.mov"];
            // 开始录制
            [self.output startRecordingToOutputFileURL:[NSURL fileURLWithPath:path] recordingDelegate:self];
        }
     }
    
    1. 监听视频录制的进度
     #pragma mark - AVCaptureFileOutputRecordingDelegate
      - (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error;
    {
        NSLog(@"完成录制");
    }
     - (void)captureOutput:(AVCaptureFileOutput *)captureOutput didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections
    {
        NSLog(@"开始录制");
    }
    

    为什么需要做视频截图

    视频截图就是截取视频播放中的某一帧(关键帧)画面。
    有时候当我们观看视频的时候,或者观看直播的时候,看到一些好玩,有趣的画面需要和朋友进行分享的时候,就要用到视频截图这个功能了。
    下面,我们一起来看一下如何进行视频截图。

    如何进行视频截图

    1. 导入框架
    #import <AVFoundation/AVFoundation.h>
    
    1. 核心代码
       创建视频资源对象
         // 1.1获取资源的url
          NSURL *url = [[NSBundle mainBundle] URLForResource:@"movie.mp4" withExtension:nil];
        
          // 1.2对url进行封装
          AVAsset *asset = [AVAsset assetWithURL:url];
    
          // 1.创建一个视频截取的截取器
          AVAssetImageGenerator *generator = [AVAssetImageGenerator assetImageGeneratorWithAsset:asset];
        
          // <#int64_t value#>:    截取的时间
          // <#int32_t timescale#>: 每秒播放多少帧
          CMTime time = CMTimeMake(23, 1);
          NSValue *value = [NSValue valueWithCMTime:time];
    
        [generator generateCGImagesAsynchronouslyForTimes:@[value] completionHandler:^(CMTime requestedTime, CGImageRef  _Nullable image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError * _Nullable error) {
            // UI的更新一定要在主线程进行,要不然不能够时时获得更新
            dispatch_sync(dispatch_get_main_queue(), ^{
                self.picImageView.image = [UIImage imageWithCGImage:image];
            });
        }];
    

    为什么要进行视频压缩

    通常录制出来的原视频都会很大,如果不压缩就进行上传,一个是浪费用户的流量,二个会造成上传时间过长,影响用户体验。

    如何进行视频压缩

    1. 获取视频的位置-------相册

    2. 创建相册控制器对象,访问相册

    // 创建访问相册的控制器对象
     UIImagePickerController *picker = [[UIImagePickerController alloc]
    init];
    
    1. 访问相册之前,需要判断是否存在相册
      // 0. 判断是否有相册
      if (![UIImagePickerController
    isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum])
    {NSLog(@" ");
    return;}
    
    1. 弹出控制器
    [self presentViewController:picker animated:YES completion:nil];
    
    1. 访问相册可以通过不同的方式,改变的方法为:
    设置他的资源类型
    /**
     UIImagePickerControllerSourceTypePhotoLibrary, //照片库   UIImagePickerControllerSourceTypeCamera,   //照相机
     UIImagePickerControllerSourceTypeSavedPhotosAlbum //相册
    */
    
     picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
    
    1. 可以看到,相册中没有视频,这是因为需要设置 媒体类型才能看到
    //  设置媒体类型
     picker.mediaTypes = [UIImagePickerControlleravailableMediaTypesForSourceType:UIImagePickerControllerSourceTypeSavedPhotosAlbum];
    
    1. 看到视频后,我们需要拿到该视频,才能进行压缩操作,所以需要设置代理
    picker.delegate = self;
    

    并且遵守协议

     @interface ViewController ()  <UINavigationControllerDelegate,UIImagePickerControllerDelegate>
    实现方法:
    // MARK: - delegate方法
    // 选择照片或者是视频时 调用
    // info:  相关参数
      - (void)imagePickerController:(UIImagePickerController *)pickerdidFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info;
    
     // 选择 取消时 调用
      - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker;
    
    1. 打印代理方法中的info这个参数,可以看到里面包含该视频的地址, 接收该地址
    NSLog(@"%@",info);
    NSURL *url = info[UIImagePickerControllerMediaURL];
    
    1. 视频压缩的原理: 把视频用低质量导出
    • 创建视频资源对象
    // asset :资源
     AVAsset *asset = [AVAsset assetWithURL:url];
    
    • 创建视频导出会话
    /**
     AVAssetExportPresetLowQuality       //低质量
     AVAssetExportPresetMediumQuality//中质量
     AVAssetExportPresetHighestQuality//高质量
    */
    //  创建视频导出会话
    // presetName :  视频导出质量
    
     AVAssetExportSession *session = [AVAssetExportSessionexportSessionWithAsset:asset presetName:AVAssetExportPresetLowQuality];
    
    • 导出视频:
    //  导出
    [session exportAsynchronouslyWithCompletionHandler:^{NSLog(@" ");
    }];
    
    • 导出视频之前,需要我们确定导出到哪里
    获取沙盒路径//  
     NSString *filePath =[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) lastObject]stringByAppendingPathComponent:@"123.mp4"];
    //  session.outputURL = [NSURL fileURLWithPath:filePath];
    
    • 演示视频导出, 报错, 查看原因,发现视频导出错的原因是没有设置视频导出的类型根据属性介绍,可以看到需要查看session.supportedFileTypes属性,打印该属性
     // NSLog(@"%@",session.supportedFileTypes); 
    /**
    "com.apple.quicktime-movie", quicktime-movie 类型 
    "public.mpeg-4"              mp4 类型
    */
    
      // 视频导出的文件类型
     session.outputFileType = @"public.mpeg-4";
    

    相关文章

      网友评论

        本文标题:视频的录制、截图和压缩

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