鍍金池/ 教程/ iOS/ 在 iOS 上捕獲視頻
與四軸無人機的通訊
在沙盒中編寫腳本
結(jié)構(gòu)體和值類型
深入理解 CocoaPods
UICollectionView + UIKit 力學
NSString 與 Unicode
代碼簽名探析
測試
架構(gòu)
第二期-并發(fā)編程
Metal
自定義控件
iOS 中的行為
行為驅(qū)動開發(fā)
Collection View 動畫
截圖測試
MVVM 介紹
使 Mac 應(yīng)用數(shù)據(jù)腳本化
一個完整的 Core Data 應(yīng)用
插件
字符串
為 iOS 建立 Travis CI
先進的自動布局工具箱
動畫
為 iOS 7 重新設(shè)計 App
XPC
從 NSURLConnection 到 NSURLSession
Core Data 網(wǎng)絡(luò)應(yīng)用實例
GPU 加速下的圖像處理
自定義 Core Data 遷移
子類
與調(diào)試器共舞 - LLDB 的華爾茲
圖片格式
并發(fā)編程:API 及挑戰(zhàn)
IP,TCP 和 HTTP
動畫解釋
響應(yīng)式 Android 應(yīng)用
初識 TextKit
客戶端
View-Layer 協(xié)作
回到 Mac
Android
Core Image 介紹
自定義 Formatters
Scene Kit
調(diào)試
項目介紹
Swift 的強大之處
測試并發(fā)程序
Android 通知中心
調(diào)試:案例學習
從 UIKit 到 AppKit
iOS 7 : 隱藏技巧和變通之道
安全
底層并發(fā) API
消息傳遞機制
更輕量的 View Controllers
用 SQLite 和 FMDB 替代 Core Data
字符串解析
終身學習的一代人
視頻
Playground 快速原型制作
Omni 內(nèi)部
同步數(shù)據(jù)
設(shè)計優(yōu)雅的移動游戲
繪制像素到屏幕上
相機與照片
音頻 API 一覽
交互式動畫
常見的后臺實踐
糟糕的測試
避免濫用單例
數(shù)據(jù)模型和模型對象
Core Data
字符串本地化
View Controller 轉(zhuǎn)場
照片框架
響應(yīng)式視圖
Square Register 中的擴張
DTrace
基礎(chǔ)集合類
視頻工具箱和硬件加速
字符串渲染
讓東西變得不那么糟
游戲中的多點互聯(lián)
iCloud 和 Core Data
Views
虛擬音域 - 聲音設(shè)計的藝術(shù)
導(dǎo)航應(yīng)用
線程安全類的設(shè)計
置換測試: Mock, Stub 和其他
Build 工具
KVC 和 KVO
Core Image 和視頻
Android Intents
在 iOS 上捕獲視頻
四軸無人機項目
Mach-O 可執(zhí)行文件
UI 測試
值對象
活動追蹤
依賴注入
Swift
項目管理
整潔的 Table View 代碼
Swift 方法的多面性
為什么今天安全仍然重要
Core Data 概述
Foundation
Swift 的函數(shù)式 API
iOS 7 的多任務(wù)
自定義 Collection View 布局
測試 View Controllers
訪談
收據(jù)驗證
數(shù)據(jù)同步
自定義 ViewController 容器轉(zhuǎn)場
游戲
調(diào)試核對清單
View Controller 容器
學無止境
XCTest 測試實戰(zhàn)
iOS 7
Layer 中自定義屬性的動畫
第一期-更輕量的 View Controllers
精通 iCloud 文檔存儲
代碼審查的藝術(shù):Dropbox 的故事
GPU 加速下的圖像視覺
Artsy
照片擴展
理解 Scroll Views
使用 VIPER 構(gòu)建 iOS 應(yīng)用
Android 中的 SQLite 數(shù)據(jù)庫支持
Fetch 請求
導(dǎo)入大數(shù)據(jù)集
iOS 開發(fā)者的 Android 第一課
iOS 上的相機捕捉
語言標簽
同步案例學習
依賴注入和注解,為什么 Java 比你想象的要好
編譯器
基于 OpenCV 的人臉識別
玩轉(zhuǎn)字符串
相機工作原理
Build 過程

在 iOS 上捕獲視頻

隨著每一代 iPhone 處理能力和相機硬件配置的提高,使用它來捕獲視頻也變得更加有意思。它們小巧,輕便,低調(diào),而且與專業(yè)攝像機之間的差距已經(jīng)變得非常小,小到在某些情況下,iPhone 可以真正替代它們。

