视频的录制、截图和压缩

什么是视频录制

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

iOS如何进行视频录制

  1. 视频录制需要导入一个框架--AVFoundation框架
#import 
  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 
  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 ()  
实现方法:
// MARK: - delegate方法
// 选择照片或者是视频时 调用
// info:  相关参数
  - (void)imagePickerController:(UIImagePickerController *)pickerdidFinishPickingMediaWithInfo:(NSDictionary *)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";

你可能感兴趣的:(视频的录制、截图和压缩)