基于AVFoundation实现视频录制的两种方式

一、前言

AVCaptureSessionAVFoundation核心类,用于管理捕获对象 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;
        });
    }
}

三、方案二:AVCaptureSession + AVAssetWriter

方案二及更多内容,请访问: 基于AVFoundation实现视频录制的两种方式

原文链接:https://www.cnblogs.com/reyzhang/p/16646673.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:基于AVFoundation实现视频录制的两种方式 - Python技术站

(0)
上一篇 2023年4月18日
下一篇 2023年4月18日

相关文章

  • iOS16新特性 | 灵动岛适配开发与到家业务场景结合的探索实践

    作者:京东零售 姜海 灵动岛是苹果在iPhone 14 Pro和iPhone 14 Pro Max上首次提出的全新UI交互形式,创新性的让虚拟软件和硬件的交互变得更为流畅。当有来电、短信等通知时,灵动岛会变化形态,以便让用户能够更直观地接收到这些信息。 而在用户使用一些应用App,比如音乐,并将其切换到后台时,灵动岛也能以另一种形态来显示这些软件,还可以通过…

    IOS 2023年4月17日
    00
  • HBuilder包装iOS APP上App Store的详细过程

    以前看过很多教程,然后。ITUNE管理APP功能被删除,IPA安装失败。Appuploader已有1个月的期限等问题。 请参见此教程重新安装。因此,放出。 很多新生开发,不知道如何包装。ios APP安装在自己的手机测试,ios不像安卓包装好后可以直接安装到手机上,苹果APP如果需要安装在非逃避的苹果手机。需要自己申请i特定OS证书包装才能安装。   在开发…

    IOS 2023年4月18日
    00
  • 无需支付688苹果开发者账号,xcode13打包导出ipa,提供他人进行内测

    众所周知,在开发苹果应用时需要使用签名(证书)才能进行打包安装苹果IPA,作为刚接触ios开发的同学,只是学习ios app开发内测,并没有上架appstore需求,对于苹果开发者账号认证需要支付688,真的是极大的浪费,经过一番百度,APP Uploader这块软件,真是及时啊,免688,只需要注册苹果个人开发者账号,不需要688认证,就可以打包自己开发的…

    IOS 2023年4月18日
    00
  • 上架app store流程详解

    本篇文章主要介绍使用Hbuildx开发的移动端项目,打包以及上传值苹果应用商店全部流程。 一、条件1.苹果App Store上传应用流程详解,在向AppStore提交应用之前,开发者首先要成为苹果iOS开发者项目的成员,每年向苹果缴纳99美元或199美元的费用(具体申请方法后期更新)。其次创建相应的证书 Development是开发环境下的证书, Produ…

    IOS 2023年4月18日
    00
  • xcode历史版本下载

    一、背景 较早之前做过一个项目,当时使用swift 3.x开发。 项目结束后就没再有新需求与更新。 但最近呢需要对项目的某些功能进行调整,项目又重新被拾了起来。 我们知道现在的swift 版本已经到了 5.x, 相应的语法上较 3.x版本也有了不小的变化。使用最新版本的xcode都已经不支持swift 3.x的 swift version. 所以目前面临两种…

    IOS 2023年4月27日
    00
  • iOS内存管理之MRC

    前言: 在iOS中,使用引用计数来管理OC对象内存一个新创建的OC对象引用计数默认是1,当引用计数减为0,OC对象就会销毁,释放其占用的内存空间。调用retain会让OC对象的引用计数+1,调用release会让OC对象的引用计数-1。 内存管理的经验总结 当调用alloc、new、copy、mutableCopy方法返回了一个对象,在不需要这个对象时,要调…

    IOS 2023年4月18日
    00
  • 本文相关主要记录一下使用Hbuilder打包成苹果IOS-App的详细步骤。

    ​介绍一下个人开发者账号: 再说下什么是免费的苹果开发者账号,就是你没交688年费的就是免费账号,如果你想变成付费开发者账号,提交申请付费就行,账号都是一样的账号。 没有账号的点击链接申请: 苹果开发者账号申请 登录开发者中心developer.apple.com/account这个界面就是免费开发者账号 ​ 苹果免费开发者账号的功能限制 1、证书描述文件有…

    IOS 2023年4月18日
    00
  • 盘点| 有哪些比较新的好用的React Native 开发工具?

    2015年,FaceBook首次开发并发布React Native框架,用于构建原始的移动应用程序。React Native的特点是使用JavaScript和React编写应用程序代码,而不是其他移动应用程序开发框架,同时利用iOS和Android平台的原始组件和API,从而实现更快、更有效的开发流程。今天就来跟大家分享 React Native 中一些新的…

    IOS 2023年4月25日
    00
合作推广
合作推广
分享本页
返回顶部