iOS视频捕获入门篇

1. AVFoundation简介

AVFoundation 是 OSX 系统和 iOS 系统中用于处理基于时间的媒体数据的高级框架,AVFoundation的设计过程高度依赖多线程机制,充分利用多核硬件优势,大量使用 Block 和 GCD 机制将运算任务放在子线程,且提供硬件加速确保最佳性能。
简单说如果你的应用程序需要使用到高级媒体捕捉、媒体编辑可以使用 AVFoundation 来完成。
AVFoundation 框架在iOS的架构如下:
iv_avf_ios_framework

使用AVKit框架即可实现简单的视频文件播放。
UIImagePickerController可以实现简单的拍照以及视频录制。

2. 视频捕捉

AVFoundation框架内容比较多的,这里通过视频捕捉来入门AVFoundation。如果想深入学习,可以进入官网:
苹果官方AVFoundation框架介绍
AVFoundation框架
推荐阅读《AVFoundation 开发秘籍》

视频流捕捉框架图如下:
iv_avf_capture_framework
整体由输入、输出、会话层、连接、设备组成。对于每一个部分都有相应的类,下面分别介绍这几个类,后面会有实践。

3. AVCaptureSession

AVCaptureSession 是视频捕获的核心类,对应于框架中的capture session。它主用于管理输入输出,开始和停止捕获等,同时还可以设置输出数据的质量与格式。常用的方法和属性如下:

// 设置预设值
@property(nonatomic, copy) AVCaptureSessionPreset sessionPreset;
// 是否可以设置该预设值
// AVCaptureSessionPreset
// 有: 高分辨率图片、720P、1080P等
- (BOOL)canSetSessionPreset:(AVCaptureSessionPreset)preset;

// 当前所有的输入
@property(nonatomic, readonly) NSArray<__kindof AVCaptureInput *> *inputs;
// 是否可以添加输入,返回YES才能添加
- (BOOL)canAddInput:(AVCaptureInput *)input;
// canAddInput返回YES后添加输入
- (void)addInput:(AVCaptureInput *)input;
// 移除一个输入
- (void)removeInput:(AVCaptureInput *)input;

// 当前所有的输出
@property(nonatomic, readonly) NSArray<__kindof AVCaptureOutput *> *outputs;
// 是否可以添加输出,返回YES才能添加
- (BOOL)canAddOutput:(AVCaptureOutput *)output;
// canAddOutput返回YES后添加输出
- (void)addOutput:(AVCaptureOutput *)output;
// 删除一个输出
- (void)removeOutput:(AVCaptureOutput *)output;

// 在session运行时更改配置时,需要在下面两个方法间改动
- (void)beginConfiguration;
- (void)commitConfiguration;

// 开始和停止会话(开启和停止数据流)
- (void)startRunning;
- (void)stopRunning;

同时还提供一些通知,让开发者可以获取该兴趣的信息。

AVCaptureSessionRuntimeErrorNotification
AVCaptureSessionDidStartRunningNotification
AVCaptureSessionDidStopRunningNotification
AVCaptureSessionWasInterruptedNotification
AVCaptureSessionInterruptionEndedNotification

4. AVCaptureDevice

AVCaptureDevice 表示提供实时输入媒体数据(如视频和音频)的物理设备。该类是不能直接初始化的。devicesWithMediaType、devices 等方法均已被 AVCaptureDeviceDiscoverySession 替代,我们应当使用 AVCaptureDeviceDiscoverySession 类来获取设备。
下面是常用的一些属性和方法:

// 摄像头的位置
@property(nonatomic, readonly) AVCaptureDevicePosition position;

// 更改设备属性时需要加锁,如手电筒、聚焦、曝光等(闪光灯在AVCapturePhotoOutput中处理)
- (BOOL)lockForConfiguration:(NSError * _Nullable * _Nullable)outError;
- (void)unlockForConfiguration;

// 是否支持手电筒
- (BOOL)isTorchModeSupported:(AVCaptureTorchMode)torchMode;
// 设置手电筒模式
@property(nonatomic) AVCaptureTorchMode torchMode;

// 是否支持聚焦模式(自动聚焦、锁定当前对焦、需要时聚焦)
- (BOOL)isFocusModeSupported:(AVCaptureFocusMode)focusMode;
// 设置聚焦模式
@property(nonatomic) AVCaptureFocusMode focusMode;
// 是否支持指定聚集点
@property(nonatomic, readonly, getter=isFocusPointOfInterestSupported) BOOL focusPointOfInterestSupported;
// 设置指定聚焦点,需要调用 setFocusMode: 生效
@property(nonatomic) CGPoint focusPointOfInterest;

// 校验权限
+ (AVAuthorizationStatus)authorizationStatusForMediaType:(NSString *)mediaType;
// 请求权限,handler 处理会在任意线程中执行
+ (void)requestAccessForMediaType:(NSString *)mediaType completionHandler:(void (^)(BOOL granted))handler;

5. AVCaptureDeviceInput

我们不能直接使用 AVCaptureDevice 作为输入,而是需要使用 AVCaptureDeviceInput 封装 AVCaptureDevice。AVCaptureDeviceInput是 AVCaptureInput的子类。

AVCaptureInput 的子类还有AVCaptureScreenInput和AVCaptureScreenInput
AVCaptureScreenInput 仅用于 OS X,对应屏幕的输入,如录屏
AVCaptureScreenInput 仅连接AVCaptureMovieFileOutput输出,可以算是一个附加输入
因此我们学会使用 AVCaptureDeviceInput 即可,常用方法和属性如下:

