iOS-鏡頭采集(Camera capture&AVCaptureSession)

iPhone 手機(jī)在圖片拍照和視頻錄制方面有很強(qiáng)大的功能,小編認(rèn)為如果很好使用 iPhone 拍攝出很好照片 & 錄制很有趣的視頻。本章將詳細(xì)講解 AVCaptureSession ,并最后給出 FYCameraKit 項(xiàng)目Demo。
下面小編為大家講解 iOS 拍照和視頻錄制功能實(shí)現(xiàn),下圖是鏡頭采集需要的類:

iOS-Camera Capture (iOS 鏡頭采集).png

總體介紹

在整個鏡頭采集過程小編把整個過程比作我們常見發(fā)電過程:均是通過特定的步驟實(shí)現(xiàn)得到最后的產(chǎn)物。下面??做詳細(xì)解釋:

AVCaptureSession (發(fā)電機(jī))

AVCaptureSession :作為音視頻捕捉會話,把鏡頭和麥克風(fēng)捕捉到的音視頻源輸出到設(shè)備中。
提示:可以有多個輸入和輸出。

AVCaptureDevice (發(fā)電設(shè)備)

AVCaptureDevice:輸入設(shè)備,包括:攝像頭和麥克風(fēng)??梢酝ㄟ^設(shè)置一些參數(shù)來調(diào)節(jié)設(shè)備采集效果(例如:曝光,白平衡和聚焦等)。

AVCaptureInput (水風(fēng)能源)

AVCaptureInput:輸入數(shù)據(jù)管理對象,經(jīng)過 AVCaptureDevice 實(shí)現(xiàn)初始化,然后添加到 AVCaptureSession (發(fā)電機(jī)) 中進(jìn)行相應(yīng)的輸出。
子類:AVCaptureDeviceInput、AVCaptureScreenInputAVCaptureMetadataInput

AVCaptureOutput (電力)

AVCaptureOut:數(shù)據(jù)輸出管理,通過 AVCaptureSession 中輸出??梢酝ㄟ^相關(guān)的協(xié)議實(shí)對應(yīng)的數(shù)據(jù)輸出。
子類:AVCaptureFileOutput、AVCapturePhotoOutput、AVCaptureStillImageOutputAVCaptureVideoDataOutput、AVCaptureAudioDataOutput、AVCaptureAudioPreviewOutputAVCaptureDepthDataOutputAVCaptureMetadataOutput。

AVCaptureVideoPreviewLayer (發(fā)電預(yù)覽)

AVCaptureVideoPreviewLayer:可以支持在拍攝過程中進(jìn)行相關(guān)的預(yù)覽,只需要在初始時實(shí)現(xiàn)對應(yīng)的 AVCaptureSession 即可。

視頻錄制

下面展示在蘋果官方開發(fā)文檔給出的圖:


iOS-Video Capture(iOS 視頻錄制).png

視頻錄制總概

  • 創(chuàng)建 AVCaptureSession 對象
  • 使用 AVCaptureDevice 靜態(tài)方法獲取設(shè)備常使用設(shè)備,例如:拍照和錄像需要的攝像頭,錄音所需的麥克風(fēng)
  • 利用輸入設(shè)備 AVCaptureDevice 初始化 AVCaptureDeviceInput 對象
  • 初始化輸出數(shù)據(jù)管理對象,拍照進(jìn)行初始化 AVCaptureStillImageOutput 對象,拍照初始化 AVCaptureMovieFileOutput 對象
  • 將數(shù)據(jù)輸入對象 AVCaptureDeviceInput 和數(shù)據(jù)輸出對象 AVCaptureDeviceOutput 添加到媒體會話管理對象 AVCaptureSession
  • 創(chuàng)建預(yù)覽的圖層 AVCaptureVideoPreviewLayer 指定媒體會話,添加圖層到容器,調(diào)用 AVCaptureSession 中的 StartRunning 方法開始捕捉
  • 將捕捉到內(nèi)容保存到指定文件中

詳解鏡頭采集類

AVCaptureSession

小編查看 AVCaptureSession.h文件看到,在鏡頭采集的過程中有兩種實(shí)現(xiàn)方式。

  • 使用系統(tǒng) AVCaptureSession自動配置輸入和輸出
  • 手動配置輸入和輸出之間的對應(yīng)關(guān)系

(1) AVCaptureSession 初始化

  • 使用AVCaptureSession 自動配置輸入和輸出之間對應(yīng)關(guān)系
    AVCaptureSession *session = [[AVCaptureSession alloc] init];
    AVCaptureDevice *audioCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
    NSError *error = nil;
    AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioCaptureDevice error:&error];
    [session beginConfiguration];

    session.sessionPreset = AVCaptureSessionPresetPhoto;
    if (audioInput) {
        
    }else {
        //// Handle the failure.
        [session commitConfiguration];
    }
    if ([session canAddInput:audioInput]) {
        [session addInput:audioInput];
    }else {
        // Handle the failure.
        [session commitConfiguration];
    }

