(七)深入了解AVFoundation-采集:采集系統架構與 AVCaptureSession 全面梳理

引言

在 iOS 開發中,AVFoundation 是構建音視頻功能的強大底層框架。而在音視頻功能中,“采集”往往是最基礎也是最關鍵的一環。從攝像頭捕捉圖形、到麥克風獲取聲音,構建一條高效且穩定的采集鏈是開發高質量音視頻應用的前提。

本系列將逐步深入 AVFoundation的采集機制,了解它的地方設計與實際使用。在本篇中,我們會聚集在采集系統的核心管理單元——AVCaptureSession,從整體架構出發,梳理采集鏈路的組成方式與搭建流程。

AVCaptureSession 的職責與系統架構

在 AVFoundation 中,AVCaptureSession 是整個采集系統的中心協調者。它的主要職責包括:

  1. 管理輸入(Input)與輸出(Output)設備:例如攝像頭、麥克風作為輸入,圖像幀輸出、音頻數據輸出作為輸出。
  2. 協調數據流的流動:確保從設備捕獲到的數據正確地傳遞到輸出模塊。
  3. 統一管理采集回話的生命周期:如開始采集startRunning()、停止采集stopRunning()、中斷與恢復。
  4. 維護鏈接配置:控制比如視頻方向、鏡像、視頻穩定等細節。

簡而言之,AVCaptureSession?就像是一個數據總管,它把輸入設備(比如攝像頭、麥克風)和輸出目標(比如屏幕預覽、數據編碼器)連接在一起,并統一管理整個采集鏈條的工作狀態。

采集系統的基本架構可以理解成這樣一個數據流動圖。

簡化來說就是:設備->輸入->Session->輸出->處理展示。

  • 一個?AVCaptureSession?可以同時管理多個輸入輸出(比如前后攝像頭切換,或者同時采集視頻與音頻)。
  • 輸入與輸出設備必須通過?session.addInput()?/?session.addOutput()?正式添加到會話中,才會參與采集。
  • 建議在?專用串行 DispatchQueue?中配置 Session,避免 UI 卡頓。

輸入 + 輸出:構建采集模型的兩大核心

在 AVFoundation 采集系統中,采集鏈條的兩大基本構成單元就是:

  1. 輸入(Input)
  2. 輸出(Output)

理解輸入輸出的工作原理和使用方式,是搭建穩定采集系統的基礎。

輸入(Input):采集數據的源頭

輸入負責吧硬件設備(如攝像頭、麥克風)鏈接到AVCaptureSession中。

在實際開發中,我們通常就是使用AVCaptureDeviceInput 來包裝攝像頭和麥克風。

以攝像頭為例:

// 1. 獲取攝像頭設備
guard let camera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) else {fatalError("未找到后置攝像頭")
}// 2. 將設備包裝成輸入
let cameraInput = try AVCaptureDeviceInput(device: camera)// 3. 添加到 Session
if session.canAddInput(cameraInput) {session.addInput(cameraInput)
}

注意事項:

  1. 添加輸入前要用?canAddInput(_:)?檢查是否可以添加。
  2. 注意捕獲設備可能沒有權限,需要提前請求授權。
  3. 創建?AVCaptureDeviceInput?可能拋異常,使用?try。

輸出(Output):采集數據的去向

輸出負責接收采集到的數據,并將其交給需要的地方處理,比如:

  • 顯示預覽畫面
  • 實時處理圖像
  • 保存到文件
  • 推流到服務器

輸出的類型有很多種:

輸出類別

相關類名

描述

圖像數據輸出

AVCaptureVideoDataOutput

原始視頻幀數據回調

音頻數據輸出

AVCaptureAudioDataOutput

原始音頻數據回調

拍照輸出

AVCapturePhotoOutput

拍攝靜態照片

錄制文件輸出

AVCaptureMovieFileOutput

錄制成視頻文件

元數據輸出(如二維碼)

AVCaptureMetadataOutput

檢測并返回元數據(條形碼、二維碼)

輸出基本使用流程(以視頻數據輸出為例)