這篇文章討論了關(guān)于如何配置視頻捕獲管線 (pipeline) 和最大限度地利用硬件性能的一些不同選擇。 這里有個使用了不同管線的樣例 app,可以在 GitHub 查看。

UIImagePickerController

目前,將視頻捕獲集成到你的應(yīng)用中的最簡單的方法是使用 UIImagePickerController。這是一個封裝了完整視頻捕獲管線和相機 UI 的 view controller。

在實例化相機之前,首先要檢查設(shè)備是否支持相機錄制:

if ([UIImagePickerController
       isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
    NSArray *availableMediaTypes = [UIImagePickerController
      availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
    if ([availableMediaTypes containsObject:(NSString *)kUTTypeMovie]) {
        // 支持視頻錄制
    }
}

然后創(chuàng)建一個 UIImagePickerController 對象,設(shè)置好代理便于進一步處理錄制好的視頻 (比如存到相冊) 以及對于用戶關(guān)閉相機作出響應(yīng):

UIImagePickerController *camera = [UIImagePickerController new];
camera.sourceType = UIImagePickerControllerSourceTypeCamera;
camera.mediaTypes = @[(NSString *)kUTTypeMovie];
camera.delegate = self;

這是你實現(xiàn)一個功能完善的攝像機所需要寫的所有代碼。

相機配置

UIImagePickerController 提供了額外的配置選項。

通過設(shè)置 cameraDevice 屬性可以選擇一個特定的相機。這是一個 UIImagePickerControllerCameraDevice 枚舉,默認情況下是 UIImagePickerControllerCameraDeviceRear,你也可以把它設(shè)置為 UIImagePickerControllerCameraDeviceFront。每次都應(yīng)事先確認你想要設(shè)置的相機是可用的:

UIImagePickerController *camera = …
if ([UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceFront]) {
    [camera setCameraDevice:UIImagePickerControllerCameraDeviceFront];
}

videoQuality 屬性用于控制錄制視頻的質(zhì)量。它允許你設(shè)置一個特定的編碼預(yù)設(shè),從而改變視頻的比特率和分辨率。以下是六種預(yù)設(shè):

enum {
   UIImagePickerControllerQualityTypeHigh             = 0,
   UIImagePickerControllerQualityTypeMedium           = 1,  // default  value
   UIImagePickerControllerQualityTypeLow              = 2,
   UIImagePickerControllerQualityType640x480          = 3,
   UIImagePickerControllerQualityTypeIFrame1280x720   = 4,
   UIImagePickerControllerQualityTypeIFrame960x540    = 5
};
typedef NSUInteger  UIImagePickerControllerQualityType;

前三種為相對預(yù)設(shè) (low, medium, high)。這些預(yù)設(shè)的編碼配置會因設(shè)備不同而不同。如果選擇 high,那么你選定的相機會提供給你該設(shè)備所能支持的最高畫質(zhì)。后面三種是特定分辨率的預(yù)設(shè) (640x480 VGA, 960x540 iFrame, 和 1280x720 iFrame)。

自定義 UI

就像上面提到的,UIImagePickerController 自帶一套相機 UI,可以直接使用。然而,你也可以自定義相機的控件,通過隱藏默認控件,然后創(chuàng)建帶有控件的自定義視圖,并覆蓋在相機預(yù)覽圖層上面:

UIView *cameraOverlay = …
picker.showsCameraControls = NO;
picker.cameraOverlayView = cameraOverlay;

然后你需要將你覆蓋層上的控件關(guān)聯(lián)上 UIImagePickerController 的控制方法 (比如,startVideoCapturestopVideoCapture)。

AVFoundation

如果你想要更多關(guān)于處理捕獲視頻的方法,而這些方法是 UIImagePickerController 所不能提供的,那么你需要使用 AVFoundation。

AVFoundation 中關(guān)于視頻捕獲的主要的類是 AVCaptureSession。它負責調(diào)配影音輸入與輸出之間的數(shù)據(jù)流:

http://wiki.jikexueyuan.com/project/objc/images/23-1.svg" alt="" />

使用一個 capture session,你需要先實例化,添加輸入與輸出,接著啟動從輸入到輸出之間的數(shù)據(jù)流:

AVCaptureSession *captureSession = [AVCaptureSession new];
AVCaptureDeviceInput *cameraDeviceInput = …
AVCaptureDeviceInput *micDeviceInput = …
AVCaptureMovieFileOutput *movieFileOutput = …
if ([captureSession canAddInput:cameraDeviceInput]) {
    [captureSession addInput:cameraDeviceInput];
}
if ([captureSession canAddInput:micDeviceInput]) {
    [captureSession addInput:micDeviceInput];
}
if ([captureSession canAddOutput:movieFileOutput]) {
    [captureSession addOutput:movieFileOutput];
}

[captureSession startRunning];

(為了簡單起見,調(diào)度隊列 (dispatch queue) 的相關(guān)代碼已經(jīng)從上面那段代碼中省略了。所有對 capture session 的調(diào)用都是阻塞的,因此建議將它們分配到后臺串行隊列中。)

capture session 可以通過一個 sessionPreset 來進一步配置,這可以用來指定輸出質(zhì)量的等級。有 11 種不同的預(yù)設(shè)模式:

NSString *const  AVCaptureSessionPresetPhoto;
NSString *const  AVCaptureSessionPresetHigh;
NSString *const  AVCaptureSessionPresetMedium;
NSString *const  AVCaptureSessionPresetLow;
NSString *const  AVCaptureSessionPreset352x288;
NSString *const  AVCaptureSessionPreset640x480;
NSString *const  AVCaptureSessionPreset1280x720;
NSString *const  AVCaptureSessionPreset1920x1080;
NSString *const  AVCaptureSessionPresetiFrame960x540;
NSString *const  AVCaptureSessionPresetiFrame1280x720;
NSString *const  AVCaptureSessionPresetInputPriority;

第一個代表高像素圖片輸出。 接下來的九個和之前我們在設(shè)置 UIImagePickerControllervideoQuality 時看到過的 UIImagePickerControllerQualityType 選項非常相似,不同的是,這里有一些額外可用于 capture session 的預(yù)設(shè)。 最后一個 (AVCaptureSessionPresetInputPriority) 代表 capture session 不去控制音頻與視頻輸出設(shè)置。而是通過已連接的捕獲設(shè)備的 activeFormat 來反過來控制 capture session 的輸出質(zhì)量等級。在下一節(jié),我們將會看到更多關(guān)于設(shè)備和設(shè)備格式的細節(jié)。

輸入

AVCaptureSession 的輸入其實就是一個或多個的 AVCaptureDevice 對象,這些對象通過 AVCaptureDeviceInput 連接上 capture session。

我們可以使用 [AVCaptureDevice devices] 來尋找可用的捕獲設(shè)備。以 iPhone 6 為例:

(
    “<AVCaptureFigVideoDevice: 0x136514db0 [Back Camera][com.apple.avfoundation.avcapturedevice.built-in_video:0]>”,
    “<AVCaptureFigVideoDevice: 0x13660be80 [Front Camera][com.apple.avfoundation.avcapturedevice.built-in_video:1]>”,
    “<AVCaptureFigAudioDevice: 0x174265e80 [iPhone Microphone][com.apple.avfoundation.avcapturedevice.built-in_audio:0]>”
)

視頻輸入

配置相機輸入,需要實例化一個 AVCaptureDeviceInput 對象,參數(shù)是你期望的相機設(shè)備,然后把它添加到 capture session:

AVCaptureSession *captureSession = …
AVCaptureDevice *cameraDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error;
AVCaptureDeviceInput *cameraDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice: error:&error];
if ([captureSession canAddInput:input]) {
    [captureSession addInput:cameraDeviceInput];
}

如果上面提到的 capture session 預(yù)設(shè)列表里能滿足你的需求,那你就不需要做更多的事情了。如果不夠,比如你想要高的幀率,你將需要配置具體的設(shè)備格式。一個視頻捕獲設(shè)備有許多設(shè)備格式,每個都帶有特定的屬性和功能。下面是對于 iPhone6 的后置攝像頭的一些例子 (一共有 22 種可用格式):

格式 分辨率 FPS HRSI FOV VIS 最大放大比例 Upscales AF ISO SS HDR
420v 1280x720 5 - 240 1280x720 54.626 YES 49.12 1.09 1 29.0 - 928 0.000003-0.200000 NO
420f 1280x720 5 - 240 1280x720 54.626 YES 49.12 1.09 1 29.0 - 928 0.000003-0.200000 NO
420v 1920x1080 2 - 30 3264x1836 58.040 YES 95.62 1.55 2 29.0 - 464 0.000013-0.500000 YES
420f 1920x1080 2 - 30 3264x1836 58.040 YES 95.62 1.55 2 29.0 - 464 0.000013-0.500000 YES
420v 1920x1080 2 - 60 3264x1836 58.040 YES 95.62 1.55 2 29.0 - 464 0.000008-0.500000 YES
420f 1920x1080 2 - 60 3264x1836 58.040 YES 95.62 1.55 2 29.0 - 464 0.000008-0.500000 YES
  • 格式 = 像素格式
  • FPS = 支持幀數(shù)范圍
  • HRSI = 高像素靜態(tài)圖片尺寸
  • FOV = 視角
  • VIS = 該格式支持視頻防抖
  • Upscales = 加入數(shù)字 upscaling 時的放大比例
  • AF = 自動對焦系統(tǒng)(1 是反差對焦,2 是相位對焦)
  • ISO = 支持感光度范圍
  • SS = 支持曝光時間范圍
  • HDR = 支持高動態(tài)范圍圖像

通過上面的那些格式,你會發(fā)現(xiàn)如果要錄制 240 幀每秒的視頻的話,可以根據(jù)想要的像素格式選用第一個或第二個格式。另外若是要捕獲 1920x1080 的分辨率的視頻的話,是不支持 240 幀每秒的。

配置一個具體設(shè)備格式,你首先需要調(diào)用 lockForConfiguration: 來獲取設(shè)備的配置屬性的獨占訪問權(quán)限。接著你簡單地使用 setActiveFormat: 來設(shè)置設(shè)備的捕獲格式。這將會自動把 capture session 的預(yù)設(shè)設(shè)置為 AVCaptureSessionPresetInputPriority。

一旦你設(shè)置了預(yù)想的設(shè)備格式,你就可以在這種設(shè)備格式的約束參數(shù)范圍內(nèi)進行進一步的配置了。

對于視頻捕獲的對焦,曝光和白平衡的設(shè)置,與圖像捕獲時一樣,具體可參考第 21 期“iOS 上的相機捕捉”。除了那些,這里還有一些視頻特有的配置選項。

你可以用捕獲設(shè)備的 activeVideoMinFrameDurationactiveVideoMaxFrameDuration 屬性設(shè)置幀速率,一幀的時長是幀速率的倒數(shù)。設(shè)置幀速率之前,要先確認它是否在設(shè)備格式所支持的范圍內(nèi),然后鎖住捕獲設(shè)備來進行配置。為了確保幀速率恒定,可以將最小與最大的幀時長設(shè)置成一樣的值:

NSError *error;
CMTime frameDuration = CMTimeMake(1, 60);
NSArray *supportedFrameRateRanges = [device.activeFormat videoSupportedFrameRateRanges];
BOOL frameRateSupported = NO;
for (AVFrameRateRange *range in supportedFrameRateRanges) {
    if (CMTIME_COMPARE_INLINE(frameDuration, >=, range.minFrameDuration) &&
        CMTIME_COMPARE_INLINE(frameDuration, <=, range.maxFrameDuration)) {
        frameRateSupported = YES;
    }
}

if (frameRateSupported && [device lockForConfiguration:&error]) {
    [device setActiveVideoMaxFrameDuration:frameDuration];
    [device setActiveVideoMinFrameDuration:frameDuration];
    [device unlockForConfiguration];
}

視頻防抖 是在 iOS 6 和 iPhone 4S 發(fā)布時引入的功能。到了 iPhone 6,增加了更強勁和流暢的防抖模式,被稱為影院級的視頻防抖動。相關(guān)的 API 也有所改動 (目前為止并沒有在文檔中反映出來,不過可以查看頭文件)。防抖并不是在捕獲設(shè)備上配置的,而是在 AVCaptureConnection 上設(shè)置。由于不是所有的設(shè)備格式都支持全部的防抖模式,所以在實際應(yīng)用中應(yīng)事先確認具體的防抖模式是否支持:

AVCaptureDevice *device = ...;
AVCaptureConnection *connection = ...;

AVCaptureVideoStabilizationMode stabilizationMode = AVCaptureVideoStabilizationModeCinematic;
if ([device.activeFormat isVideoStabilizationModeSupported:stabilizationMode]) {
    [connection setPreferredVideoStabilizationMode:stabilizationMode];
}

iPhone 6 的另一個新特性就是視頻 HDR (高動態(tài)范圍圖像),它是“高動態(tài)范圍的視頻流,與傳統(tǒng)的將不同曝光度的靜態(tài)圖像合成成一張高動態(tài)范圍圖像的方法完全不同”,它是內(nèi)建在傳感器中的。有兩種方法可以配置視頻 HDR:直接將 capture device 的 videoHDREnabled 設(shè)置為啟用或禁用,或者使用 automaticallyAdjustsVideoHDREnabled 屬性來留給系統(tǒng)處理。

技術(shù)參考:iPhone 6 和 iPhone Plus 的新 AV Foundation 相機特性

音頻輸入

之前展示的捕獲設(shè)備列表里面只有一個音頻設(shè)備,你可能覺得奇怪,畢竟 iPhone 6 有 3 個麥克風。然而因為有時會放在一起使用,便于優(yōu)化性能,因此可能被當做一個設(shè)備來使用。例如在 iPhone 5 及以上的手機錄制視頻時,會同時使用前置和后置麥克風,用于定向降噪。

Technical Q&A: AVAudioSession - Microphone Selection

大多數(shù)情況下,設(shè)置成默認的麥克風配置即可。后置麥克風會自動搭配后置攝像頭使用 (前置麥克風則用于降噪),前置麥克風和前置攝像頭也是一樣。

然而想要訪問和配置單獨的麥克風也是可行的。例如,當用戶正在使用后置攝像頭捕獲場景的時候,使用前置麥克風來錄制解說也應(yīng)是可能的。這就要依賴于 AVAudioSession。 為了變更要訪問的音頻,audio session 首先需要設(shè)置為支持這樣做的類別。然后我們需要遍歷 audio session 的輸入端口和端口數(shù)據(jù)來源,來找到我們想要的麥克風:

// 配置 audio session
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[audioSession setActive:YES error:nil];

// 尋找期望的輸入端口
NSArray* inputs = [audioSession availableInputs];
AVAudioSessionPortDescription *builtInMic = nil;
for (AVAudioSessionPortDescription* port in inputs) {
    if ([port.portType isEqualToString:AVAudioSessionPortBuiltInMic]) {
        builtInMic = port;
        break;
    }
}

// 尋找期望的麥克風
for (AVAudioSessionDataSourceDescription* source in builtInMic.dataSources) {
    if ([source.orientation isEqual:AVAudioSessionOrientationFront]) {
        [builtInMic setPreferredDataSource:source error:nil];
        [audioSession setPreferredInput:builtInMic error:&error];
        break;
    }
}

除了設(shè)置非默認的麥克風配置,你也可以使用 AVAudioSession 來配置其他音頻設(shè)置,比如音頻增益和采樣率等。

訪問權(quán)限

有件事你需要記住,訪問相機和麥克風需要先獲得用戶授權(quán)。當你給視頻或音頻創(chuàng)建第一個 AVCaptureDeviceInput 對象時,iOS 會自動彈出一次對話框,請求用戶授權(quán),但你最好還是自己實現(xiàn)下。之后你就可以在還沒有被授權(quán)的時候,使用相同的代碼來提示用戶進行授權(quán)。當用戶未授權(quán)時,對于錄制視頻或音頻的嘗試,得到的將是黑色畫面和無聲。

輸出

輸入配置完了,現(xiàn)在把我們的注意力轉(zhuǎn)向 capture session 的輸出。

AVCaptureMovieFileOutput

將視頻寫入文件,最簡單的選擇就是使用 AVCaptureMovieFileOutput 對象。把它作為輸出添加到 capture session 中,就可以將視頻和音頻寫入 QuickTime 文件,這只需很少的配置。

AVCaptureMovieFileOutput *movieFileOutput = [AVCaptureMovieFileOutput new];
if([captureSession canAddOutput:movieFileOutput]){
    [captureSession addOutput:movieFileOutput];
}

// 開始錄制
NSURL *outputURL = …
[movieFileOutput startRecordingToOutputFileURL:outputURL recordingDelegate:self];

當實際的錄制開始或停止時,想要接收回調(diào)的話就必須要一個錄制代理。當錄制停止時,輸出通常還在寫入數(shù)據(jù),等它完成之后會調(diào)用代理方法。

AVCaptureMovieFileOutput 有一些其他的配置選項,比如在某段時間后,在達到某個指定的文件尺寸時,或者當設(shè)備的最小磁盤剩余空間達到某個閾值時停止錄制。如果你還需要更多設(shè)置,比如自定義視頻音頻的壓縮率,或者你想要在寫入文件之前,處理視頻音頻的樣本,那么你需要一些更復(fù)雜的操作。

AVCaptureDataOutputAVAssetWriter

如果你想要對影音輸出有更多的操作,你可以使用 AVCaptureVideoDataOutputAVCaptureAudioDataOutput 而不是我們上節(jié)討論的 AVCaptureMovieFileOutput。

這些輸出將會各自捕獲視頻和音頻的樣本緩存,接著發(fā)送到它們的代理。代理要么對采樣緩沖進行處理 (比如給視頻加濾鏡),要么保持原樣傳送。使用 AVAssetWriter 對象可以將樣本緩存寫入文件:

http://wiki.jikexueyuan.com/project/objc/images/23-2.svg" alt="" />

配置一個 asset writer 需要定義一個輸出 URL 和文件格式,并添加一個或多個輸入來接收采樣的緩沖。我們還需要將輸入的 expectsMediaInRealTime 屬性設(shè)置為 YES,因為它們需要從 capture session 實時獲得數(shù)據(jù)。

NSURL *url = …;
AVAssetWriter *assetWriter = [AVAssetWriter assetWriterWithURL:url fileType:AVFileTypeMPEG4 error:nil];
AVAssetWriterInput *videoInput = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo outputSettings:nil];
videoInput.expectsMediaDataInRealTime = YES;
AVAssetWriterInput *audioInput = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeAudio outputSettings:nil];
audioInput.expectsMediaDataInRealTime = YES;
if ([assetWriter canAddInput:videoInput]) {
    [assetWriter addInput:videoInput];
}
if ([assetWriter canAddInput:audioInput]) {
    [assetWriter addInput:audioInput];
}

