当前位置: 首页 > news >正文

(十)深入了解AVFoundation-采集:录制视频功能的实现

引言

在前文章中,我们深入探讨了如何通过 AVCaptureSession 配置 iOS 中的捕捉输入及输出。并通过使用 AVCaptureDeviceInput 和 AVCapturePhotoOutput,我们实现了基础的照片捕获功能,并配置了 PHPreviewView 来显示实时预览。

在本篇中,我们将继续沿用前两篇的基本配置思路,但重点转向如何实现 高清视频和音频的录制。尽管大部分配置流程和前面的内容相似,主要区别在于,我们需要使用 AVCaptureMovieFileOutput 来处理视频录制,并结合音频输入和输出进行同步。通过这种方式,我们可以实现一个完整的多媒体录制系统,同时捕获视频和音频流。

搭建视频录制功能

为了更好的理解视频录制整体搭建流程,我们将其功能封装到一个 PHCaptureRecordController 类中,它将会负责视频录制的全部操作流程:

  1. 配置 AVCaptureSession。
  2. 添加摄像头输入。
  3. 添加视频录制输出。
  4. 启动与停止会话。
  5. 处理视频录制完成数据。

1. 类的基本结构

我们先来创建一个PHCaptureRecordController类,大致结构如下:

import UIKit
import AVFoundationclass PHCaptureRecordController: NSObject {/// 会话let session = AVCaptureSession()/// 输出private let moviceFileOutput = AVCaptureMovieFileOutput()/// 输入private var captureDeviceInput: AVCaptureDeviceInput?/// 队列private let sessionQueue = DispatchQueue(label: "com.example.captureSession")/// 代理weak var delegate: PHCaptureProtocol?/// 配置会话func setupConfigureSession() {}/// 启动会话func startSession() {}/// 停止会话func stopSession() {}/// 开始录制func startRecording() {}/// 停止录制func stopRecording() {}}

可以看到我们在类的内部维护了:

  1. session:采集会话。
  2. moviceFileOutput:用于视频录制的会话输出。
  3. captureDeviceInput:当前使用的会话输入。
  4. sessionQueue:串行队列,保证采集相关操作的线程安全。
  5. delegate:代理,负责错误和结果的回调。

2. 配置采集会话

我们在 setupConfigureSession 方法中需要完成三个操作:

  1. 设置会话预设。
  2. 添加摄像头输入。
  3. 添加照片输出。

并且保证这些操作需要在会话 beginConfiguration 与 commitConfiguration 方法之间执行。

    /// 配置会话func setupConfigureSession() {session.beginConfiguration()// 1.设置会话预设setupSessionPreset()// 2.设置会话输入if !setupSessionInput() {delegate?.captureError(NSError(domain: "PHCaptureController", code: 1001, userInfo: [NSLocalizedDescriptionKey: "Failed to add input"]))return}// 3.设置会话输出if !setupSessionOutput() {delegate?.captureError(NSError(domain: "PHCaptureController", code: 1002, userInfo: [NSLocalizedDescriptionKey: "Failed to add output"]))return}session.commitConfiguration()}

2.1 设置会话预设

在配置 AVCaptureSession 时,我们需要选择适当的预设(preset)来确定录制视频的质量。AVCaptureSession 提供了多种预设选项,每个选项对应不同的视频分辨率和帧率。

例如,以下代码设置会话的预设为 .high,这意味着录制的视频将以较高的质量进行处理,适用于需要高清视频的场景:

    /// 设置会话话预设private func setupSessionPreset() {session.sessionPreset = .high}

2.2 设置会话输入

在视频录制中我们要同时设置摄像头及麦克风的输入,并确保这两个输入都成功被添加到会话,有一个失败则认为是设置失败。

    /// 设置会话输入private func setupSessionInput(device: AVCaptureDevice? = nil) -> Bool {// 1.获取摄像头guard let device = device else { return false }do {captureDeviceInput = try AVCaptureDeviceInput(device: device)if session.canAddInput(captureDeviceInput!) {session.addInput(captureDeviceInput!)} else {return false}} catch {delegate?.captureError(error)return false}//2.获取麦克风guard let audioDevice = AVCaptureDevice.default(for: .audio) else { return false }do {let audioInput = try AVCaptureDeviceInput(device: audioDevice)if session.canAddInput(audioInput) {session.addInput(audioInput)return true} else {return false}} catch {delegate?.captureError(error)return false}}

2.3 设置回话输出

在完成输入设备的配置之后,我们需要设置输出设备,以便从会话中捕获视频、音频数据。

/// 设置会话输出private func setupSessionOutput() -> Bool {if session.canAddOutput(moviceFileOutput) {session.addOutput(moviceFileOutput)return true} else {return false}}

3. 会话的启动与停止

我们同样使用单独的串行队列来管理会话的启动与停止,避免出现线程问题。

    /// 启动会话func startSession() {sessionQueue.async {if !self.session.isRunning {self.session.startRunning()}}}/// 停止会话func stopSession() {sessionQueue.async {if self.session.isRunning {self.session.stopRunning()}}}

4. 开始与停止录制

在配置好输入设备和输出设备后,我们可以通过 AVCaptureMovieFileOutput 来控制视频的录制。AVCaptureMovieFileOutput 提供了两个主要方法:startRecording 和 stopRecording,用于开始和停止视频录制。

开始录制

开始录制时,我们需要指定一个文件保存路径,并调用 startRecording 方法开始录制。以下是实现代码:

/// 开始录制
func startRecording() {// 设置输出文件路径let outputURL = FileManager.default.temporaryDirectory.appendingPathComponent("output.mov")// 启动录制moviceFileOutput.startRecording(to: outputURL, recordingDelegate: self)
}
  1. 输出路径:我们使用 FileManager.default.temporaryDirectory 来创建一个临时文件夹,并为录制的视频指定一个保存路径。这里保存的是 .mov 格式的视频文件。
  2. 启动录制:调用 startRecording(to: recordingDelegate:) 方法,传入输出文件路径和录制的代理对象。代理对象负责处理录制过程中产生的各种事件,例如录制的开始、停止、失败等。
停止录制

录制完成后,我们需要调用 stopRecording 方法来结束录制,并将录制的视频保存到指定的文件路径中。以下是停止录制的代码实现:

/// 停止录制
func stopRecording() {// 停止录制moviceFileOutput.stopRecording()
}

调用 stopRecording() 后,AVCaptureMovieFileOutput 会停止录制视频,并将录制的视频保存到先前指定的输出路径。此时,代理方法会被触发,我们可以在代理方法中处理保存的文件或进行其他后续操作。

5. 录制完成的代理方法

当视频录制完成时,AVCaptureMovieFileOutput 会调用 AVCaptureFileOutputRecordingDelegate 的 fileOutput(_:didFinishRecordingTo:from:connections:error:) 方法。我们可以通过这个方法获取录制的文件路径,并处理录制结果。

以下是代理方法的代码实现:

// MARK: AVCaptureFileOutputRecordingDelegate
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: (any Error)?) {if let error = error {// 录制过程中发生错误,调用错误回调delegate?.captureError(error)} else {// 录制完成,处理视频文件// 可以将 outputFileURL 移动到你想要保存的位置delegate?.captureVideo(outputFileURL)}
}
  1. outputFileURL:这是录制视频的输出文件 URL,包含了录制完成的视频文件路径。你可以根据需要将其移动或拷贝到其他位置进行后续处理。
  2. connections:表示输出连接的数组,通常情况下,我们只关心视频录制的连接。
  3. error:如果录制过程中出现错误,该参数会包含错误信息。我们可以检查并处理错误。

结语

在本篇中,我们详细介绍了如何在 iOS 中实现高清视频与音频的录制。从配置 AVCaptureSession 和添加输入输出设备,到设置视频和音频的录制输出,我们逐步完成了录制会话的初始化和控制。特别是在开始与停止录制部分,我们展示了如何通过 AVCaptureMovieFileOutput 控制录制的启动与停止,并通过代理方法处理录制完成后的文件。

接下来,你可以根据项目需求进一步优化视频录制体验,例如添加实时预览、录制过程中动态调整质量,或者对录制的文件进行后期处理(如视频编辑、转码等)。

感谢阅读。

http://www.xdnf.cn/news/297721.html

相关文章:

  • HTTP 与 HTTPS 的深度剖析:差异、原理与应用场景
  • Day17 聚类算法(K-Means、DBSCAN、层次聚类)
  • MacOS+VSCODE 安装esp-adf详细流程
  • Three.js和WebGL区别、应用建议
  • 【奔跑吧!Linux 内核(第二版)】第1章:Linux 系统基础知识
  • 【测试开发】概念篇 - 从理解需求到认识常见开发、测试模型
  • 第二节:Vben Admin 最新 v5.0 对接后端登录接口(上)
  • 用OMS从MySQL迁移到OceanBase,字符集utf8与utf8mb4的差异
  • 如何保障服务器租用中的数据安全?
  • 基于 Trae 的单细胞 RNA 测序分析与可视化
  • Linux下的好玩的命令
  • Linux:进程间通信---命名管道共享内存
  • Android组件化 -> Debug模式下,本地构建module模块的AAR和APK
  • Nginx安全防护与HTTPS部署
  • 如何搭建spark yarn模式集群的集群
  • OpenKylin安装Elastic Search8
  • 多线程“CPU 飙高”问题:如何确保配置的线程数与CPU核数匹配(Java、GoLang、Python )中的最佳实践解决方案
  • 数据分析指标体系
  • 深度剖析:可视化如何重塑驾驶舱信息交互模式
  • [Linux]多线程(一)充分理解线程库
  • 天文探秘学习小结
  • 【Linux系统】探索进程等待与程序替换的奥秘
  • Java引用RabbitMQ快速入门
  • 2025 后端自学UNIAPP【项目实战:旅游项目】1、创建项目框架
  • Linux之基础开发工具二(makefile,git,gdb)
  • react naive 网络框架源码解析
  • React Hooks 深入浅出
  • EasyRTC嵌入式音视频通信SDK技术,助力工业制造多场景实时监控与音视频通信
  • Apache Velocity代码生成简要介绍
  • css3伸缩盒模型第二章(侧轴相关)