// 1. 創建輸出
let videoOutput = AVCaptureVideoDataOutput()// 2. 配置輸出參數(如像素格式)
videoOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
]// 3. 設置代理回調隊列
videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "VideoOutputQueue"))// 4. 添加到 Session
if session.canAddOutput(videoOutput) {session.addOutput(videoOutput)
}

代理方法示例(捕獲到每一幀數據):

extension YourClass: AVCaptureVideoDataOutputSampleBufferDelegate {func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {// 處理每一幀圖像}
}

注意事項:

  • 回調通常發生在自定義的串行隊列上,避免占用主線程。
  • 輸出設備也需要使用?canAddOutput(_:)?檢查后再添加。

輸入(Input) 負責采集硬件數據,輸出(Output)負責把采集到的數據交給你處理或者保存。

輸入輸出就像水管的兩端,中間由 AVCaptureSession 統一協調和流轉。

搭建完整采集鏈條

在前面了解了 AVCaptureSession 的基本架構,以及輸入(Input)和輸出(Output)之后,這一部分,我們直接從實際角度出發,梳理一次完整搭建采集鏈條的流程。

完整流程

搭建完整采集鏈條,核心步驟可以總結為:

  1. 創建 AVCaptureSession
  2. 選擇并創建輸入設備(Input)
  3. 選擇并創建輸出設備(Output)
  4. 添加輸入與輸出到 Session
  5. 配置連接參數(如攝像頭方向、鏡像等)
  6. 創建預覽層(可選)
  7. 啟動 Session

整體的偽代碼流程如下:

// 1. 創建 Session
let session = AVCaptureSession()// 2. 配置 preset
session.sessionPreset = .high// 3. 創建輸入(攝像頭)
guard let camera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back),let cameraInput = try? AVCaptureDeviceInput(device: camera),session.canAddInput(cameraInput) else {return
}
session.addInput(cameraInput)// 4. 創建輸出(視頻數據輸出)
let videoOutput = AVCaptureVideoDataOutput()
videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "VideoOutputQueue"))
if session.canAddOutput(videoOutput) {session.addOutput(videoOutput)
}// 5. 配置連接(方向、鏡像)
if let connection = videoOutput.connection(with: .video) {connection.videoOrientation = .portraitconnection.isVideoMirrored = false
}// 6. 創建預覽層(可選)
let previewLayer = AVCaptureVideoPreviewLayer(session: session)
previewLayer.videoGravity = .resizeAspectFill
previewLayer.frame = view.bounds
view.layer.addSublayer(previewLayer)// 7. 啟動 Session
session.startRunning()

采集分辨率的控制開關

sessionPreset?負責定義采集的數據質量,比如分辨率、碼率、幀率等。

常見的 preset 有:

Preset

說明

.high

高質量(設備自動適配)

.medium

中等質量,適配中速網絡上傳場景

.low

低質量,適合弱網傳輸

.hd1280x720

720p 高清

.hd1920x1080

1080p 高清

.photo

照片質量(高分辨率)

注意:

  • preset 需要在?startRunning()?之前設置。
  • preset 要與輸入設備能力匹配,否則設置無效,比如某些前置攝像頭不支持 4K 采集。
  • 可以使用?session.canSetSessionPreset(_:)?檢查兼容性。

連接(AVCaptureConnection)管理

在 Session 里,輸入與輸出之間的通道,叫做?AVCaptureConnection。

連接對象允許我們進一步微調采集流的細節,比如:

  • 方向(Orientation)
  • 鏡像(Mirrored)
  • 視頻防抖(Video Stabilization)
  • 自動對焦/曝光/白平衡(某些連接可以關聯控制)

一般情況下,我們需要手動設置采集方向為豎屏:

if let connection = videoOutput.connection(with: .video),connection.isVideoOrientationSupported {connection.videoOrientation = .portrait
}

很多 app 前置攝像頭拍照是鏡像模式,也可以通過 Connection 設置:

if camera.position == .front,let connection = videoOutput.connection(with: .video),connection.isVideoMirrored {connection.isVideoMirrored = true
}

線程注意點:采集是高度異步的

Session 的?startRunning?和?stopRunning?是同步調用,但異步完成,因此推薦在后臺線程調用。

輸出的數據回調 (captureOutput(_:didOutput:from:)) 是在你指定的 DispatchQueue里觸發的,不是主線程。如果在回調里要更新 UI,需要回到主線程。

