自定义视频录制方法之AVCaptureSession

前言####

这些年App的呈现方式不断在进化,从最初的文字到图片,再到gif动态图片,现在是视频展示,所以我觉得我们的技术也要不断的更新,那么今天就从录制小视频开始吧。

录制视频的方式###

简单的来讲主要有两种
1、UIImagePickerController,比较简单,功能单一
2、AVFoundation的AVCaptureSession视频捕获类(本文主讲)
由于考虑到视频录制以后可能会用到,所以我把录制视频封装成工具类。视频源码地址:自定义视频录制之AVCaptureSession
录制效果:

Snip20161008_37.png

录制视频的步骤####

1、相机、麦克风、保存视频的相册是否授权

//相机是否可以用   
 - (BOOL)isAvailableWithCamera
{
    return [self isAvailableWithDeviveMediaType:AVMediaTypeVideo];
 }
//麦克风是否可以用
- (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、初始化输入输出、摄像头、数据流管理、视频预览层

 @property (strong, nonatomic) AVCaptureSession *captureSession;  //负责输入和输出设备之间的连接会话,数据流的管理控制
 @property (strong, nonatomic) AVCaptureVideoPreviewLayer *previewLayer;//捕获到的视频呈现的layer
 @property (strong, nonatomic) AVCaptureDeviceInput       *backCameraInput;//后置摄像头输入
 @property (strong, nonatomic) AVCaptureDeviceInput       *frontCameraInput;//前置摄像头输入
 @property (strong, nonatomic) AVCaptureDeviceInput       *audioMicInput;//麦克风输入
 @property (strong, nonatomic) AVCaptureConnection        *videoConnection;//视频录制连接
 @property (strong,nonatomic) AVCaptureMovieFileOutput    *captureMovieFileOutput;//视频输出流

由于初始化的东西比较多,那么我就简单的列举几个,详情可以查看demo自定义视频录制之AVCaptureSession

 //捕获视频的会话
- (AVCaptureSession *)captureSession
{
if(_captureSession == nil)
{
    _captureSession = [[AVCaptureSession alloc] init];
    //设置分辨率
    if ([_captureSession canSetSessionPreset:AVCaptureSessionPreset1280x720]) {
        _captureSession.sessionPreset=AVCaptureSessionPreset1280x720;
    }
    //添加后置摄像头的输入
    if ([_captureSession canAddInput:self.backCameraInput]) {
        [_captureSession addInput:self.backCameraInput];
    }
    //添加后置麦克风的输入
    if ([_captureSession canAddInput:self.audioMicInput]) {
        [_captureSession addInput:self.audioMicInput];
    }
    //将设备输出添加到会话中
    if ([_captureSession canAddOutput:self.captureMovieFileOutput]) {
        [_captureSession addOutput:self.captureMovieFileOutput];
    }
    //设置视频录制的方向
    self.videoConnection.videoOrientation = AVCaptureVideoOrientationPortrait;
}
return _captureSession;

}

初始化录制视频的预览层

//捕获到的视频呈现的layer
 - (AVCaptureVideoPreviewLayer *)previewLayer {
if (_previewLayer == nil) {
    //通过AVCaptureSession初始化
    AVCaptureVideoPreviewLayer *preview = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
    //设置比例为铺满全屏
    preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
    _previewLayer = preview;
}
return _previewLayer;
}

4、初始化完成之后,就可以启动录制功能(注意:是启动录制功能,并不是开始录制),启动录制功能的之前一定要把视频预览层放到你想要的录制区域,这样开启录制功能就能预览录制效果

//启动录制功能
- (void)startRecordFunction
{
  [self.captureSession startRunning];
  }
 //关闭录制功能
- (void)stopRecordFunction
{
if(self.captureSession)
    [self.captureSession stopRunning];
}

5、在录制视频开始之前要设置录制视频的输入视频流的存放地址,你可以存放到您想存放的地方,本文存放到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];
//设置录制视频流输出的路径
[self.captureMovieFileOutput startRecordingToOutputFileURL:fileUrl recordingDelegate:self]; 
}
//停止录制
- (void) stopCapture
 {
if ([self.captureMovieFileOutput isRecording]) {
    [self.captureMovieFileOutput stopRecording];//停止录制
}
}

7、视频录制过程中有AVCaptureFileOutputRecordingDelegate记录监听录制过程,我们可以实现代理方法查看,并且在录制完成,我们希望把视频保存到我们的相册中

 #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(@"视频录制完成.");
//视频录入完成之后在后台将视频存储到相
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
    [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:outputFileURL];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
    if (error) {
        NSLog(@"保存视频到相簿过程中发生错误,错误信息:%@",error.localizedDescription);
    }
    NSLog(@"成功保存视频到相簿.");
}];    
}

8、在录制过程中我们有时候还要增加一些功能,比如切换摄像头、开启闪光灯、录制进度显示等

  #注意:改变会话的配置前一定要先开启配置,配置完成后提交配置改变 
    //开启闪光灯
- (void)openFlashLight
{
//改变会话的配置前一定要先开启配置,配置完成后提交配置改变
[self.captureSession beginConfiguration];
AVCaptureDevice *backCamera = [self backCamera];
if (backCamera.torchMode == AVCaptureTorchModeOff) {
    [backCamera lockForConfiguration:nil];
    backCamera.torchMode = AVCaptureTorchModeOn;
    backCamera.flashMode = AVCaptureFlashModeOn;
    [backCamera unlockForConfiguration];
}
//提交会话配置
[self.captureSession commitConfiguration];
[self startRecordFunction];
}

详情代码请直接下载demo查看:
自定义视频录制之AVCaptureSession

最后赠言###

如果觉得文章对您有帮助,不要忘记star哦!,star 是对程序猿最大的鼓励!

你可能感兴趣的:(自定义视频录制方法之AVCaptureSession)