iOS -自定義視頻錄制方法之AVCaptureSession

前言####

這些年App的呈現(xiàn)方式不斷在進(jìn)化,從最初的文字到圖片,再到gif動(dòng)態(tài)圖片,現(xiàn)在是視頻展示,所以我覺得我們的技術(shù)也要不斷的更新,那么今天就從錄制小視頻開始吧。

錄制視頻的方式###

簡單的來講主要有兩種
1、UIImagePickerController,比較簡單,功能單一
2、AVFoundation的AVCaptureSession視頻捕獲類(本文主講)
由于考慮到視頻錄制以后可能會(huì)用到,所以我把錄制視頻封裝成工具類。視頻源碼地址:自定義視頻錄制之AVCaptureSession
錄制效果:

Snip20161008_37.png
Snip20161008_37.png

錄制視頻的步驟####

1、相機(jī)、麥克風(fēng)、保存視頻的相冊是否授權(quán)

//相機(jī)是否可以用   
 - (BOOL)isAvailableWithCamera
{
    return [self isAvailableWithDeviveMediaType:AVMediaTypeVideo];
 }
//麥克風(fēng)是否可以用
- (BOOL)isAvailableWithMic
{
  return [self isAvailableWithDeviveMediaType:AVMediaTypeAudio];
}
- (BOOL)isAvailableWithDeviveMediaType:(NSString *)mediaType
{
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if(status == ALAuthorizationStatusDenied||status == ALAuthorizationStatusRestricted)
    return NO;
else
    return YES;
}

2、初始化輸入輸出、攝像頭、數(shù)據(jù)流管理、視頻預(yù)覽層

 @property (strong, nonatomic) AVCaptureSession *captureSession;  //負(fù)責(zé)輸入和輸出設(shè)備之間的連接會(huì)話,數(shù)據(jù)流的管理控制
 @property (strong, nonatomic) AVCaptureVideoPreviewLayer *previewLayer;//捕獲到的視頻呈現(xiàn)的layer
 @property (strong, nonatomic) AVCaptureDeviceInput       *backCameraInput;//后置攝像頭輸入
 @property (strong, nonatomic) AVCaptureDeviceInput       *frontCameraInput;//前置攝像頭輸入
 @property (strong, nonatomic) AVCaptureDeviceInput       *audioMicInput;//麥克風(fēng)輸入
 @property (strong, nonatomic) AVCaptureConnection        *videoConnection;//視頻錄制連接
 @property (strong,nonatomic) AVCaptureMovieFileOutput    *captureMovieFileOutput;//視頻輸出流

由于初始化的東西比較多,那么我就簡單的列舉幾個(gè),詳情可以查看demo自定義視頻錄制之AVCaptureSession

 //捕獲視頻的會(huì)話
- (AVCaptureSession *)captureSession
{
if(_captureSession == nil)
{
    _captureSession = [[AVCaptureSession alloc] init];
    //設(shè)置分辨率
    if ([_captureSession canSetSessionPreset:AVCaptureSessionPreset1280x720]) {
        _captureSession.sessionPreset=AVCaptureSessionPreset1280x720;
    }
    //添加后置攝像頭的輸入
    if ([_captureSession canAddInput:self.backCameraInput]) {
        [_captureSession addInput:self.backCameraInput];
    }
    //添加后置麥克風(fēng)的輸入
    if ([_captureSession canAddInput:self.audioMicInput]) {
        [_captureSession addInput:self.audioMicInput];
    }
    //將設(shè)備輸出添加到會(huì)話中
    if ([_captureSession canAddOutput:self.captureMovieFileOutput]) {
        [_captureSession addOutput:self.captureMovieFileOutput];
    }
    //設(shè)置視頻錄制的方向
    self.videoConnection.videoOrientation = AVCaptureVideoOrientationPortrait;
}
return _captureSession;

}

初始化錄制視頻的預(yù)覽層

//捕獲到的視頻呈現(xiàn)的layer
 - (AVCaptureVideoPreviewLayer *)previewLayer {
if (_previewLayer == nil) {
    //通過AVCaptureSession初始化
    AVCaptureVideoPreviewLayer *preview = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
    //設(shè)置比例為鋪滿全屏
    preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
    _previewLayer = preview;
}
return _previewLayer;
}