上面代碼是 AVCaptureSession 進(jìn)行初始化并且實(shí)現(xiàn)初始化麥克風(fēng)進(jìn)行相關(guān)音頻錄制,并添加到 AVCaptureSession中。
beginConfiguration & commitConfiguration 在進(jìn)行配置 AVCaptureSession 的相關(guān)屬性值時需要對這兩個函數(shù)調(diào)用,并且這兩個函數(shù)是成對出現(xiàn)。

  • 手動配置 AVCaptureSession 輸入和輸出之間對應(yīng)關(guān)系
    AVCaptureSession *session = [[AVCaptureSession alloc] init];
    
    [session beginConfiguration];
    NSError *error = nil;
    AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
    if (!videoInput) {
        //handle configuration video device
    }
    AVCaptureInputPort *videoPort = videoInput.ports[0];
    
    error = nil;
    AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
    AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:&error];
    if (!videoInput) {
        //handle configuration audio device
    }
    AVCaptureInputPort *audioPort = audioInput.ports[0];
    
    NSArray<AVCaptureInputPort *> *inputPorts = @[videoPort, audioPort];
    AVCaptureVideoDataOutput *videoDataOutput = [[AVCaptureVideoDataOutput alloc] init];
    
    AVCaptureConnection *connection = [AVCaptureConnection connectionWithInputPorts:inputPorts output:videoDataOutput];
    if ([session canAddConnection:connection]) {
        [session addConnection:connection];
    }else {
        //handle session can not add AVCaptureConnection
        
        [session commitConfiguration];
        return;
    }
    [session commitConfiguration];

上面??代碼是使用 AVCaptureConnection實(shí)現(xiàn)在 AVCaptureSession 使輸入和輸出進(jìn)行自己配置。
詳細(xì)的細(xì)節(jié)會在 FYCameraKit 進(jìn)行詳細(xì)的講解。

注釋:
1)只有在調(diào)用 beginConfiguration 時我們對 AVCaptureSession 配置才會被真正開始修改。

(2) AVCaptureSession 中斷

在音視頻錄制過程中可能對因?yàn)殡娫拰?dǎo)致中斷,開發(fā)過程中提供中斷結(jié)束后獲取中斷產(chǎn)生的原因。

  • 注冊中斷監(jiān)聽 & 刪除監(jiān)聽
//監(jiān)聽注冊
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleCaptureSession:) name:AVCaptureSessionInterruptionEndedNotification object:_session];

//監(jiān)聽清除   
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureSessionInterruptionEndedNotification object:_session];
  • 從傳遞的 userInfo 通過關(guān)鍵 key 獲取原因:
AVCaptureSessionInterruptionReasonKey
  • 獲取具體的中斷原因:
typedef NS_ENUM(NSInteger, AVCaptureSessionInterruptionReason) {
    AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableInBackground               = 1,//從后臺運(yùn)行開啟 camera,不夠 iOS 9.0 之后不提供中斷 
    AVCaptureSessionInterruptionReasonAudioDeviceInUseByAnotherClient                   = 2,//音頻軟軟件被占用
    AVCaptureSessionInterruptionReasonVideoDeviceInUseByAnotherClient                   = 3,//視頻軟件被占用
    AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableWithMultipleForegroundApps = 4,//全屏或者是錄制屏幕變化
}
  • 監(jiān)聽事件的處理
- (void)handleCaptureSession:(NSNotification *)notification {
    AVCaptureSessionInterruptionReason reason = [[notification.userInfo objectForKey:AVCaptureSessionInterruptionReasonKey] unsignedIntegerValue];
    
    switch (reason) {
        case AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableInBackground:
        {
           //handle device not available background
            break;
        }
        case AVCaptureSessionInterruptionReasonAudioDeviceInUseByAnotherClient:
        {
           //handle that audio was occupied  
           break;
        }
        case AVCaptureSessionInterruptionReasonVideoDeviceInUseByAnotherClient:
        {  
           //handle that video was occupied  
            break;
        }
        case AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableWithMultipleForegroundApps:
        {
           //handle that UI was multiple
            break;
        }
    }
}

實(shí)現(xiàn)拍照和視頻錄制的 FYCameraKit 的下載地址: FYCameraKit

最后給出 AVFoundation API 的總結(jié):

AVFoundation-Struct.png

參考資料:
AVCaptureSession
AVCaptureDevice
AVCaptureConnection

第一次發(fā)布:2017/8/10 20:49:21 星期四
第二次發(fā)布:2017/8/10 23:36:34 星期四

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容