ios多媒體採集

iOS媒體採集

媒體採集

媒體採集,在這個流程中,這裏會存在幾個對象:

  • AVCaptureDevice。這裏代表抽象的硬件設備。
  • AVCaptureInput。這裏代表輸入設備(可以是它的子類),它配置抽象硬件設備的ports。
  • AVCaptureOutput。它代表輸出數據,管理着輸出到一個movie或者圖像。
  • AVCaptureSession。它是input和output的橋樑。它協調着intput到output的數據傳輸。

上述對象的關係:

有很多Device的input,也有很多數據類型的Output,都通過一個Capture Session來控制進行傳輸。也即:CaptureDevice適配AVCaptureInput,通過Session來輸入到AVCaptureOutput中。這樣也就達到了從設備到文件等持久化傳輸的目的(如從相機設備採集圖像到UIImage中)。

特別注意,這裏的關係是可以通過一個Capture Session來同時控制多個設備的輸入和輸出。

那麼存在一個問題了:視頻輸入(input)就對應視頻的輸出(output),而音頻輸入就應對應音頻的輸出,因而需要建立對應的Connections,來各自連接它們。而這樣的連接對象,是由AVCaptureSession來持有的,這個對象叫AVCaptureConnection。

在一個AVCaptureConnection中,這裏維持着對應的數據傳輸輸入到數據輸出的過程(detail過程)。這裏,AVCaptureInput或其子類對象包含着各種input port,通過各種input port,我們的AVCaptureOutput可以獲取到相應的數據。

一個AVCaptureConnection可以控制input到output的數據傳輸。

當使用addInput:或addOutput:,Connection在所有兼容的輸入和輸出之間自動形成。手動添Connection是在在添加一個輸入或輸出時沒有形成連接的時候。

AVCaptureDevice

InputDevice即是對硬件的抽象,一對一的。一個AVCaptureDevice對象,對應一個實際的硬件設備。

那麼顯然,我們可以通過AVCaptureDevice的類方法devices或devicesWithMediaType去獲取全部或局部設備列表。(當然也可以檢測相應的設備是否可以使用,這裏注意有設備搶佔問題,當前是否可用)

CaptureInput的構建和添加到Session中的方法

/*創建並配置輸入設備*/

AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (error){
    //handle the failure.
}

//添加input到session的模式是(檢查可否添加到session,然後根據情況添加或者不添加):
AVCaptureSession *captureSession = <#Get a capture session#>;
if ([captureSession canAddInput:input]) {
    [captureSession addInput:captureDeviceInput];
}
else{
    //handle the failure.
}

output的分類和使用

什麼類型的輸出,決定了什麼輸出數據的類型。在ios中,分爲MovieFile、VideoData、AudioFile、AudioData、StillImage和Metadata幾種output,使用方式類似,只是範圍不同。另外,它們都繼承於AVCaptureOutput,其自身是抽象類。

第一個是輸出成movie文件,第二個適用於逐個Frame的處理,第三個適用於輸出成聲音文件,第四個適用於聲音採集,第五個是still image(靜態圖像<拍照>)相關,最後一個用於輸出元數據(面部識別、條碼等)。

他們的添加方式都是使用session的addOutput方法。

二維碼的掃描的實現

1.獲得掃描設備:(攝像頭)。

AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

2.生成連接設備和session的input。

NSError *error;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if(error){
    NSLog(@"%@", error.localizedDescription);
}

3.AVCaptureOutput。

在ios6之後,新增Output的實現類AVCaptureMetadataOutput。

AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutput alloc] init];
dispatch_queue_t dispatchQueue;
dispatchQueue = dispatch_queue_create("hellp", NULL);
[output setMetadataObjectsDelegate:self queue:dispatchQueue];

4.AVCaptureSession。

AVCaptureSession *session  = [[AVCaptureSession alloc] init];
[session addInput:input];
[session addOutput:output];
//注意:設置AVMetadataMachineReadableCodeObject的可輸出的元數據類型,一定要講output添加到session中後,再設置;
[output setMetadataObjectTypes:[NSArray arrayWithObjects:
                                                   AVMetadataObjectTypeEAN13Code,
                                                   AVMetadataObjectTypeCode39Code,
                                                   AVMetadataObjectTypeEAN8Code,
                                                   AVMetadataObjectTypeCode128Code,
                                                   AVMetadataObjectTypeQRCode, nil]];

5.AVCaptureVideoPreviewLayer,CALayer的子類,可以預覽device撲捉的畫面。

AVCaptureVideoPreviewLayer *videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_session];
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章