• 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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

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

    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;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    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;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    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;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    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;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    10. 总结

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

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

    瑞思拜~

  • 相关阅读:
    数据中心网络规划设计,数据中心设计规范解读
    Spring----IOC、注解
    安卓主板_MTK安卓一体机方案定制
    使用LVM方式创建linux文件系统,详细教程
    小县城蔬菜配送小程序制作全攻略
    微信小程序基础学习(5):使用 npm包、全局数据共享、分包
    推理还原的干货
    【Rust 日报】2022-08-21 surrealdb端到端云原生数据库
    comsol6.1软件下载+安装教程
    java nodejs python小学生兴趣延时班预约系统 php小程序
  • 原文地址:https://blog.csdn.net/Void_leng/article/details/126662932