DispatchQueue.global().async {session.startRunning()
}// 回調中處理 UI
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {DispatchQueue.main.async {// 更新 UI,比如顯示幀率}
}

結語

在本篇內容中,我們從整體視角出發,完整梳理了?AVCaptureSession?為核心的采集系統,包括它的職責、輸入輸出模型,以及如何搭建一條基本的采集鏈條。

同時也深入探討了?preset 設置、連接管理?和?線程注意事項?等關鍵細節,幫助你在實際項目中少踩坑。

可以看到,AVFoundation 的采集體系雖然靈活強大,但也有一定的復雜度。理解 Session 是怎么組織 Input 和 Output 的,掌握 Connection 上的各種參數調優,才能真正駕馭底層采集系統。

接下來的博客我們將繼續AVFoudation的采集篇章,我們將在這個基礎上,進一步探索更多實戰話題。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/76747.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/76747.shtml
英文地址,請注明出處:http://en.pswp.cn/web/76747.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

QML ShaderEffect(著色器效果)組件

ShaderEffect 是 QML 中用于實現自定義著色器效果的組件,允許開發者使用 GLSL 著色器語言創建圖形效果。 核心屬性 基本屬性 屬性類型默認值說明fragmentShaderstring""片段著色器代碼vertexShaderstring""頂點著色器代碼blendingbooltrue是…

基于javaweb的SSM教材征訂與發放管理系統設計與實現(源碼+文檔+部署講解)

技術范圍:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬蟲、數據可視化、小程序、安卓app、大數據、物聯網、機器學習等設計與開發。 主要內容:免費功能設計、開題報告、任務書、中期檢查PPT、系統功能實現、代碼編寫、論文編寫和輔導、論文…

大模型學習筆記------Llama 3模型架構之分組查詢注意力(GQA)

大模型學習筆記------Llama 3模型架構之分組查詢注意力(GQA) 1、分組查詢注意力(GQA)的動機2、 多頭注意力(Multi-Head Attention, MHA)3、 多查詢注意力 (Multi-Query Attention,MQA)4、 分組查…

matlab 環形單層柱狀圖

matlab 環形單層柱狀圖 matlab 環形單層柱狀圖 matlab 環形單層柱狀圖 圖片 圖片 【圖片來源粉絲】 我給他的思路是:直接使用風玫瑰圖可以畫出。 rose_bar 本次我的更新和這個有些不同!是環形柱狀圖,可調節細節多; 只需要函數…

Docker--Docker網絡原理

虛擬網卡 虛擬網卡(Virtual Network Interface,簡稱vNIC) 是一種在軟件層面模擬的網卡設備,不依賴于物理硬件,而是通過操作系統或虛擬化技術實現網絡通信功能。它允許計算機在虛擬環境中模擬物理網卡的行為&#xff0…

linux基礎14--dns和web+dns

DNS:域名系統(Domain Name System) DNS協議是用來將域名轉換為IP地址或將IP地址轉換為相應的域名 DNS使用TCP和UDP端口53,給用戶提供解析時一般使用UDP53 對于每一級域名長度的限制是63個字符,域名總長度則不能超過2…

C++抽象基類定義與使用

在 C 中,抽象基類(Abstract Base Class, ABC) 是一種特殊的類,用于定義接口規范和約束派生類的行為。它通過純虛函數(Pure Virtual Function)強制要求派生類實現特定功能,自身不能被實例化。以下…

用selenium4 webdriver + java 搭建并完成第一個自動化測試腳本

自動化測試任務: 百度搜索自己的姓名。點擊第一個鏈接(或者第二個),在新的頁面上,添加斷言,驗證你的名字是否存在。 實驗資料百度網盤下載路徑: 鏈接: https://pan.baidu.com/s/1nVlHX_ivres…

LLM大模型中的基礎數學工具—— 約束優化

Q26: 推導拉格朗日乘子法 的 KKT 條件 拉格朗日乘子法與 KKT 條件是啥? 拉格朗日乘子法是解決約束優化問題的利器。比如,想最小化函數 ,同時滿足約束 ,就構造拉格朗日函數 ( 是乘子)。KKT 條件是解這類問…

net+MySQL中小民營企業安全生產管理系統(源碼+lw+部署文檔+講解),源碼可白嫖!

摘要 近些年來,隨著科技的飛速發展,互聯網的普及逐漸延伸到各行各業中,給人們生活帶來了十分的便利,中小民營企業安全生產管理系統利用計算機網絡實現信息化管理,使企業的中小民營企業安全生產管理發展和服務水平有顯…

論文閱讀:2024 arxiv AI Safety in Generative AI Large Language Models: A Survey

總目錄 大模型安全相關研究:https://blog.csdn.net/WhiffeYF/article/details/142132328 AI Safety in Generative AI Large Language Models: A Survey 生成式人工智能大型語言模型中的人工智能安全性:一項調查 https://arxiv.org/pdf/2407.18369 https://www.doubao.com…

【MySQL數據庫】表的約束

目錄 1,空屬性 2,默認值 3,列描述 4,zerofill 5,主鍵primary key 6,自增長auto_increment 7,唯一鍵unique 8,外鍵foreign key 在MySQL中,表的約束是指用于插入的…

基于javaweb的SpringBoot校園失物招領系統設計與實現(源碼+文檔+部署講解)

技術范圍:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬蟲、數據可視化、小程序、安卓app、大數據、物聯網、機器學習等設計與開發。 主要內容:免費功能設計、開題報告、任務書、中期檢查PPT、系統功能實現、代碼編寫、論文編寫和輔導、論文…

多模態大語言模型arxiv論文略讀(二十六)

Holistic Autonomous Driving Understanding by Bird’s-Eye-View Injected Multi-Modal Large Models ?? 論文標題:Holistic Autonomous Driving Understanding by Bird’s-Eye-View Injected Multi-Modal Large Models ?? 論文作者:Xinpeng Ding,…

“星睿O6” AI PC開發套件評測 - 部署PVE搭建All in One NAS服務器

Radxa O6平臺上部署PVE搭建All in One NAS服務器 Radxa O6是一款性能卓越的單板計算機,其強勁的硬件配置和多樣化的接口設計,使其成為家庭和小型企業理想的All in One服務器解決方案。值得一提的是,O6原生配備了兩個5G網口,便于直…

C++ linux打包運行方案(cmake)

文章目錄 背景動態庫打包方案動態庫轉靜態庫動態庫打到軟件包中 運行 背景 使用C編寫的一個小項目,需要打包成ubuntu下的可執行文件,方便分發給其他ubuntu執行,因為docker鏡像方案過于臃腫,所以需要把項目的動態庫都打在軟件包中…

Linux內核編譯(Ubuntu)

實驗內容:在系統中下載統一發行版本的版本號較高的內核,編譯之后運行自己編譯的內核,并使用uname-r命令查看是否運行成功。 實驗步驟: 1.查看實驗環境和內核版本 圖1 實驗環境 VMware中虛擬機Ubuntu(24.04&#xff…

EdgeGPT - 新版Bing聊天功能逆向工程

本文翻譯整理自:https://github.com/acheong08/EdgeGPT 文章目錄 一、關于 EdgeGPT相關鏈接資源關鍵功能特性 二、安裝系統要求安裝命令 三、認證配置獲取Cookie步驟代碼中使用Cookie 四、使用方法1、命令行方式2、Python API方式使用Chatbot類使用Query輔助類 3、…

三網通電玩城平臺系統結構與源碼工程詳解(四):子游戲集成與服務器調度機制全解

本篇將深入講解三網通電玩城平臺中子游戲接入、前后端資源組織方式、服務器調度邏輯、并發接入方案等核心內容,重點覆蓋“李逵劈魚”、“水果瑪麗”、“瘋狂瑪麗”等熱門組件,輔以完整代碼框架與部署邏輯。 一、子游戲資源目錄結構與加載機制 平臺采用標…

1.1 AI大模型與Agent的興起及其對企業數字化轉型的推動作用

隨著人工智能技術的飛速發展,AI大模型和智能代理(Agent)的興起正成為推動企業數字化轉型的重要力量。從2017年GPT-1的首次亮相到2025年GPT-4和Qwen 2.5等多模態模型的成熟,AI大模型經歷了顯著的技術演進;與此同時&…