視頻的錄制、截圖和壓縮

什么是視頻錄制

視頻錄制其實(shí)就是一個(gè)類似于拍電影的過程,通過手機(jī)的攝像頭和麥克風(fēng),錄入聲音和畫面,然后經(jīng)過一個(gè)加工廠加工,然后導(dǎo)出,就變成了我們口中定義的視頻。接下來,我會帶大家看一下,iOS中的視頻錄制到底是怎么做的,讓大家能初步地寫出一個(gè)錄制視頻的小demo。當(dāng)然,還會教大家怎么進(jìn)行視頻圖像的捕獲還有壓縮。

iOS如何進(jìn)行視頻錄制

  1. 視頻錄制需要導(dǎo)入一個(gè)框架--AVFoundation框架
#import <AVFoundation/AVFoundation.h>
  1. 根據(jù)前言的分析,所以我們需要設(shè)置四個(gè)屬性來進(jìn)行視頻錄制的相關(guān)配置
//輸入聲音     
@property (nonatomic, strong) AVCaptureDeviceInput *inputAudio; 
//輸入畫面     
@property (nonatomic, strong) AVCaptureDeviceInput *inputVideo; 
//會話屬性     
@property (nonatomic, strong) AVCaptureSession *session;
//導(dǎo)出   
@property (nonatomic, strong) AVCaptureMovieFileOutput *output;
  1. 我們就做一個(gè)簡單點(diǎn)的demo,在touchesBegan方法中進(jìn)行視頻錄制相關(guān)操作
    // 3.創(chuàng)建對象,并且實(shí)例化
    // 3.1創(chuàng)建一個(gè)設(shè)備
    // 聲音
   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 導(dǎo)出
   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];
    }
    // 添加一個(gè)預(yù)覽的圖層
    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. 添加視頻錄制開關(guān)按鈕
  // 視頻錄制的開關(guān)
 - (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. 監(jiān)聽視頻錄制的進(jìn)度
 #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(@"開始錄制");
}

為什么需要做視頻截圖

視頻截圖就是截取視頻播放中的某一幀(關(guān)鍵幀)畫面。
有時(shí)候當(dāng)我們觀看視頻的時(shí)候,或者觀看直播的時(shí)候,看到一些好玩,有趣的畫面需要和朋友進(jìn)行分享的時(shí)候,就要用到視頻截圖這個(gè)功能了。
下面,我們一起來看一下如何進(jìn)行視頻截圖。

如何進(jìn)行視頻截圖

  1. 導(dǎo)入框架
#import <AVFoundation/AVFoundation.h>
  1. 核心代碼
   創(chuàng)建視頻資源對象
     // 1.1獲取資源的url
      NSURL *url = [[NSBundle mainBundle] URLForResource:@"movie.mp4" withExtension:nil];
    
      // 1.2對url進(jìn)行封裝
      AVAsset *asset = [AVAsset assetWithURL:url];

      // 1.創(chuàng)建一個(gè)視頻截取的截取器
      AVAssetImageGenerator *generator = [AVAssetImageGenerator assetImageGeneratorWithAsset:asset];
    
      // <#int64_t value#>:    截取的時(shí)間
      // <#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的更新一定要在主線程進(jìn)行,要不然不能夠時(shí)時(shí)獲得更新
        dispatch_sync(dispatch_get_main_queue(), ^{
            self.picImageView.image = [UIImage imageWithCGImage:image];
        });
    }];

為什么要進(jìn)行視頻壓縮

通常錄制出來的原視頻都會很大,如果不壓縮就進(jìn)行上傳,一個(gè)是浪費(fèi)用戶的流量,二個(gè)會造成上傳時(shí)間過長,影響用戶體驗(yàn)。

如何進(jìn)行視頻壓縮

  1. 獲取視頻的位置-------相冊

  2. 創(chuàng)建相冊控制器對象,訪問相冊

// 創(chuàng)建訪問相冊的控制器對象
 UIImagePickerController *picker = [[UIImagePickerController alloc]
init];
  1. 訪問相冊之前,需要判斷是否存在相冊
  // 0. 判斷是否有相冊
  if (![UIImagePickerController
isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum])
{NSLog(@" ");
return;}
  1. 彈出控制器
[self presentViewController:picker animated:YES completion:nil];
  1. 訪問相冊可以通過不同的方式,改變的方法為:
設(shè)置他的資源類型
/**
 UIImagePickerControllerSourceTypePhotoLibrary, //照片庫   UIImagePickerControllerSourceTypeCamera,   //照相機(jī)
 UIImagePickerControllerSourceTypeSavedPhotosAlbum //相冊
*/

 picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
  1. 可以看到,相冊中沒有視頻,這是因?yàn)樾枰O(shè)置 媒體類型才能看到
//  設(shè)置媒體類型
 picker.mediaTypes = [UIImagePickerControlleravailableMediaTypesForSourceType:UIImagePickerControllerSourceTypeSavedPhotosAlbum];
  1. 看到視頻后,我們需要拿到該視頻,才能進(jìn)行壓縮操作,所以需要設(shè)置代理
picker.delegate = self;

并且遵守協(xié)議

 @interface ViewController ()  <UINavigationControllerDelegate,UIImagePickerControllerDelegate>
實(shí)現(xiàn)方法:
// MARK: - delegate方法
// 選擇照片或者是視頻時(shí) 調(diào)用
// info:  相關(guān)參數(shù)
  - (void)imagePickerController:(UIImagePickerController *)pickerdidFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info;

 // 選擇 取消時(shí) 調(diào)用
  - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker;
  1. 打印代理方法中的info這個(gè)參數(shù),可以看到里面包含該視頻的地址, 接收該地址
NSLog(@"%@",info);
NSURL *url = info[UIImagePickerControllerMediaURL];
  1. 視頻壓縮的原理: 把視頻用低質(zhì)量導(dǎo)出
  • 創(chuàng)建視頻資源對象
// asset :資源
 AVAsset *asset = [AVAsset assetWithURL:url];
  • 創(chuàng)建視頻導(dǎo)出會話
/**
 AVAssetExportPresetLowQuality       //低質(zhì)量
 AVAssetExportPresetMediumQuality//中質(zhì)量
 AVAssetExportPresetHighestQuality//高質(zhì)量
*/
//  創(chuàng)建視頻導(dǎo)出會話
// presetName :  視頻導(dǎo)出質(zhì)量

 AVAssetExportSession *session = [AVAssetExportSessionexportSessionWithAsset:asset presetName:AVAssetExportPresetLowQuality];
  • 導(dǎo)出視頻:
//  導(dǎo)出
[session exportAsynchronouslyWithCompletionHandler:^{NSLog(@" ");
}];
  • 導(dǎo)出視頻之前,需要我們確定導(dǎo)出到哪里
獲取沙盒路徑//  
 NSString *filePath =[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) lastObject]stringByAppendingPathComponent:@"123.mp4"];
//  session.outputURL = [NSURL fileURLWithPath:filePath];
  • 演示視頻導(dǎo)出, 報(bào)錯(cuò), 查看原因,發(fā)現(xiàn)視頻導(dǎo)出錯(cuò)的原因是沒有設(shè)置視頻導(dǎo)出的類型根據(jù)屬性介紹,可以看到需要查看session.supportedFileTypes屬性,打印該屬性
 // NSLog(@"%@",session.supportedFileTypes); 
/**
"com.apple.quicktime-movie", quicktime-movie 類型 
"public.mpeg-4"              mp4 類型
*/

  // 視頻導(dǎo)出的文件類型
 session.outputFileType = @"public.mpeg-4";
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容