AVCapture iOS 系統相機知多少 - AVFoundation

語言: CN / TW / HK

幾個列舉值

捕捉畫面的質量的屬性

``` 我們可以通過設定AVCaptureSession的一些屬性來改變捕捉畫面的質量
但是要注意:size相關的屬性的時候需要首先進行測試裝置是否支援 判斷方法是 canSetSessionPreset

AVCaptureSessionPresetPhoto ——適用於高解析度照片質量輸出

AVCaptureSessionPresetHigh ——適用於高質量影片和音訊輸出

AVCaptureSessionPresetMedium ——適用於中等質量輸出,適合通過WiFi共享的輸出影片和音訊位元率

AVCaptureSessionPresetLow ——適用於低質量輸出,實現適合通過3G共享的輸出影片和音訊位元率

AVCaptureSessionPreset320x240 ——適用於320x240影片輸出

AVCaptureSessionPreset352x288 ——適用於352x288影片輸出

AVCaptureSessionPreset640x480 ——適用於640x480影片輸出

AVCaptureSessionPreset960x540 ——適用於960x540影片輸出

AVCaptureSessionPreset1280x720 ——適用於1280x720影片輸出

AVCaptureSessionPreset1920x1080 ——適用於1920x1080影片輸出

AVCaptureSessionPreset3840x2160 ——適用於3840x2160(UHD 4K)影片輸出

AVCaptureSessionPresetiFrame960x540 ——可生成960x540 Apple iFrame影片和音訊內容。以使用AAC音訊以~30 Mbits / sec的速度實現960x540質量的iFrame H.264影片。 以iFrame格式捕獲的QuickTime影片最適合編輯應用程式

AVCaptureSessionPresetiFrame1280x720 ——可生成1280x720 Apple iFrame影片和音訊內容。以使用AAC音訊以~40 Mbits / sec的速度實現1280x720質量的iFrame H.264影片。 以iFrame格式捕獲的QuickTime影片最適合編輯應用程式

AVCaptureSessionPresetInputPriority ——指示會話輸入的格式優先,此更改表明客戶端選擇的輸入格式現在決定了輸出端提供的服務質量等級。當客戶端將會話預設設定為除AVCaptureSessionPresetInputPriority以外的任何其他內容時,會話將繼續負責配置輸入和輸出,並可根據需要隨意更改其輸入的activeFormat

```

設定攝像頭的方向

