使用AVFoundation实现视频录制详解

 更新时间:2022年09月05日 08:44:44   作者:reyzhang  
这篇文章主要介绍了使用AVFoundation实现视频录制详解的相关资料,需要的朋友可以参考下

一、前言

AVCaptureSession 是 AVFoundation 的核心类,用于管理捕获对象 AVCaptureInput 的视频和音频的输入,协调捕获的输出 AVCaptureOutput。

AVCaptureOutput 的输出有两种方法:

  • 一种是直接以 movieFileUrl 方式输出;
  • 一种是以原始数据流 data 的方式输出

流程对比图如下:

下面详细讲解录制视频的方案:

二、AVCaptureSession + AVCaptureMovieFileOutput

1.创建AVCaptureSession

//导入 AVFoundation.framework 
#import <AVFoundation/AVFoundation.h>

//声明属性
@property (nonatomic, strong) AVCaptureSession *captureSession;

//懒加载 AVCapturesession
- (AVCaptureSession *)captureSession {
    if (!_captureSession) {
        _captureSession = [[AVCaptureSession alloc] init];
        
        //设置分辨率
        if ([_captureSession canSetSessionPreset:AVCaptureSessionPresetHigh]) {
            [_captureSession setSessionPreset:AVCaptureSessionPresetHigh];
        }
    }
    return _captureSession;
}

注意:AVCaptureSession 的调用是会阻塞线程的,建议单独开辟子线程处理。2.设置音频、视频输入

//声明属性
@property (nonatomic, strong) AVCaptureDeviceInput *videoInput;
@property (nonatomic, strong) AVCaptureDeviceInput *audioInput;


//设置视频,音频输入源
- (void)setCaptureDeviceInput {
    //1. 视频输入源
    //获取视频输入设备, 默认后置摄像头
    AVCaptureDevice *videoCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    
    NSError *error = nil;
    self.videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoCaptureDevice error:&error];
    
    if ([self.captureSession canAddInput:self.videoInput]) {
        [self.captureSession addInput:self.videoInput];
    }
    
    
    //2. 音频输入源
    AVCaptureDevice *audioCaptureDevice = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio] firstObject];
    self.audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioCaptureDevice error:&error];
    if ([self.captureSession canAddInput:self.audioInput]) {
        [self.captureSession addInput:self.audioInput];
    }
    
}

3.设置文件输出源

//声明属性
@property (nonatomic, strong) AVCaptureMovieFileOutput *movieFileOutput;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer;


//设置文件输出源
- (void)setDeviceFileOutput {
    
    //初始化文件输出对象
    self.movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
    
    //捕获会话中特定捕获输入对象和捕获输出对象之间的连接
    AVCaptureConnection *captureConnection = [self.movieFileOutput connectionWithMediaType:AVMediaTypeVideo];
    
    //设置防抖
    if ([captureConnection isVideoStabilizationSupported]) {
        captureConnection.preferredVideoStabilizationMode = AVCaptureVideoStabilizationModeAuto;
    }
    
    //预览图层和视频方向保持一致
    captureConnection.videoOrientation = [self.previewLayer connection].videoOrientation;
    
    //添加文件输出源
    if ([self.captureSession canAddOutput:self.movieFileOutput]) {
        [self.captureSession addOutput:self.movieFileOutput];
    }
    
}

4.添加视频预览层

- (void)setVideoPreviewLayer {
    self.previewLayer.frame = [UIScreen mainScreen].bounds;
    
    [self.superView.layer addSubLayer:self.previewLayer];
}


- (AVCaptureVideoPreviewLayer *)previewLayer {
    if (!_previewLayer) {
        _previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
        _previewLayer.masksToBounds = YES;
        _previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;//填充模式
    }
    return _previewLayer;
}

5. 开始采集

//声明属性
@property (nonatomic, strong) dispatch_queue_t sessionQueue;

//开始采集
- (void)startCapture {
    self.sessionQueue = dispatch_queue_create("com.capturesession.queue", DISPATCH_QUEUE_CONCURRENT);

    if (![self.captureSession isRunning]) {
        __weak __typeof(self) weakSelf = self;
        
        dispatch_async(self.sessionQueue, ^{
            [weakSelf.captureSession startRunning];
        });
        
    }
}

