你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> iOS學習:AVFoundation 視頻流處理

iOS學習:AVFoundation 視頻流處理

編輯:IOS開發基礎

框架

首先我們從整體對所需框架做個初步了解。

AVFoundation在相關框架棧中的的位置:

1.jpg

為了捕捉視頻,我們需要這樣幾種類(與其它的子類)。

  • AVCaptureDevice 代表了輸入設備,例如攝像頭與麥克風。

  • AVCaptureInput 代表了輸入數據源

  • AVCaptureOutput 代表了輸出數據源

  • AVCaptureSession 用於協調輸入與輸出之間的數據流

並且還有AVCaptureVideoPreviewLayer提供攝像頭的預覽功能

可以用這樣一幅圖來概述: 

2.jpg

例子

實際應用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

3.jpg

應用已經上架AppStore 並且完整開源

項目架構:

|- 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];
}

在這裡我們可以看到和上面創建捕捉視頻流的步驟基本是一致的。

也就是

  1. 創建session

  2. 創建device

  3. 創建input

  4. 創建output。

    這裡是與捕捉視頻流所不一致的地方。我們捕捉視頻流需要的是AVCaptureVideoDataOutput,而在這裡我們需要捕捉的是二維碼信息。因此我們需要AVCaptureMetadataOutput。並且我們需要指定捕捉的metadataObject類型。在這裡我們指定的是AVMetadataObjectTypeQRCode,我們還可以指定其他類型,例如PDF417條碼類型。

    完整的可指定列表可以在這裡找到。

    然後我們還要指定處理這些信息的delegate與隊列。

  5. 開始錄制

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能夠做得更多。能夠進行剪輯,處理音軌等功能。如果我們需要對視頻與音頻相關的事務進行處理,不妨在著手處理,尋找第三方解決方案前,看看這個蘋果公司為我們帶來的強大模塊。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved