iOS學習:AVFoundation 視訊流處理
轉自 http://www.cocoachina.com/ios/20150528/11966.html
框架
首先我們從整體對所需框架做個初步瞭解。
AVFoundation在相關框架棧中的的位置:
為了捕捉視訊,我們需要這樣幾種類(與其它的子類)。
-
AVCaptureDevice 代表了輸入裝置,例如攝像頭與麥克風。
-
AVCaptureInput 代表了輸入資料來源
-
AVCaptureOutput 代表了輸出資料來源
-
AVCaptureSession 用於協調輸入與輸出之間的資料流
並且還有AVCaptureVideoPreviewLayer提供攝像頭的預覽功能
可以用這樣一幅圖來概述:
例子
實際應用AVFoundation來捕捉視訊流並不複雜。
Talk is Cheap,Show me the Code.
我們用程式碼簡單地描述用AVFoundation捕捉視訊的過程,其他捕捉音訊,靜態影象的過程也是大同小異的。
1.建立AVCaputureSession。
作為協調輸入與輸出的中心,我們第一步需要建立一個Session
AVCaptureSession *session = [[AVCaptureSession alloc] init];
2.建立AVCaptureDevice
建立一個AVCaptureDevice代表代表輸入裝置。在這裡我們制定裝置用於攝像。
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
3.建立AVCaptureDeviceInput,並新增到Session中
我們需要使用AVCaptureDeviceInput來讓裝置新增到session中, AVCaptureDeviceInput負責管理裝置埠。我們可以理解它為裝置的抽象。一個裝置可能可以同時提供視訊和音訊的捕捉。我們可以分別用AVCaptureDeviceInput來代表視訊輸入和音訊輸入。
NSError *error; AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; [session addInput:input];
4.建立AVCaptureOutput
為了從session中取得資料,我們需要建立一個AVCaptureOutput
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc]init];
5.設定output delegate,將output新增至session,在代理方法中分析視訊流
為了分析視訊流,我們需要為output設定delegate,並且指定delegate方法在哪個執行緒被呼叫。需要主要的是,執行緒必須是序列的,確保視訊幀按序到達。
videoDataOutputQueue = dispatch_queue_create("VideoDataOutputQueue", DISPATCH_QUEUE_SERIAL); [videoDataOutput setSampleBufferDelegate:self queue:videoDataOutputQueue]; [session addOutput:videoDataOutput];
我們可以在delegate方法中分析視訊流。
captureOutput:didOutputSampleBuffer:fromConnection:,
6.開始捕捉
[session startRunning];
通過上面的簡單例子,我麼可以看出使用AVFoundation來捕捉視訊流並不是十分複雜。重點是使用的過程需要了解配置的細節,還有效能問題。
實戰
學習基礎知識過後,讓我們用個具體例子來進行闡明。
我們來做一個基於AVFoundation二維碼識別應用:QRCatcher
專案架構:
|- Model |- URLEntity |- View |- QRURLTableViewCell |- QRTabBar |- Controller |- QRCatchViewController |- QRURLViewController |- Tools |- NSString+Tools |- NSObject+Macro
專案並不複雜。典型的MVC架構.
-
Model層只有一個URLEntity用於儲存捕捉到的URL資訊。 這次專案也順便學習了一下CoreData。感覺良好,配合NSFetchedResultsController工作很幸福。
-
View層則是一個TableViewCell和Tabbar,繼承Tabbar主要用於改變tabbar高度。
-
Controller層中QRCatchViewController負責捕捉與儲存二維碼資訊, QRURLViewController負責展示與管理收集到的URL資訊。
-
Tools則是一些輔助方便開發的類。出自我自己平時使用收集編寫維護的一個工具庫 (開源連結)在這個專案中主要用以檢查URL是否合法,判斷裝置型別等。
介紹完基本的架構後,我們把精力放回AVFoundation模組上來。在這個專案中, AVFoundation主要負責二維碼的掃描與解析。
我們直接來看QRCatchViewController中涉及的程式碼。
對於我們這個應用來說,只需兩步核心步驟即可。
1.設定AVFoundation
- (void)setupAVFoundation { //session self.session = [[AVCaptureSession alloc] init]; //device AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; NSError *error = nil; //input AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; if(input) { [self.session addInput:input]; } else { NSLog(@"%@", error); return; } //output AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init]; [self.session addOutput:output]; [output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]]; [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()]; //add preview layer self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session]; [self.preview.layer addSublayer:self.previewLayer]; //start [self.session startRunning]; }
在這裡我們可以看到和上面建立捕捉視訊流的步驟基本是一致的。
也就是
-
建立session
-
建立device
-
建立input
-
建立output。
這裡是與捕捉視訊流所不一致的地方。我們捕捉視訊流需要的是AVCaptureVideoDataOutput,而在這裡我們需要捕捉的是二維碼資訊。因此我們需要AVCaptureMetadataOutput。並且我們需要指定捕捉的metadataObject型別。在這裡我們指定的是AVMetadataObjectTypeQRCode,我們還可以指定其他型別,例如PDF417條碼型別。
完整的可指定列表可以在這裡找到。
然後我們還要指定處理這些資訊的delegate與佇列。
-
開始錄製
2.實現代理方法:
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection { for (AVMetadataMachineReadableCodeObject *metadata in metadataObjects) { if ([metadata.type isEqualToString:AVMetadataObjectTypeQRCode]) { self.borderView.hidden = NO; if ([metadata.stringValue isURL]) { [[UIApplication sharedApplication] openURL:[NSString HTTPURLFromString:metadata.stringValue]]; [self insertURLEntityWithURL:metadata.stringValue]; self.stringLabel.text = metadata.stringValue; } else { self.stringLabel.text = metadata.stringValue; } } } }
我們需要在代理方法裡面接收資料,並根據自己的需求進行處理。在這裡我簡單地進行了URL的測試,如果是的話則開啟safari進行瀏覽。
總結
在這裡僅僅是通過一個二維碼的應用來展示AVFoundation處理視訊流能力。事實上,AVFoundation能夠做得更多。能夠進行剪輯,處理音軌等功能。如果我們需要對視訊與音訊相關的事務進行處理,不妨在著手處理,尋找第三方解決方案前,看看這個蘋果公司為我們帶來的強大模組。
相關文章
- IOS音視訊(二)AVFoundation視訊捕捉iOS
- iOS開發 AVFoundation 自定義視訊錄製iOS
- IOS音視訊(四十三)AVFoundation 之 Audio SessioniOSSession
- SparkStreaming實時流處理學習Spark
- iOS AVPlayer播放視訊的留白處理iOS
- iOS 學習視訊 資料集合 (視訊 +部落格)iOS
- iOS使用AVFoundation在視訊上新增字幕以及控制字幕時間iOS
- Python-OpenCV 處理視訊(二): 視訊處理PythonOpenCV
- 唱吧 iOS 音視訊快取處理框架iOS快取框架
- iOS 中多音訊處理iOS音訊
- IOS 訊息推送處理iOS
- iOS視訊流採集概述(AVCaptureSession)iOSAPTSession
- .net core 訊息流處理流程
- AVFoundation (iOS) 簡介iOS
- 視訊處理之OSD
- 前端視角看視訊處理前端
- ios網路學習------9 播放網路視訊iOS
- Python-OpenCV 處理視訊(一)(二): 輸入輸出 視訊處理PythonOpenCV
- iOS視訊處理之增加動畫掛件和Image邊框iOS動畫
- opencv 視訊處理相關OpenCV
- 多功能視訊處理方案
- 使用FFmpeg處理音視訊
- 用Python處理視訊Python
- 視訊直播技術之iOS端推流iOS
- 批處理----學習
- AVFoundation | 封裝一個好用的視訊播放器封裝播放器
- 音視訊學習 (十一) Android 端實現 rtmp 推流Android
- 視訊播放學習
- java學習視訊Java
- php實現ffmpeg處理視訊PHP
- 【視訊處理】YUV格式說明
- 我的 iOS 音訊處理總結iOS音訊
- iOS 視訊直播與錄播拉流框架2.0iOS框架
- 全面學習MySQL中的檢視(3) 指定檢視處理方式MySql
- Streams 流處理
- 關於視訊流媒體伺服器的學習記錄伺服器
- Android音視訊處理之MediaMuxerAndroidUX
- GoPro Quik電腦版,視訊處理GoUI