互联网技术 · 2024年2月8日 0

基于 AVFoundation 框架的小视频功能解析

开发视频录制功能最简单的就是使用系统封装的 UIImagePickerController,但是这种方式比较封闭,可自定义东西比较少,所以就需要基于 AVFoundation 框架来开发视频录制功能。基于 AVFoundation 框架来开发,则需要自己手动设置设备音频,视频输入、输出。

AVCaptureSession 是 AVFoundation 的核心类,用于管理捕获对象 AVCaptureInput 的视频和音频的输入,协调捕获的输出 AVCaptureOutput。AVCaptureOutput 的输出有两种方法:一种是直接以 movieFileUrl 方式输出;一种是以原始数据流 data 的方式输出,流程对比图如下:

基于 AVFoundation 框架的小视频功能解析

下面详细讲解两种录制视频的方案:

(1) AVCaptureSession + AVCaptureMovieFileOutput

1. 创建 AVCaptureSession

基于 AVFoundation 框架的小视频功能解析

注意:AVCaptureSession 的调用是会阻塞线程的,建议单独开辟子线程处理。

2. 设置音频、视频输入

基于 AVFoundation 框架的小视频功能解析

3. 设置文件输出源

基于 AVFoundation 框架的小视频功能解析

4. 添加视频预览层

基于 AVFoundation 框架的小视频功能解析

5. 开始采集

基于 AVFoundation 框架的小视频功能解析

6. 开始录制

基于 AVFoundation 框架的小视频功能解析

当实际的录制开始或停止时,系统会有代理回调。当开始录制之后,这时可能还没有真正写入,真正开始写入会回调下面代理,停止录制也是如此,所以如果你需要对录制视频起始点操作,建议通过系统的回调代理:

基于 AVFoundation 框架的小视频功能解析

7. 停止录制

基于 AVFoundation 框架的小视频功能解析

8. 停止采集

基于 AVFoundation 框架的小视频功能解析

(2) AVCaptureSession + AVAssetWriter

1. 创建 AVCaptureSession

基于 AVFoundation 框架的小视频功能解析

2. 设置音频、视频输入

基于 AVFoundation 框架的小视频功能解析

3. 设置音频 Data、视频 Data 输出

基于 AVFoundation 框架的小视频功能解析

4. 添加视频预览层

基于 AVFoundation 框架的小视频功能解析

5. 开始采集

基于 AVFoundation 框架的小视频功能解析

和第一种方式不同,第一种方式是开始录制之后,movieFileOutput 的回调才会触发,停止录制回调触发之后也就完成了。AVCaptureSession + AVAssetWriter 方式因为在设置输出源的时候,把输出代理 (setSampleBufferDelegate)已经设置好了,所以一旦开始采集(startRunning),数据流回调也就触发了。

基于 AVFoundation 框架的小视频功能解析

6. 开始录制

这里需要创建AVAssetWriter,配置音频、视频录制参数,录制写入过程要单独开辟线程处理,避免阻塞线程,可以和 AVCaptureSession 放在同一线程处理。

基于 AVFoundation 框架的小视频功能解析

7. 处理数据流

开始采集,数据流就会回调,所以这里用了变量 isRecording 来界定当前是否需要对数据处理,一般是在 startRecord 和 stopRecord 才会去处理数据流。

基于 AVFoundation 框架的小视频功能解析

8. 停止录制

基于 AVFoundation 框架的小视频功能解析

9. 停止采集

基于 AVFoundation 框架的小视频功能解析

两种方案对比:

相同点:他们的数据采集都是通过 AVCaptureSession 处理,音频视频的输入源也是一致的,画面预览一致。

不同点:输出源不一样,前者输出是 fileUrl,也就是说在视频写入完成之前开发者无法操作处理;后者输出是 data,AVAssetWriter 需要拿到 AVCaptureVideoDataOutput 和 AVCaptureAudioDataOutput 两个单独的输出,然后分别处理再写入指定路径。输出方式不同,决定了开发者对视频处理剪裁压缩的方式也就不同,前者如果需要对视频剪裁压缩,就需要从本地取出完整的视频文件,再做处理;而 AVAssetWriter 拿到的是数据流 data,如果需要剪裁压缩,可以直接配置相关参数后处理数据流,这样写入本地的就是已经处理过的视频文件。

其他功能点扩充

1. 聚焦处理

基于 AVFoundation 框架的小视频功能解析

2. 摄像头切换

基于 AVFoundation 框架的小视频功能解析