// 当前设备
@property(nonatomic, readonly) AVCaptureDevice *device;

// 通过设备初始化输入
- (nullable instancetype)initWithDevice:(AVCaptureDevice *)device error:(NSError * _Nullable * _Nullable)outError;

6. AVCaptureOutput

AVCaptureOutput 对应输出的类,其是一个抽象类,我们需要使用其子类。

AVCaptureFileOutput: 文件数据输出,用于记录,如录视频和录音。
AVCaptureMovieFileOutput: AVCaptureFileOutput的子类,视频文件数据输出,连接的输入有音频输入和视频输入
AVCaptureAudioFileOutput: AVCaptureFileOutput的子类,音频文件数据输出,连接的输入有音频输入
以下是实时数据输出,可实时处理
AVCaptureVideoDataOutput: 视频数据输出,连接视频输入
AVCaptureMetadataOutput: 视频元数据输出,连接视频输入
AVCaptureAudioDataOutput: 音频数据输出,连接音频输入
AVCapturePhotoOutput: 照片数据输出,连接视频输入
AVCaptureStillImageOutput: (原照片数据输出吗,已被废弃)

因为主要是视频捕获,下面介绍一下 AVCaptureMovieFileOutput、AVCaptureVideoDataOutput、AVCapturePhotoOutput。(AVCaptureMetadataOutput在后面进阶中介绍)

7. AVCaptureMovieFileOutput

AVCaptureMovieFileOutput 用于录制视频,其中有详细信息的元数据。

元数据:保存音视频等多媒体资料的各种附加信息。如:作者, 标题, 创建时间, 封面等描述关于这个多媒体的一些常见描述信息。
常用方法和属性如下:

// 时间和大小
@property(nonatomic, readonly) CMTime recordedDuration;
@property(nonatomic, readonly) int64_t recordedFileSize;
// 最大时间长度和大小,默认无限制
@property(nonatomic) CMTime maxRecordedDuration;
@property(nonatomic) int64_t maxRecordedFileSize;

// 停止录制,想要从一个文件切换到另一个文件的直接调用startRecordingToOutputFileURL:recordingDelegate:即可
- (void)stopRecording;

// 开始录制,所有的错误均会在delegate中通知
- (void)startRecordingToOutputFileURL:(NSURL *)outputFileURL recordingDelegate:(id<AVCaptureFileOutputRecordingDelegate>)delegate;

8. AVCaptureVideoDataOutput

AVCaptureVideoDataOutput 主要是需要处理实时视频数据时使用,例如想要实现实时视频帧处理、追踪、译码等均可以在这里处理。下面介绍一下常用方法和属性。

// 设置视频帧的属性,在iOS上只支持设置像素格式
@property(nonatomic, copy, null_resettable) NSDictionary<NSString *, id> *videoSettings;

// 视频帧输出代理和一个串行的queue
- (void)setSampleBufferDelegate:(nullable id<AVCaptureVideoDataOutputSampleBufferDelegate>)sampleBufferDelegate queue:(nullable dispatch_queue_t)sampleBufferCallbackQueue;

9. AVCapturePhotoOutput

AVCapturePhotoOutput 取代了 AVCaptureStillImageOutput 来获取照片。AVCapturePhotoOutput的功能更加强大,支持简JPEG图片拍摄、Live照片、RAW格式拍摄等,也有双摄以及人像模式等。下面是常用的方法与属性。

// 图片配置信息
@property(nonatomic, readonly) NSArray<AVCapturePhotoSettings *> *preparedPhotoSettingsArray
// 可用的像素格式
@property(nonatomic, readonly) NSArray<NSNumber *> *availablePhotoPixelFormatTypes;
// 可用的图片压缩格式
@property(nonatomic, readonly) NSArray<AVVideoCodecType> *availablePhotoCodecTypes;

// 执行捕获 每一次捕获或者照片都对应一个settings,即该图片的各种配置
- (void)capturePhotoWithSettings:(AVCapturePhotoSettings *)settings delegate:(id<AVCapturePhotoCaptureDelegate>)delegate;

// 有些类型的照片捕获,需要接收方分配额外的缓冲区或准备其他资源。因此你可以提前设置要捕获的类型,这样可以提前分配好资源,而不用等捕获时再分配资源
// 使用下面的方法来配置照片设置,它有如下规则:
// a) 你可以不调用这个方法,但是调用-capturePhotoWithSettings:delegate:执行照片捕获可能会执行缓慢,因为额外的资源是即时分配的。
// b) completionHandler不会立即被调用。它只会触发你调用-[AVCaptureSession startRunning]后的所需资源准备后触发。
// c) 如果多次调用-setPreparedPhotoSettingsArray:completionHandler:前一次调用的completionHandler会立即且prepared== NO
- (void)setPreparedPhotoSettingsArray:(NSArray<AVCapturePhotoSettings *> *)preparedPhotoSettingsArray completionHandler:(nullable void (^)(BOOL prepared, NSError * _Nullable error))completionHandler;

10. 总结

AVFoundation 框架内容很多,因此我是以视频捕捉作为入门和实践,所以仅介绍重点类和常用方法与属性,另外在现在这个快餐时代,写太多了,人会产生一种不耐烦的心情,不会专心读不下去,即使看下去了,也不一定能记住,因此短篇足够。

纸上得来终觉浅,绝知此事要躬行。下一章会实践篇,来构建一个可以拍视频和拍照的相机,会把使用到的地方细讲。

瑞思拜~

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值