iOS AVDemo(7):视频采集

本文介绍了在iOS平台上进行视频采集的实现,包括创建视频采集模块,实现视频采集逻辑并实时预览,以及详细代码注释帮助理解。通过AVCaptureSession和CMSampleBufferRef等技术,展示了如何配置采集参数,处理采集数据,并提供截图保存到相册的功能。

iOS/Android 客户端开发同学如果想要开始学习音视频开发,最丝滑的方式是对音视频基础概念知识有一定了解后,再借助 iOS/Android 平台的音视频能力上手去实践音视频的采集 → 编码 → 封装 → 解封装 → 解码 → 渲染过程,并借助音视频工具来分析和理解对应的音视频数据。

音视频工程示例这个栏目,我们将通过拆解采集 → 编码 → 封装 → 解封装 → 解码 → 渲染流程并实现 Demo 来向大家介绍如何在 iOS/Android 平台上手音视频开发。

这里是第七篇:iOS 视频采集 Demo。这个 Demo 里包含以下内容:

  • 1)实现一个视频采集模块;

  • 2)实现视频采集逻辑并将采集的视频图像渲染进行预览,同时支持将数据转换为图片存储到相册;

  • 3)详尽的代码注释,帮你理解代码逻辑和原理。

1、视频采集模块

首先,实现一个 KFVideoCaptureConfig 类用于定义视频采集参数的配置。

KFVideoCaptureConfig.h
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>

NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(NSInteger, KFVideoCaptureMirrorType) {
    KFVideoCaptureMirrorNone = 0,
    KFVideoCaptureMirrorFront = 1 << 0,
    KFVideoCaptureMirrorBack = 1 << 1,
    KFVideoCaptureMirrorAll = (KFVideoCaptureMirrorFront | KFVideoCaptureMirrorBack),
};

@interface KFVideoCaptureConfig : NSObject
@property (nonatomic, copy) AVCaptureSessionPreset preset; // 视频采集参数,比如分辨率等,与画质相关。
@property (nonatomic, assign) AVCaptureDevicePosition position; // 摄像头位置,前置/后置摄像头。
@property (nonatomic, assign) AVCaptureVideoOrientation orientation; // 视频画面方向。
@property (nonatomic, assign) NSInteger fps; // 视频帧率。
@property (nonatomic, assign) OSType pixelFormatType; // 颜色空间格式。
@property (nonatomic, assign) KFVideoCaptureMirrorType mirrorType; // 镜像类型。
@end

NS_ASSUME_NONNULL_END

这里的参数包括了:分辨率、摄像头位置、画面方向、帧率、颜色空间格式、镜像类型这几个参数。

其中画面方向是指采集的视频画面是可以带方向的,包括:PortraitPortraitUpsideDownLandscapeRightLandscapeLeft 这几种。

颜色空间格式对应 RGB、YCbCr 这些概念,具体来讲,一般我们采集图像用于后续的编码时,这里设置 kCVPixelFormatType_420YpCbCr8BiPlanarFullRange 即可;如果想支持 HDR 时(iPhone12 及之后设备才支持),这里设置 kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange。在我们这个 Demo 中,我们想要将采集的图像数据直接转换并存储为图片,所以我们会设置采集的颜色空间格式为 kCVPixelFormatType_32BGRA,这样将更方便将 CMSampleBuffer 转换为 UIImage。后面你会看到这个逻辑。

镜像类型表示采集的画面是否左右镜像,这个在直播时,主播经常需要考虑是否对自己的画面进行镜像,从而决定主播和观众的所见画面是否在『左右』概念的理解上保持一致。

其他的几个参数大家应该从字面上就能理解,就不做过多解释了。

KFVideoCaptureConfig.m
#import "KFVideoCaptureConfig.h"

@implementation KFVideoCaptureConfig

- (instancetype)init {
    self = [super init];
    if (self) {
        _preset = AVCaptureSessionPreset1920x1080;
        _position = AVCaptureDevicePositionFront;
        _orientation = AVCaptureVideoOrientationPortrait;
        _fps = 30;
        _mirrorType = KFVideoCaptureMirrorFront;

        // 设置颜色空间格式,这里要注意了:
        // 1、一般我们采集图像用于后续的编码时,这里设置 kCVPixelFormatType_420YpCbCr8BiPlanarFullRange 即可。
        // 2、如果想支持 HDR 时(iPhone12 及之后设备才支持),这里设置为:kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange。
        _pixelFormatType = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange;
    }
    
    return self;
}

@end

上面我们在 KFVideoCaptureConfig 的初始化方法里提供了一些默认值。

接下来,我们实现一个 KFVideoCapture 类来实现视频采集。

KFVideoCapture.h
#import <Foundation/Foundation.h>
#import "KFVideoCaptureConfig.h"

NS_ASSUME_NONNULL_BEGIN

@interface KFVideoCapture : NSObject
+ (instancetype)new NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithConfig:(KFVideoCaptureConfig *)config;

@property (nonatomic, strong, readonly) KFVideoCaptureConfig *config;
@property (nonatomic, strong, readonly) AVCaptureVideoPreviewLayer *previewLayer; // 视频预览渲染 layer。
@property (nonatomic, copy) void (^sampleBufferOutputCallBack)(CMSampleBufferRef sample); // 视频采集数据回调。
@property (nonatomic, copy) void (^sessionErrorCallBack)(NSError *error); // 视频采集会话错误回调。
@property (nonatomic, copy) void (^sessionInitSuccessCallBack)(void); // 视频采集会话初始化成功回调。

- (void)startRunning; // 开始采集。
- (void)stopRunning; // 停止采集。
- (void)changeDevicePosition:(AVCaptureDevicePosition)position; // 切换摄像头。
@end

NS_ASSUME_NONNULL_END

上面是 KFVideoCapture 的接口设计,可以看到这些接口类似音频采集器的接口设计,除了初始化方法,主要是有获取视频配置以及视频采集数据回调错误回调的接口,另外就是开始采集停止采集的接口。

有一些不同的是,这里还提供了初始化成功回调视频预览渲染 Layer、以及切换摄像头的接口,这个主要是因为视频采集一般会实现所见即所得,能让用户看到实时采集的画面,这样就需要在初始化成功后让业务层感知到来做一些 UI 布局,并通过预览渲染的 Layer 来展示采集的画面。切换摄像头的接口则主要是对应了手机设备常见的前置、后置等多摄像头的能力。

【学习地址】:FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发

【文章福利】:免费领取更多音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击1079654

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值