框架git
首先咱們從總體對所需框架作個初步瞭解。github
AVFoundation在相關框架棧中的的位置:session
爲了捕捉視頻,咱們須要這樣幾種類(與其它的子類)。架構
AVCaptureDevice 表明了輸入設備,例如攝像頭與麥克風。app
AVCaptureInput 表明了輸入數據源框架
AVCaptureOutput 表明了輸出數據源ide
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可以作得更多。可以進行剪輯,處理音軌等功能。若是咱們須要對視頻與音頻相關的事務進行處理,不妨在着手處理,尋找第三方解決方案前,看看這個蘋果公司爲咱們帶來的強大模塊。