typedef NS_ENUM(NSInteger, AVCaptureDevicePosition) { AVCaptureDevicePositionUnspecified = 0, // 最近開啟的方向,記錄最近時間開啟的方向 AVCaptureDevicePositionBack = 1, // 後置攝像頭 AVCaptureDevicePositionFront = 2 // 前置攝像頭 } NS_AVAILABLE(10_7, 4_0) __TVOS_PROHIBITED;

設定閃光燈模式

typedef NS_ENUM(NSInteger, AVCaptureFlashMode) { AVCaptureFlashModeOff = 0, // 關閉閃光燈 AVCaptureFlashModeOn = 1, // 開啟閃光燈 AVCaptureFlashModeAuto = 2 // 自動模式 } NS_AVAILABLE(10_7, 4_0) __TVOS_PROHIBITED;

手電筒模式

typedef NS_ENUM(NSInteger, AVCaptureTorchMode) { AVCaptureTorchModeOff = 0, // 手電筒關閉 AVCaptureTorchModeOn = 1, // 手電筒開啟 AVCaptureTorchModeAuto = 2, // 手電筒自動模式 } NS_AVAILABLE(10_7, 4_0) __TVOS_PROHIBITED;

系統對焦模式

typedef NS_ENUM(NSInteger, AVCaptureAutoFocusSystem) { AVCaptureAutoFocusSystemNone = 0, // 不設定對焦模式 AVCaptureAutoFocusSystemContrastDetection = 1, // 對比度檢測對焦 AVCaptureAutoFocusSystemPhaseDetection = 2, // 相位檢測對焦 } NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;

影片防抖動模式

typedef NS_ENUM(NSInteger, AVCaptureVideoStabilizationMode) { AVCaptureVideoStabilizationModeOff = 0, // 影片防抖動模式關閉 AVCaptureVideoStabilizationModeStandard = 1, // 影片防抖標準模式 AVCaptureVideoStabilizationModeCinematic = 2, // 影片防抖電影模式 AVCaptureVideoStabilizationModeAuto = -1, // 影片防抖自動模式 } NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;

焦距調整

typedef NS_ENUM(NSInteger, AVCaptureFocusMode) { AVCaptureFocusModeLocked = 0, // 鎖定對焦 AVCaptureFocusModeAutoFocus = 1, // 自動對焦模式 AVCaptureFocusModeContinuousAutoFocus = 2, // 連續自動對焦 } NS_AVAILABLE(10_7, 4_0) __TVOS_PROHIBITED;

自動對焦範圍限制

typedef NS_ENUM(NSInteger, AVCaptureAutoFocusRangeRestriction) { AVCaptureAutoFocusRangeRestrictionNone = 0, // 不限制 AVCaptureAutoFocusRangeRestrictionNear = 1, // 近距離對焦模式 AVCaptureAutoFocusRangeRestrictionFar = 2, // 遠距離對焦模式 } NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;

曝光模式設定

typedef NS_ENUM(NSInteger, AVCaptureExposureMode) { AVCaptureExposureModeLocked = 0, // 鎖定曝光 AVCaptureExposureModeAutoExpose = 1, // 自動曝光模式 AVCaptureExposureModeContinuousAutoExposure = 2, // 連續自動曝光模式 AVCaptureExposureModeCustom NS_ENUM_AVAILABLE_IOS(8_0) = 3, // 自定義曝光模式 } NS_AVAILABLE(10_7, 4_0) __TVOS_PROHIBITED;

白平衡模式

typedef NS_ENUM(NSInteger, AVCaptureWhiteBalanceMode) { AVCaptureWhiteBalanceModeLocked = 0, // 鎖定白平衡模式 AVCaptureWhiteBalanceModeAutoWhiteBalance = 1, // 自動 AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance = 2, // 連續自動 } NS_AVAILABLE(10_7, 4_0) __TVOS_PROHIBITED;

授權狀態 使用者是否已經允許啟用裝置

typedef NS_ENUM(NSInteger, AVAuthorizationStatus) { AVAuthorizationStatusNotDetermined = 0, // 授權狀態未確定 AVAuthorizationStatusRestricted, // 授權受限 AVAuthorizationStatusDenied, // 授權被拒絕 AVAuthorizationStatusAuthorized // 授權被許可 } NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;

表示傳輸控制元件當前播放模式的列舉 - 播放控制模式

typedef NS_ENUM(NSInteger, AVCaptureDeviceTransportControlsPlaybackMode) { AVCaptureDeviceTransportControlsNotPlayingMode = 0, AVCaptureDeviceTransportControlsPlayingMode = 1 } NS_AVAILABLE(10_7, NA) __TVOS_PROHIBITED;

幾個物件

存在的幾個物件的理解

  • AVCaptureDevice //硬體裝置
  • AVCaptureInput //輸入的裝置
  • AVCaptureOutput //輸出的資料
  • AVCaotureSession //協助input和output的資料傳輸

關係: \ 有很多Device的input和很多型別的Output,都通過一個CaptureSession來控制進行傳輸,即:CaputureDevice適配AVCaptureInput,通過Session來輸入到AVCaptureOutput中,這樣就達到了從裝置到檔案等持久傳輸的目的(如從相機裝置採集影象到UIImage中)

那麼如果影片輸入(input)和對應的影片輸出(output),音訊對應音訊,因而需要建立對應的Connections(連線),來各自連線它們,這個連線物件是由AVCaptureSession持有的,這個物件為 AVCaptureConnection,可以控制input和output的資料傳輸(通過各種的input port,都可以獲取到相應的資料)

AVCaotureSession

self.captureSession = [[AVCaptureSession alloc] init]; [self.captureSession startRunning]; 需要建立一個session,發running訊息,響應,就把輸入裝置的東西,提交到輸出裝置中。

如果想在一個已經使用session中(已經startRunning)更換新的device,刪除舊的,方法

[session beginConfiguration]; [session commitConfiguration];

``` //切換攝像頭 - (BOOL)switchCameras {

//判斷是否有多個攝像頭
if (![self canSwitchCameras]){
    return NO;
}

//獲取當前裝置的反向裝置
NSError *error;
AVCaptureDevice *videoDevice = [self inactiveCamera];//返回當前未啟用的攝像頭


//將輸入裝置封裝成AVCaptureDeviceInput
AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];

//判斷videoInput 是否為nil
if (videoInput)
{
    //標註原配置變化開始
    [self.captureSession beginConfiguration];

    //將捕捉會話中,原本的捕捉輸入裝置移除
    [self.captureSession removeInput:self.activeVideoInput];

    //判斷新的裝置是否能加入
    if ([self.captureSession canAddInput:videoInput])
    {
        //能加入成功,則將videoInput 作為新的影片捕捉裝置
        [self.captureSession addInput:videoInput];

        //將獲得裝置 改為 videoInput
        self.activeVideoInput = videoInput;
    }else
    {
        //如果新裝置,無法加入。則將原本的影片捕捉裝置重新加入到捕捉會話中
        [self.captureSession addInput:self.activeVideoInput];
    }

    //配置完成後, AVCaptureSession commitConfiguration 會分批的將所有變更整合在一起。
    [self.captureSession commitConfiguration];
}else{
    return NO;
}
return YES;

} ```

AVCaptureDevice

Device是對硬體的一對一的表示,一個AVCaptureDevice物件,對應一個實際的硬體裝置\

``` / 建立並配置輸入裝置 / AVCaptureDevice device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; if (device==nil) { UIAlertController alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"裝置沒有攝像頭" preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"確認" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

    }]];
    [self presentViewController:alert animated:YES completion:nil];
    return;
}
// Device
_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

// Input
_input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];

//Out put
AVCaptureStillImageOutput *imageOutput; //圖片的輸出
AVCaptureMovieFileOutput *movieOutput; //影片的輸出

self.movieOutput = [[AVCaptureMovieFileOutput alloc]init];

``` 然後新增input到session的模式(檢查是否可新增)

``` // Session 新增輸入輸出裝置前要判斷該手機(裝置)能否新增輸入輸出裝置。 _session = [[AVCaptureSession alloc]init]; [_session setSessionPreset:AVCaptureSessionPresetHigh]; if ([_session canAddInput:self.input]) { [_session addInput:self.input]; }

//if ([_session canAddOutput:self.output])
//{
//    [_session addOutput:self.output];
//}
if ([self.captureSession canAddOutput:self.movieOutput]){
    [self.captureSession addOutput:self.movieOutput];
}

```

AVCaptureOutput

Output的使用 \ ios中,分為MovieFile(輸出成movie檔案)、VideoData(適用各個Frame的處理)、AudioData(聲音採集)、StillImage(靜態影象拍照)幾種output,它們都繼承與AVCaptureOutput

AVCaptureDeviceInput

self.input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];