视频的录制、截图和压缩

什么是视频录制

视频录制其实就是一个类似于拍电影的过程,通过手机的摄像头和麦克风,录入声音和画面,然后经过一个加工厂加工,然后导出,就变成了我们口中定义的视频。接下来,我会带大家看一下,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";
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容