4、初始化完成之后,就可以啟動(dòng)錄制功能(注意:是啟動(dòng)錄制功能,并不是開始錄制),啟動(dòng)錄制功能的之前一定要把視頻預(yù)覽層放到你想要的錄制區(qū)域,這樣開啟錄制功能就能預(yù)覽錄制效果

//啟動(dòng)錄制功能
- (void)startRecordFunction
{
  [self.captureSession startRunning];
  }
 //關(guān)閉錄制功能
- (void)stopRecordFunction
{
if(self.captureSession)
    [self.captureSession stopRunning];
}

5、在錄制視頻開始之前要設(shè)置錄制視頻的輸入視頻流的存放地址,你可以存放到您想存放的地方,本文存放到temp文件中

   #pragma mark - 視頻地址
  - (NSString *)getVideoPathCache
 {
NSString *videoCache = [NSTemporaryDirectory() stringByAppendingPathComponent:@"videos"] ;
BOOL isDir = NO;
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL existed = [fileManager fileExistsAtPath:videoCache isDirectory:&isDir];
if ( !(isDir == YES && existed == YES) ) {
    [fileManager createDirectoryAtPath:videoCache withIntermediateDirectories:YES attributes:nil error:nil];
};
return videoCache;
 }
- (NSString *)getVideoNameWithType:(NSString *)fileType
{
NSTimeInterval now = [[NSDate date] timeIntervalSince1970];
NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"HHmmss"];
NSDate * NowDate = [NSDate dateWithTimeIntervalSince1970:now];
;
NSString * timeStr = [formatter stringFromDate:NowDate];
NSString *fileName = [NSString stringWithFormat:@"video_%@.%@",timeStr,fileType];
return fileName;
}

6、開始錄制

  //開始錄制
- (void)startCapture
{
if(self.captureMovieFileOutput.isRecording)
    return;
NSString *defultPath = [self getVideoPathCache];
NSString *outputFielPath=[ defultPath stringByAppendingPathComponent:[self getVideoNameWithType:@"mp4"]];
NSLog(@"save path is :%@",outputFielPath);
NSURL *fileUrl=[NSURL fileURLWithPath:outputFielPath];
//設(shè)置錄制視頻流輸出的路徑
[self.captureMovieFileOutput startRecordingToOutputFileURL:fileUrl recordingDelegate:self]; 
}
//停止錄制
- (void) stopCapture
 {
if ([self.captureMovieFileOutput isRecording]) {
    [self.captureMovieFileOutput stopRecording];//停止錄制
}
}

7、視頻錄制過程中有AVCaptureFileOutputRecordingDelegate記錄監(jiān)聽錄制過程,我們可以實(shí)現(xiàn)代理方法查看,并且在錄制完成,我們希望把視頻保存到我們的相冊中

 #pragma mark - 視頻輸出代理
 -(void)captureOutput:(AVCaptureFileOutput *)captureOutput didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections{
NSLog(@"開始錄制...");
}
 -(void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error{
NSLog(@"視頻錄制完成.");
//視頻錄入完成之后在后臺(tái)將視頻存儲(chǔ)到相
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
    [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:outputFileURL];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
    if (error) {
        NSLog(@"保存視頻到相簿過程中發(fā)生錯(cuò)誤,錯(cuò)誤信息:%@",error.localizedDescription);
    }
    NSLog(@"成功保存視頻到相簿.");
}];    
}

8、在錄制過程中我們有時(shí)候還要增加一些功能,比如切換攝像頭、開啟閃光燈、錄制進(jìn)度顯示等

  #注意:改變會(huì)話的配置前一定要先開啟配置,配置完成后提交配置改變 
    //開啟閃光燈
- (void)openFlashLight
{
//改變會(huì)話的配置前一定要先開啟配置,配置完成后提交配置改變
[self.captureSession beginConfiguration];
AVCaptureDevice *backCamera = [self backCamera];
if (backCamera.torchMode == AVCaptureTorchModeOff) {
    [backCamera lockForConfiguration:nil];
    backCamera.torchMode = AVCaptureTorchModeOn;
    backCamera.flashMode = AVCaptureFlashModeOn;
    [backCamera unlockForConfiguration];
}
//提交會(huì)話配置
[self.captureSession commitConfiguration];
[self startRecordFunction];
}

詳情代碼請直接下載demo查看:
自定義視頻錄制之AVCaptureSession

最后贈(zèng)言###

如果覺得文章對您有幫助,不要忘記star哦!??,star 是對程序猿最大的鼓勵(lì)!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容