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
这里的参数包括了:分辨率、摄像头位置、画面方向、帧率、颜色空间格式、镜像类型这几个参数。
其中画面方向是指采集的视频画面是可以带方向的,包括:Portrait、PortraitUpsideDown、LandscapeRight、LandscapeLeft 这几种。
颜色空间格式对应 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

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

被折叠的 条评论
为什么被折叠?