6. 开始录制

//开始录制
- (void)startRecord {
    
    [self.movieFileOutput startRecordingToOutputFileURL:[self createVideoPath] recordingDelegate:self];
}

当实际的录制开始或停止时,系统会有代理回调。当开始录制之后,这时可能还没有真正写入,真正开始写入会回调下面代理,停止录制也是如此,所以如果你需要对录制视频起始点操作,建议通过系统的回调代理:

//实现协议 <AVCaptureFileOutputRecordingDelegate>中的方法


#pragma mark _ AVCaptureFileOutputRecordingDelegate

//起始点 - 开始录制
- (void)captureOutput:(AVCaptureFileOutput *)output didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray<AVCaptureConnection *> *)connections {
    
}

//结束录制
-(void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error
{
    NSLog(@"视频录制完成. 文件路径:%@",[outputFileURL absoluteString]);
}

7.停止录制

//停止录制
- (void)stopRecord {
    if ([self.movieFileOutput isRecording]) {
        [self.movieFileOutput stopRecording];
    }
}

8.停止采集

//停止采集
- (void)stopCapture {
    if ([self.captureSession isRunning]) {
        __weak __typeof(self) weakSelf = self;
        dispatch_async(self.sessionQueue, ^{
            [weakSelf.captureSession stopRunning];
            weakSelf.captureSession = nil;
        });
    }
}

到此这篇关于使用AVFoundation实现视频录制详解的文章就介绍到这了,更多相关AVFoundation实现视频录制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • swift3.0网络图片缓存原理简析

    swift3.0网络图片缓存原理简析

    这篇文章主要为大家简析了swift3.0网络图片缓存原理,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09
  • 深入学习iOS7自定义导航转场动画

    深入学习iOS7自定义导航转场动画

    这篇文章主要为大家详细介绍了iOS7自定义导航转场动画的相关资料,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • iOS实现只有底部边框线的输入框示例代码

    iOS实现只有底部边框线的输入框示例代码

    这篇文章给大家分享了一种利用iOS实现只有底部边框线的输入框,其实这个效果也挺常见的,本文给出了示例代码,下面来看看如何实现这种效果。
    2016-09-09
  • iOS push侧滑返回功能实现方法

    iOS push侧滑返回功能实现方法

    这篇文章主要为大家详细介绍了iOS push侧滑返回功能实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • IOS入门笔记之地理位置定位系统

    IOS入门笔记之地理位置定位系统

    关于地理位置及定位系统,在iOS开发中也比较常见,接下来通过本文给大家介绍IOS入门笔记之地理位置定位系统,对ios地理位置定位系统感兴趣的朋友一起学习吧
    2016-01-01
  • IOS 静态库和Framework区别

    IOS 静态库和Framework区别

    这篇文章主要介绍了IOS 静态库和Framework区别的相关资料,这里对动态库与静态库做比较,选择什么时候使用库文件,需要的朋友可以参考下
    2016-12-12
  • IOS实现自定义透明背景的tabbar

    IOS实现自定义透明背景的tabbar

    这篇文章介绍的是在IOS中怎样把tabbar背景设置为透明,有需要的小伙伴们可以参考借鉴。
    2016-08-08
  • iOS如何自定义步骤进度条实例详解

    iOS如何自定义步骤进度条实例详解

    这篇文章主要给大家介绍了关于iOS如何自定义步骤进度条的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-11-11
  • iOS开发中Date Picker和UITool Bar控件的使用简介

    iOS开发中Date Picker和UITool Bar控件的使用简介

    这篇文章主要介绍了iOS开发中Date Picker和UITool Bar控件的使用简介,代码基于传统的Objective-C,需要的朋友可以参考下
    2016-01-01
  • 一个iOS上的秒表小应用的实现方法分享

    一个iOS上的秒表小应用的实现方法分享

    这篇文章主要介绍了一个iOS上的秒表小应用的实现方法分享,代码基于传统的Objective-C,需要的朋友可以参考下
    2015-10-10

最新评论