(這里推薦將 asset writer 派送到后臺串行隊列中調(diào)用。)

在上面的示例代碼中,我們將 asset writer 的 outputSettings 設(shè)置為 nil。這就意味著附加上來的樣本不會再被重新編碼。如果你確實想要重新編碼這些樣本,那么需要提供一個包含具體輸出參數(shù)的字典。關(guān)于音頻輸出設(shè)置的鍵值被定義在這里, 關(guān)于視頻輸出設(shè)置的鍵值定義在這里。

為了更簡單點,AVCaptureVideoDataOutputAVCaptureAudioDataOutput 分別帶有 recommendedVideoSettingsForAssetWriterWithOutputFileType:recommendedAudioSettingsForAssetWriterWithOutputFileType: 方法,可以生成與 asset writer 兼容的帶有全部鍵值對的字典。所以你可以通過在這個字典里調(diào)整你想要重寫的屬性,來簡單地定義你自己的輸出設(shè)置。比如,增加視頻比特率來提高視頻質(zhì)量等。

或者,你也可以使用 AVOutputSettingsAssistant 來配置輸出設(shè)置的字典,但是從我的經(jīng)驗來看,使用上面的方法會更好,它們會提供更實用的輸出設(shè)置,比如視頻比特率。另外,AVOutputSettingsAssistant 似乎存在一些缺點,例如,當你改變希望的視頻的幀速率時,視頻的比特率并不會改變。

實時預(yù)覽

當使用 AVFoundation 來做圖像捕獲時,我們必須提供一套自定義的用戶界面。其中一個關(guān)鍵的相機交互組件是實時預(yù)覽圖。最簡單的實現(xiàn)方式是通過把 AVCaptureVideoPreviewLayer 對象作為一個 sublayer 加到相機圖層上去:

AVCaptureSession *captureSession = ...;
AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:captureSession];
UIView *cameraView = ...;
previewLayer.frame = cameraView.bounds;
[cameraView.layer addSublayer:previewLayer];

如果你想要更進一步操作,比如,在實時預(yù)覽圖加濾鏡,你需要將 AVCaptureVideoDataOutput 對象加到 capture session,并且使用 OpenGL 展示畫面,具體可查看該文“iOS 上的相機捕捉”

總結(jié)

有許多不同的方法可以給 iOS 上的視頻捕獲配置管線,從最直接的 UIImagePickerController,到精密配合的 AVCaptureSessionAVAssetWriter 。如何抉擇取決于你的項目要求,比如期望的視頻質(zhì)量和壓縮率,或者是你想要展示給用戶的相機控件。