原文:AVFoundation Programming Guide
寫(xiě)在前面
簡(jiǎn)單翻譯一下
AVFoundation的相關(guān)文檔,本人英語(yǔ)水平一般,有不對(duì)的歡迎大家留言指正。
要管理從相機(jī)或麥克風(fēng)等設(shè)備的捕獲,您需要使用對(duì)象以表示輸入和輸出,并使用AVCaptureSession的實(shí)例來(lái)協(xié)調(diào)它們之間的數(shù)據(jù)流。你最少需要:
- 一個(gè)AVCaptureDevice對(duì)象來(lái)表示輸入設(shè)備,如相機(jī)或麥克風(fēng)
- 一個(gè)AVCaptureInput的具體子類的實(shí)例,用于配置輸入設(shè)備端口
- 一個(gè)AVCaptureOutput的具體子類的實(shí)例來(lái)管理是輸出到一個(gè)視頻文件還是靜態(tài)圖片
- 一個(gè)AVCaptureSession實(shí)例來(lái)協(xié)調(diào)從輸入設(shè)備到輸出設(shè)備的數(shù)據(jù)流
為了給用戶展示相機(jī)正在錄制的內(nèi)容,你可以使用一個(gè)AVCaptureVideoPreviewLayer實(shí)例。
你可以配置多個(gè)輸入和輸出設(shè)備,并使用一個(gè)會(huì)話(session)來(lái)協(xié)調(diào),如圖4-1。

對(duì)于許多應(yīng)用,這就是你所需要的。然而,對(duì)于某些操作(例如,你想要監(jiān)視音頻通道中的功率電平)則需要考慮如何表示輸入設(shè)備的各種端口以及這些端口如何連接到輸出。
捕獲會(huì)話中的輸入和輸出之間的連接由AVCaptureConnection對(duì)象表示。捕獲輸入(AVCaptureInput的實(shí)例)具有一個(gè)或多個(gè)輸入端口(AVCaptureInputPort的實(shí)例)。捕獲輸出(AVCaptureOutput的實(shí)例)可以接受來(lái)自一個(gè)或多個(gè)源的數(shù)據(jù)(例如,AVCaptureMovieFileOutput對(duì)象接受視頻和音頻數(shù)據(jù))。
當(dāng)您向會(huì)話添加輸入或輸出時(shí),會(huì)話將形成所有兼容捕獲輸入端口和捕獲輸出之間的連接,如圖4-2所示。捕獲輸入和捕捉輸出之間的連接由AVCaptureConnection對(duì)象表示。

你可以使用一個(gè)捕獲連接來(lái)啟用或禁用一個(gè)給定的輸入或輸出的數(shù)據(jù)流。您還可以使用連接來(lái)監(jiān)視音頻通道中的平均和峰值功率。
注意: 媒體捕獲不支持在iOS設(shè)備上同時(shí)捕獲前置和后置攝像頭。
使用一個(gè)捕獲會(huì)話來(lái)協(xié)調(diào)數(shù)據(jù)流
一個(gè)AVCaptureSession對(duì)象是用于管理數(shù)據(jù)捕獲的中心協(xié)調(diào)對(duì)象。您使用它來(lái)協(xié)調(diào)從AV輸入設(shè)備到輸出的數(shù)據(jù)流。您將捕獲設(shè)備和輸出添加到會(huì)話,然后通過(guò)發(fā)送會(huì)話startRunning 消息來(lái)啟動(dòng)數(shù)據(jù)流,并通過(guò)發(fā)送stopRunning消息來(lái)停止數(shù)據(jù)流。
AVCaptureSession *session = [[AVCaptureSession alloc] init];
// Add inputs and outputs.
[session startRunning];
配置會(huì)話
您可以在會(huì)話中使用預(yù)設(shè)來(lái)指定所需的圖像質(zhì)量和分辨率。預(yù)設(shè)是一些配置常數(shù);在某些情況下,實(shí)際配置是由設(shè)備決定的:
| 標(biāo)識(shí) | 分辨率 | 注釋 |
|---|---|---|
| AVCaptureSessionPresetHigh | High | 最高的錄制質(zhì)量,每個(gè)設(shè)備有所不同 |
| AVCaptureSessionPresetMedium | Medium | 適用于wifi分享,實(shí)際值可能會(huì)變 |
| AVCaptureSessionPresetLow | Low | 適用于3G分享,實(shí)際值可能會(huì)變 |
| AVCaptureSessionPreset640x480 | 640x480 | VGA. |
| AVCaptureSessionPreset1280x720 | 1280x720 | 720p HD. |
| AVCaptureSessionPresetPhoto | Photo | 完整的照片分辨率,不支持視頻輸出。 |
如果你想要給媒體幀設(shè)置一個(gè)特定大小的配置,你應(yīng)該在設(shè)置前檢查它是否支持,如下:
if ([session canSetSessionPreset:AVCaptureSessionPreset1280x720]) {
session.sessionPreset = AVCaptureSessionPreset1280x720;
} else {
// Handle the failure.
}
如果您需要給會(huì)話設(shè)置一個(gè)比預(yù)設(shè)可能更精細(xì)的參數(shù),或者您想對(duì)正在運(yùn)行的會(huì)話進(jìn)行更改,則可以使用beginConfiguration和commitConfiguration方法來(lái)包圍您的更改。 beginConfiguration和commitConfiguration方法確保設(shè)備更改在一個(gè)組內(nèi)發(fā)生。調(diào)用beginConfiguration之后,您可以添加或刪除輸出,更改會(huì)話的預(yù)設(shè)屬性,或配置各個(gè)捕獲輸入或輸出屬性。在調(diào)用commitConfiguration之前,實(shí)際上沒(méi)有進(jìn)行任何更改,這些配置會(huì)在一起被應(yīng)用。
[session beginConfiguration];
// Remove an existing capture device.
// Add a new capture device.
// Reset the preset.
[session commitConfiguration];
監(jiān)視捕獲會(huì)話狀態(tài)
捕獲會(huì)話會(huì)發(fā)出通知,你可以監(jiān)聽(tīng)它們,例如,當(dāng)它啟動(dòng)或停止運(yùn)行或中斷時(shí)。您可以注冊(cè)接收 AVCaptureSessionRuntimeErrorNotification來(lái)處理錯(cuò)誤。您還可以查詢會(huì)話的running屬性,以確定其是否正在運(yùn)行,以及interrupted屬性以確定是否中斷。此外,running和interrupted的屬性都符合KVC,并且通知會(huì)發(fā)布在主線程上。
An AVCaptureDevice對(duì)象表示輸入設(shè)備
一個(gè)AVCaptureDevice對(duì)象是一個(gè)向AVCaptureSession對(duì)象提供輸入數(shù)據(jù)(如音頻或視頻)的物理捕獲設(shè)備的抽象。每個(gè)輸入設(shè)備有一個(gè)對(duì)象,例如兩個(gè)視頻輸入: 一個(gè)用于前置攝像頭,一個(gè)用于后置攝像頭,和一個(gè)用于麥克風(fēng)的音頻輸入。您可以使用AVCaptureDevice的類方法devices和devicesWithMediaType:找出當(dāng)前可用的捕獲設(shè)備。并且,如有必要,您可以找到iPhone,iPad或iPod提供的功能(請(qǐng)參閱Device Capture Settings)??捎迷O(shè)備的列表可能會(huì)改變。當(dāng)前的輸入設(shè)備可能變得不可用(如果它們被另一個(gè)應(yīng)用程序使用),并且新的輸入設(shè)備可能變得可用(如果它們被另一個(gè)應(yīng)用程序放棄)。您應(yīng)該注冊(cè)接收AVCaptureDeviceWasConnectedNotification 和AVCaptureDeviceWasDisconnectedNotification 通知,以便在可用設(shè)備列表更改時(shí)提醒。您可以使用捕獲輸入將輸入設(shè)備添加到捕獲會(huì)話(請(qǐng)參閱Use Capture Inputs to Add a Capture Device to a Session)。
設(shè)備特性
您可以查詢?cè)O(shè)備的不同的特征。您還可以測(cè)試它是否提供特定的媒體類型或支持給定捕獲會(huì)話的預(yù)設(shè),分別使用方法hasMediaType:和supportsAVCaptureSessionPreset:。要向用戶提供信息,您可以找出捕獲設(shè)備的位置(無(wú)論是在正在測(cè)試的設(shè)備的正面或背面)及其本地化名稱。如果要提供捕獲設(shè)備列表以允許用戶選擇一個(gè)捕獲設(shè)備,這可能很有用。
圖4-3顯示了后置(AVCaptureDevicePositionBack) 和前置(AVCaptureDevicePositionFront)攝像機(jī)的位置。
注意:媒體捕獲不支持同時(shí)捕獲iOS設(shè)備上的前置和后置攝像頭。

下面的代碼展示了獲取所有的可用設(shè)備并且輸出它們的名字,如果是視頻設(shè)備,輸出它們的位置
NSArray *devices = [AVCaptureDevice devices];
for (AVCaptureDevice *device in devices) {
NSLog(@"Device name: %@", [device localizedName]);
if ([device hasMediaType:AVMediaTypeVideo]) {
if ([device position] == AVCaptureDevicePositionBack) {
NSLog(@"Device position : back");
} else {
NSLog(@"Device position : front");
}
}
}
你還可以獲取設(shè)備的model ID和unique ID。
設(shè)備捕獲設(shè)置
不同的設(shè)備具有不同的功能;例如,一些可能支持不同的焦點(diǎn)或閃光模式;有一些可能會(huì)支持在一個(gè)興趣點(diǎn)上聚焦。
以下代碼片段顯示了如何查找具有手電筒模式并支持給定捕獲會(huì)話預(yù)置的視頻輸入設(shè)備:
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
NSMutableArray *torchDevices = [[NSMutableArray alloc] init];
for (AVCaptureDevice *device in devices) {
if ([device hasTorch] && [device supportsAVCaptureSessionPreset:AVCaptureSessionPreset640x480]) {
[torchDevices addObject:device];
}
}
如果您發(fā)現(xiàn)多個(gè)符合條件的設(shè)備,您可以讓用戶選擇要使用的設(shè)備。要向用戶顯示設(shè)備的描述,可以使用其localizedName屬性。
您以類似的方式使用各種不同的功能。有一些常數(shù)來(lái)指定特定模式,您可以詢問(wèn)設(shè)備是否支持特定模式。在某些情況下,您可以監(jiān)聽(tīng)屬性以便在功能正在更改時(shí)獲得通知。在所有情況下,您應(yīng)該在更改特定功能的模式之前鎖定設(shè)備,如Configuring a Device中所述。
注意:興趣點(diǎn)聚焦和興趣點(diǎn)曝光是相互排斥的,聚焦模式和曝光模式也是相互排斥的。
聚焦模式
有三種聚焦模式:
- AVCaptureFocusModeLocked: 焦點(diǎn)位置是固定的。當(dāng)您想允許用戶組合場(chǎng)景然后鎖定焦點(diǎn)時(shí),這很有用。
- AVCaptureFocusModeAutoFocus: 相機(jī)執(zhí)行一個(gè)掃描焦點(diǎn),然后還原到鎖定。這適合于您想要選擇要聚焦的特定項(xiàng)目,然后將焦點(diǎn)保持在該項(xiàng)目上的情況,即使它不是場(chǎng)景的中心。
- AVCaptureFocusModeContinuousAutoFocus: 相機(jī)會(huì)根據(jù)需要不斷自動(dòng)對(duì)焦。
您使用isFocusModeSupported:方法來(lái)確定設(shè)備是否支持給定的對(duì)焦模式,然后使用focusMode屬性設(shè)置模式。
另外,設(shè)備可能支持興趣焦點(diǎn)。 您可以使用focusPointOfInterest來(lái)測(cè)試。 如果支持,您可以使用focusPointOfInterest設(shè)置焦點(diǎn)。 您傳遞一個(gè)CGPoint,其中{0,0}表示圖片區(qū)域的左上角,而{1,1}表示右下角在橫向模式(Home鍵在右側(cè)),即使設(shè)備處于縱向模式時(shí)也是。
您可以使用adjustingFocus屬性來(lái)確定設(shè)備當(dāng)前是否正在進(jìn)行對(duì)焦。 您可以使用鍵值觀察觀察屬性,以在設(shè)備啟動(dòng)和停止對(duì)焦時(shí)獲得通知。
如果更改對(duì)焦模式設(shè)置,可以按如下方式將其返回到默認(rèn)配置:
if ([currentDevice isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) {
CGPoint autofocusPoint = CGPointMake(0.5f, 0.5f);
[currentDevice setFocusPointOfInterest:autofocusPoint];
[currentDevice setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
}
曝光模式
有兩種曝光模式:
- AVCaptureExposureModeContinuousAutoExposure: 設(shè)備根據(jù)需要自動(dòng)調(diào)整曝光級(jí)別。
- AVCaptureExposureModeLocked: 曝光級(jí)別固定在當(dāng)前級(jí)別.
您使用isExposureModeSupported:方法來(lái)確定設(shè)備是否支持給定的曝光模式,然后使用exposureMode屬性設(shè)置模式。
另外,設(shè)備可能支持興趣點(diǎn)曝光。 您可以使用exposurePointOfInterestSupported測(cè)試。 如果支持,您可以使用exposurePointOfInterest設(shè)置曝光點(diǎn)。 您傳遞一個(gè)CGPoint,其中{0,0}表示圖片區(qū)域的左上角,而{1,1}表示右下角在橫向模式(Home鍵在右側(cè)),即使設(shè)備處于縱向模式時(shí)也是。
您可以使用adjustingExposure屬性來(lái)確定設(shè)備是否正在更改其曝光設(shè)置。 您可以使用鍵值觀察監(jiān)聽(tīng)屬性,以在設(shè)備啟動(dòng)或停止改變曝光模式時(shí)獲得通知。
如果更改曝光設(shè)置,可以按如下方式將其返回到默認(rèn)配置:
if ([currentDevice isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) {
CGPoint exposurePoint = CGPointMake(0.5f, 0.5f);
[currentDevice setExposurePointOfInterest:exposurePoint];
[currentDevice setExposureMode:AVCaptureExposureModeContinuousAutoExposure];
}
閃光模式
有三種閃光模式:
- AVCaptureFlashModeOff: 閃光燈關(guān)閉.
- AVCaptureFlashModeOn: 閃關(guān)燈永遠(yuǎn)打開(kāi).
- AVCaptureFlashModeAuto: 閃光燈將根據(jù)環(huán)境光線條件自動(dòng)觸發(fā).
您使用hasFlash來(lái)確定設(shè)備是否有閃光燈。 如果該方法返回YES,則使用isFlashModeSupported:方法,傳遞所需的模式以確定設(shè)備是否支持給定的閃光模式,然后使用flashMode屬性設(shè)置模式。
手電筒模式
在手電筒模式下,閃光燈以低功率持續(xù)照明來(lái)進(jìn)行視頻拍攝。有三種手電筒模式:
- AVCaptureTorchModeOff: 手電筒關(guān)閉.
- AVCaptureTorchModeOn: 手電筒打開(kāi).
- AVCaptureTorchModeAuto: 手電筒在需要的時(shí)候自動(dòng)打開(kāi)和關(guān)閉.
您使用hasTorch來(lái)確定設(shè)備是否有閃關(guān)燈。 您使用isTorchModeSupported:方法來(lái)確定設(shè)備是否支持給定的閃關(guān)燈模式,然后使用torchMode屬性設(shè)置模式。
對(duì)于帶手電筒的設(shè)備,手電筒只有在設(shè)備與正在運(yùn)行的捕獲會(huì)話關(guān)聯(lián)時(shí)才會(huì)打開(kāi)。
視頻穩(wěn)定
視頻穩(wěn)定是否可用于操作視頻取決于特定的設(shè)備硬件。 即使如此,并不是所有的源格式和視頻分辨率都得到支持。
啟用電影視頻穩(wěn)定也可能在視頻捕獲管道中加入額外的延遲。 要檢測(cè)視頻穩(wěn)定是否正在使用,請(qǐng)使用videoStabilizationEnabled屬性。 enablesVideoStabilizationWhenAvailable屬性允許應(yīng)用程序自動(dòng)啟用視頻穩(wěn)定(如果相機(jī)支持)。 默認(rèn)情況下,由于上述限制,自動(dòng)穩(wěn)定功能被禁用。
白平衡
有兩種白平衡模式:
- AVCaptureWhiteBalanceModeLocked: 白平衡模式是固定的.
- AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance: 相機(jī)會(huì)根據(jù)需要連續(xù)調(diào)節(jié)白平衡.
您使用isWhiteBalanceModeSupported:方法來(lái)確定設(shè)備是否支持給定的白平衡模式,然后使用whiteBalanceMode屬性設(shè)置模式。
您可以使用adjustingWhiteBalance屬性來(lái)確定設(shè)備當(dāng)前是否正在更改其白平衡設(shè)置。 您可以使用鍵值觀察觀察屬性,以在設(shè)備啟動(dòng)或停止更改其白平衡設(shè)置時(shí)獲得通知。
設(shè)置設(shè)備方向
您可以在AVCaptureConnection上設(shè)置所需的方向,以指定如何在AVCaptureOutput(AVCaptureMovieFileOutput,AVCaptureStillImageOutput和AVCaptureVideoDataOutput)中為圖形定向。
使用AVCaptureConnectionsupportsVideoOrientation屬性來(lái)確定設(shè)備是否支持更改視頻的方向,以及videoOrientation屬性來(lái)指定在輸出端口中的圖像的方向。 List 4-1顯示了如何將AVCaptureConnection的方向設(shè)置為AVCaptureVideoOrientationLandscapeLeft:
List 4-1設(shè)置捕獲連接的方向
AVCaptureConnection *captureConnection = <#A capture connection#>;
if ([captureConnection isVideoOrientationSupported]) {
AVCaptureVideoOrientation orientation = AVCaptureVideoOrientationLandscapeLeft;
[captureConnection setVideoOrientation:orientation];
}
配置設(shè)備
要在設(shè)備上設(shè)置捕獲屬性,必須先使用lockForConfiguration:獲取設(shè)備的鎖定。 這樣可以避免與其他應(yīng)用程序中的設(shè)置不兼容的更改。 以下代碼片段說(shuō)明了如何通過(guò)首先確定是否支持該模式,然后嘗試鎖定設(shè)備以進(jìn)行重新配置來(lái)改變?cè)O(shè)備上的聚焦模式。 僅當(dāng)獲得鎖定時(shí)才改變對(duì)焦模式,然后立即釋放鎖定。
if ([device isFocusModeSupported:AVCaptureFocusModeLocked]) {
NSError *error = nil;
if ([device lockForConfiguration:&error]) {
device.focusMode = AVCaptureFocusModeLocked;
[device unlockForConfiguration];
} else {
// Respond to the failure as appropriate.
只有當(dāng)您需要可設(shè)置的設(shè)備屬性保持不變時(shí),才應(yīng)該保持設(shè)備鎖定。 不必要地持有設(shè)備鎖會(huì)降低共享設(shè)備的其他應(yīng)用程序的捕獲效果。
在設(shè)備之間切換
有時(shí)您可能希望允許用戶在輸入設(shè)備之間切換,例如從使用前置攝像頭切換到后置攝像頭。 為了避免停頓或卡頓,您可以在運(yùn)行時(shí)重新配置會(huì)話,但是您應(yīng)該使用beginConfiguration和commitConfiguration來(lái)包含您的配置更改:
AVCaptureSession *session = <#A capture session#>;
[session beginConfiguration];
[session removeInput:frontFacingCameraDeviceInput];
[session addInput:backFacingCameraDeviceInput];
[session commitConfiguration];
當(dāng)最外面的配置被調(diào)用時(shí),所有的更改都在一起被改變。 這確保了一個(gè)平穩(wěn)過(guò)渡。
使用捕獲輸入將捕獲設(shè)備添加到會(huì)話
要將捕獲設(shè)備添加到捕獲會(huì)話中,可以使用AVCaptureDeviceInput(抽象類AVCaptureInput的具體子類)的實(shí)例。 捕獲設(shè)備輸入管理設(shè)備的端口。
NSError *error;
AVCaptureDeviceInput *input =
[AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (!input) {
// Handle the error appropriately.
}
您可以使用addInput:向會(huì)話添加輸入。 您可以使用canAddInput:檢查捕獲輸入是否與現(xiàn)有會(huì)話兼容。
AVCaptureSession *captureSession = <#Get a capture session#>;
AVCaptureDeviceInput *captureDeviceInput = <#Get a capture device input#>;
if ([captureSession canAddInput:captureDeviceInput]) {
[captureSession addInput:captureDeviceInput];
} else {
// Handle the failure.
}
有關(guān)如何重新配置正在運(yùn)行的會(huì)話的詳細(xì)信息,請(qǐng)參閱Configuring a Session 。
AVCaptureInput會(huì)提供一個(gè)或多個(gè)媒體數(shù)據(jù)流。 例如,輸入設(shè)備可以提供音頻和視頻數(shù)據(jù)。 輸入提供的每個(gè)媒體流由AVCaptureInputPort對(duì)象表示。 捕獲會(huì)話使用AVCaptureConnection對(duì)象來(lái)定義一組AVCaptureInputPort對(duì)象與單個(gè)AVCaptureOutput之間的映射。
使用捕獲輸出從會(huì)話獲取輸出
要從捕獲會(huì)話獲取輸出,您需要添加一個(gè)或多個(gè)輸出。 輸出是AVCaptureOutput的具體子類的一個(gè)實(shí)例。 你可以使用:
- AVCaptureMovieFileOutput 輸出到電影文件
- AVCaptureVideoDataOutput 如果要在捕獲的視頻中處理幀,例如,創(chuàng)建自己的自定義視圖層
- AVCaptureAudioDataOutput 如果要處理正在捕獲的音頻數(shù)據(jù)
- AVCaptureStillImageOutput 如果要捕獲帶有附帶元數(shù)據(jù)的靜態(tài)圖像
您可以使用addOutput:將輸出添加到捕獲會(huì)話。 您可以使用canAddOutput:檢查捕獲輸出是否與現(xiàn)有會(huì)話兼容。 您可以在會(huì)話運(yùn)行時(shí)根據(jù)需要添加和刪除輸出。
AVCaptureSession *captureSession = <#Get a capture session#>;
AVCaptureMovieFileOutput *movieOutput = <#Create and configure a movie output#>;
if ([captureSession canAddOutput:movieOutput]) {
[captureSession addOutput:movieOutput];
} else {
// Handle the failure.
}
保存到電影文件
可以使用AVCaptureMovieFileOutput對(duì)象將電影數(shù)據(jù)保存到文件。(AVCaptureMovieFileOutput是AVCaptureFileOutput的具體子類,它定義了大部分的基本行為。)您可以配置影片文件輸出的各個(gè)方面,例如錄制的最長(zhǎng)持續(xù)時(shí)間或文件的最大尺寸。 如果剩余的磁盤(pán)空間少于一定數(shù)量,您也可以禁止錄制。
AVCaptureMovieFileOutput *aMovieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
CMTime maxDuration = <#Create a CMTime to represent the maximum duration#>;
aMovieFileOutput.maxRecordedDuration = maxDuration;
aMovieFileOutput.minFreeDiskSpaceLimit = <#An appropriate minimum given the quality of the movie format and the duration#>;
輸出的分辨率和比特率取決于捕獲會(huì)話的sessionPreset。 視頻編碼通常是H.264,音頻編碼通常是AAC。 實(shí)際值因設(shè)備而異。
開(kāi)始錄制
您可以使用startRecordingToOutputFileURL:recordingDelegate:來(lái)錄制QuickTime影片。您需要提供一個(gè)基于文件的URL和代理。 URL不能標(biāo)識(shí)現(xiàn)有文件,因?yàn)殡娪拔募敵霾粫?huì)覆蓋現(xiàn)有資源。 您還必須具有寫(xiě)入指定位置的權(quán)限。 代理必須符合AVCaptureFileOutputRecordingDelegate協(xié)議,并且必須實(shí)現(xiàn)captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error:方法。
AVCaptureMovieFileOutput *aMovieFileOutput = <#Get a movie file output#>;
NSURL *fileURL = <#A file URL that identifies the output location#>;
[aMovieFileOutput startRecordingToOutputFileURL:fileURL recordingDelegate:<#The delegate#>];
在實(shí)現(xiàn)captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error:時(shí),代理可能會(huì)將生成的電影寫(xiě)入Camera Roll相冊(cè)。 它還應(yīng)該檢查可能發(fā)生的任何錯(cuò)誤。
確保文件成功寫(xiě)入
要確定文件是否成功保存,在實(shí)現(xiàn)captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error:時(shí),您不僅要檢查錯(cuò)誤,還檢查錯(cuò)誤的用戶信息字典(error’s user info dictionary)中的AVErrorRecordingSuccessfullyFinishedKey的值:
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput
didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL
fromConnections:(NSArray *)connections
error:(NSError *)error {
BOOL recordedSuccessfully = YES;
if ([error code] != noErr) {
// A problem occurred: Find out if the recording was successful.
id value = [[error userInfo] objectForKey:AVErrorRecordingSuccessfullyFinishedKey];
if (value) {
recordedSuccessfully = [value boolValue];
}
}
// Continue as appropriate...
您應(yīng)該檢查AVErrorRecordingSuccessfullyFinishedKeykey的值,因?yàn)樵撐募赡芤殉晒Ρ4妫词狗祷亓艘粋€(gè)錯(cuò)誤。 錯(cuò)誤可能表示您的錄制達(dá)到了一個(gè)約束 - 例如,AVErrorMaximumDurationReached或者AVErrorMaximumFileSizeReached。 其他導(dǎo)致錄制結(jié)束的原因是:
- 磁盤(pán)已滿 AVErrorDiskFull
- 錄制設(shè)備已斷開(kāi) AVErrorDeviceWasDisconnected
- 會(huì)話中斷(例如,接到電話)AVErrorSessionWasInterrupted
添加元數(shù)據(jù)到文件
你也可以隨時(shí)設(shè)置影片文件的元數(shù)據(jù),即使在錄制時(shí)。 對(duì)于在記錄開(kāi)始時(shí)信息不可用的情況(如位置信息一樣)下這是很有用的。 文件輸出的元數(shù)據(jù)由AVMetadataItem對(duì)象的數(shù)組表示; 您可以使用其可變子類AVMutableMetadataItem的實(shí)例來(lái)創(chuàng)建您自己的元數(shù)據(jù)。
AVCaptureMovieFileOutput *aMovieFileOutput = <#Get a movie file output#>;
NSArray *existingMetadataArray = aMovieFileOutput.metadata;
NSMutableArray *newMetadataArray = nil;
if (existingMetadataArray) {
newMetadataArray = [existingMetadataArray mutableCopy];
} else {
newMetadataArray = [[NSMutableArray alloc] init];
}
AVMutableMetadataItem *item = [[AVMutableMetadataItem alloc] init];
item.keySpace = AVMetadataKeySpaceCommon;
item.key = AVMetadataCommonKeyLocation;
CLLocation *location - <#The location to set#>;
item.value = [NSString stringWithFormat:@"%+08.4lf%+09.4lf/" location.coordinate.latitude, location.coordinate.longitude];
[newMetadataArray addObject:item];
aMovieFileOutput.metadata = newMetadataArray;
處理視頻幀
AVCaptureVideoDataOutput對(duì)象使用委托來(lái)公開(kāi)視頻幀。您可以使用setSampleBufferDelegate:queue:設(shè)置委托。除了設(shè)置委托,您還可以指定一個(gè)在其上調(diào)用委托方法的串行隊(duì)列。您必須使用串行隊(duì)列來(lái)確保視頻幀以適當(dāng)?shù)捻樞騻鬟f給代理。您可以使用隊(duì)列來(lái)修改傳遞的優(yōu)先級(jí)和處理視頻幀。有關(guān)示例實(shí)現(xiàn),請(qǐng)參閱SquareCam。
這些視頻幀在委托方法captureOutput:didOutputSampleBuffer:fromConnection:中,作為CMSampleBufferRef的實(shí)例(請(qǐng)參閱 Representations of Media)。默認(rèn)情況下,緩沖區(qū)以相機(jī)最有效的格式發(fā)出。您可以使用videoSettings屬性來(lái)指定自定義輸出格式。視頻設(shè)置屬性是一個(gè)字典;目前唯一支持的鍵是kCVPixelBufferPixelFormatTypeKey。推薦的像素格式由availableVideoCVPixelFormatTypes屬性返回,由availableVideoCodecTypes屬性返回支持的值。 Core Graphics和OpenGL都能與BGRA格式配合使用:
AVCaptureVideoDataOutput *videoDataOutput = [AVCaptureVideoDataOutput new];
NSDictionary *newSettings = @{ (NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA) };
videoDataOutput.videoSettings = newSettings;
// discard if the data output queue is blocked (as we process the still image
[videoDataOutput setAlwaysDiscardsLateVideoFrames:YES];)
// create a serial dispatch queue used for the sample buffer delegate as well as when a still image is captured
// a serial dispatch queue must be used to guarantee that video frames will be delivered in order
// see the header doc for setSampleBufferDelegate:queue: for more information
videoDataOutputQueue = dispatch_queue_create("VideoDataOutputQueue", DISPATCH_QUEUE_SERIAL);
[videoDataOutput setSampleBufferDelegate:self queue:videoDataOutputQueue];
AVCaptureSession *captureSession = <#The Capture Session#>;
if ( [captureSession canAddOutput:videoDataOutput] )
[captureSession addOutput:videoDataOutput];
處理視頻的性能注意事項(xiàng)
您應(yīng)該將會(huì)話輸出設(shè)置為應(yīng)用程序的最低實(shí)際分辨率。將輸出設(shè)置為更高的分辨率會(huì)浪費(fèi)處理周期,并且耗電。
您必須確保實(shí)現(xiàn)方法captureOutput:didOutputSampleBuffer:fromConnection:能夠在分配給幀的時(shí)間量?jī)?nèi)處理樣本緩沖區(qū)。如果時(shí)間太長(zhǎng),并且您持有了視頻幀,AV Foundation會(huì)停止傳輸視頻幀,不僅是你的代理,h還包括其他的輸出(如預(yù)覽圖層)。
您可以使用捕獲視頻數(shù)據(jù)輸出的minFrameDuration屬性來(lái)確保您有足夠的時(shí)間來(lái)處理幀,而不是以比其他情況更低的幀速率。您還應(yīng)該確保將alwaysDiscardsLateVideoFrames屬性設(shè)置為YES(默認(rèn)值)。這樣可以確保任何延遲的視頻幀都被丟棄,而不是交給您進(jìn)行處理?;蛘?,如果不在乎錄制時(shí)的延遲,并且您希望獲得所有的數(shù)據(jù),您可以將屬性值設(shè)置為NO。這并不意味著幀不會(huì)被丟棄(也就是說(shuō),幀可能會(huì)被丟棄),但是它們可能不會(huì)被過(guò)早或者頻繁地被丟棄。
捕捉靜態(tài)圖像
如果要捕獲靜態(tài)圖像,可以使用AVCaptureStillImageOutput輸出。 圖像的分辨率取決于會(huì)話的預(yù)設(shè)以及設(shè)備。
像素和編碼格式
不同的設(shè)備支持不同的圖像格式。 您可以分別使用availableImageDataCVPixelFormatTypes和availableImageDataCodecTypes找到設(shè)備支持的像素和編碼類型。 每個(gè)方法返回設(shè)備的支持的值得一個(gè)數(shù)組。 您設(shè)置outputSettings字典以指定所需的圖像格式,例如:
AVCaptureStillImageOutput *stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *outputSettings = @{ AVVideoCodecKey : AVVideoCodecJPEG};
[stillImageOutput setOutputSettings:outputSettings];
如果要捕獲JPEG圖像,則通常不應(yīng)指定您自己的壓縮格式。 相反,您應(yīng)該讓靜態(tài)圖像輸出為您做壓縮,因?yàn)樗膲嚎s是硬件加速的。 如果您需要圖像的數(shù)據(jù)表示,您可以使用jpegStillImageNSDataRepresentation:獲取NSData對(duì)象而不重新壓縮數(shù)據(jù),即使您修改了圖像的元數(shù)據(jù)。
捕獲圖像
當(dāng)您要捕獲圖像時(shí),您可以給輸出發(fā)送一個(gè)captureStillImageAsynchronouslyFromConnection:completionHandler:消息。 第一個(gè)參數(shù)是要用于捕獲的連接。 您需要查找正在收集視頻的輸入端口的連接:
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in stillImageOutput.connections) {
for (AVCaptureInputPort *port in [connection inputPorts]) {
if ([[port mediaType] isEqual:AVMediaTypeVideo] ) {
videoConnection = connection;
break;
}
}
if (videoConnection) { break; }
}
captureStillImageAsynchronouslyFromConnection:completionHandler:的第二個(gè)參數(shù)是一個(gè)包含兩個(gè)參數(shù)的block:一個(gè)包含圖像數(shù)據(jù)的CMSampleBuffer和一個(gè)錯(cuò)誤。 樣本緩沖區(qū)本身可以包含諸如EXIF字典的元數(shù)據(jù)作為附件。 您可以根據(jù)需要修改附件,但請(qǐng)注意 Pixel and Encoding Formats中討論的JPEG圖像的優(yōu)化。
[stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:
^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
CFDictionaryRef exifAttachments =
CMGetAttachment(imageSampleBuffer, kCGImagePropertyExifDictionary, NULL);
if (exifAttachments) {
// Do something with the attachments.
}
// Continue as appropriate.
}];
給用戶展示正在錄制的內(nèi)容
您可以向用戶展示相機(jī)(使用預(yù)覽圖)或麥克風(fēng)(通過(guò)監(jiān)聽(tīng)音頻通道)正在錄制的內(nèi)容。
視頻預(yù)覽
您可以使用AVCaptureVideoPreviewLayer對(duì)象向用戶展示正在錄制的內(nèi)容。 AVCaptureVideoPreviewLayer是CALayer的子類(請(qǐng)參閱Core Animation Programming Guide),您不需要任何輸出來(lái)顯示預(yù)覽。
使用AVCaptureVideoDataOutput類為客戶端應(yīng)用程序提供了在呈現(xiàn)給用戶之前訪問(wèn)視頻像素的能力。
與捕獲輸出不同,視頻預(yù)覽層持有了與其相關(guān)聯(lián)的會(huì)話的強(qiáng)引用。 這是為了確保在預(yù)覽層嘗試顯示視頻時(shí)會(huì)話不會(huì)被釋放。下面是初始化預(yù)覽圖層的方法:
AVCaptureSession *captureSession = <#Get a capture session#>;
CALayer *viewLayer = <#Get a layer from the view in which you want to present the preview#>;
AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:captureSession];
[viewLayer addSublayer:captureVideoPreviewLayer];
通常,預(yù)覽圖層與其他CALayer對(duì)象相同(參見(jiàn)Core Animation Programming Guide)。 您可以像使用其他圖層一樣縮放圖像、執(zhí)行轉(zhuǎn)換、旋轉(zhuǎn)等操作。 一個(gè)區(qū)別是,您可能需要設(shè)置圖層的orientation屬性來(lái)指定如何旋轉(zhuǎn)來(lái)自相機(jī)的圖像。 另外,您可以通過(guò)查詢supportsVideoMirroring屬性來(lái)測(cè)試設(shè)備是否支持視頻鏡像。 您可以根據(jù)需要設(shè)置videoMirrored屬性,但是當(dāng)將automaticallyAdjustsVideoMirroring屬性設(shè)置為YES(默認(rèn)值)時(shí),將根據(jù)會(huì)話的配置自動(dòng)設(shè)置鏡像值。
視頻重力模式
預(yù)覽圖層支持三種重力模式,可以使用videoGravity設(shè)置:
- AVLayerVideoGravityResizeAspect 保留寬高比,在視頻未填滿的屏幕區(qū)域顯示黑條。
- AVLayerVideoGravityResizeAspectFill 保留寬高比,但填滿屏幕區(qū)域,必要時(shí)裁剪視頻。
- AVLayerVideoGravityResize 這簡(jiǎn)單地拉伸視頻以填充屏幕區(qū)域,即使拉伸了圖像。
在預(yù)覽中使用“點(diǎn)擊聚焦”
在預(yù)覽圖層中實(shí)現(xiàn)點(diǎn)擊對(duì)焦時(shí),您需要注意。 您必須考慮圖層的預(yù)覽方向和重力,以及預(yù)覽展示的可能性。 請(qǐng)參閱示例項(xiàng)目AVCam-iOS: Using AVFoundation to Capture Images and Movies。
顯示音頻音量
要監(jiān)視拍攝連接中音頻通道中的平均和峰值級(jí)別,可以使用AVCaptureAudioChannel對(duì)象。 音頻音量不支持鍵值觀察,所以您必須按您想要的頻率輪詢更新用戶界面(例如,每秒10次)。
AVCaptureAudioDataOutput *audioDataOutput = <#Get the audio data output#>;
NSArray *connections = audioDataOutput.connections;
if ([connections count] > 0) {
// There should be only one connection to an AVCaptureAudioDataOutput.
AVCaptureConnection *connection = [connections objectAtIndex:0];
NSArray *audioChannels = connection.audioChannels;
for (AVCaptureAudioChannel *channel in audioChannels) {
float avg = channel.averagePowerLevel;
float peak = channel.peakHoldLevel;
// Update the level meter user interface.
}
}
整合:將視頻幀捕獲為UIImage對(duì)象
這個(gè)簡(jiǎn)短的代碼示例說(shuō)明了如何捕獲視頻并將獲得的幀轉(zhuǎn)換為UIImage對(duì)象。:
- 創(chuàng)建AVCaptureSession對(duì)象以協(xié)調(diào)從AV輸入到輸出的數(shù)據(jù)流。
- 找到您想要的輸入類型的AVCaptureDevice對(duì)象
- 為設(shè)備創(chuàng)建AVCaptureDeviceInput對(duì)象
- 創(chuàng)建AVCaptureVideoDataOutput對(duì)象以產(chǎn)生視頻幀
- 為AVCaptureVideoDataOutput對(duì)象實(shí)現(xiàn)代理方法以處理視頻幀
- 實(shí)現(xiàn)一個(gè)函數(shù)來(lái)將委托接收的
CMSampleBuffer轉(zhuǎn)換成UIImage對(duì)象
注意:為了專注于最相關(guān)的代碼,本示例省略了完整應(yīng)用程序的幾個(gè)方面,包括內(nèi)存管理。 要使用AVFoundation,您需要有足夠的Cocoa編程經(jīng)驗(yàn),以推斷出丟失的部分。
創(chuàng)建并配置捕獲會(huì)話
您可以使用AVCaptureSession對(duì)象來(lái)協(xié)調(diào)從AV輸入到輸出的數(shù)據(jù)流。 創(chuàng)建會(huì)話,并將其配置為生成中等分辨率的視頻幀。
AVCaptureSession *session = [[AVCaptureSession alloc] init];
session.sessionPreset = AVCaptureSessionPresetMedium;
創(chuàng)建和配置設(shè)備以及設(shè)備輸入
捕獲設(shè)備由AVCaptureDevice對(duì)象表示; 該類提供了檢索所需輸入類型的對(duì)象的方法。 一個(gè)設(shè)備具有一個(gè)或多個(gè)端口,可以使用AVCaptureInput對(duì)象進(jìn)行配置。 通常,你可以使用默認(rèn)的配置。
查找視頻捕獲設(shè)備,然后使用設(shè)備創(chuàng)建設(shè)備輸入并將其添加到會(huì)話中。 如果找不到適當(dāng)?shù)脑O(shè)備,則deviceInputWithDevice:error:方法將通過(guò)引用返回錯(cuò)誤。
AVCaptureDevice *device =
[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
AVCaptureDeviceInput *input =
[AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (!input) {
// Handle the error appropriately.
}
[session addInput:input];
創(chuàng)建和配置視頻數(shù)據(jù)輸出
你可以使用AVCaptureVideoDataOutput對(duì)象來(lái)處理被捕獲的視頻中的未壓縮幀。 您通常會(huì)配置輸出的幾個(gè)方面。 例如,對(duì)于視頻,您可以使用videoSettings屬性指定像素格式,并通過(guò)設(shè)置minFrameDuration屬性來(lái)限制幀率。
創(chuàng)建并配置視頻數(shù)據(jù)的輸出并將其添加到會(huì)話中; 通過(guò)把minFrameDuration屬性設(shè)置為1/15秒將幀率設(shè)置為15 fps:
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
[session addOutput:output];
output.videoSettings =
@{ (NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA) };
output.minFrameDuration = CMTimeMake(1, 15);
數(shù)據(jù)輸出對(duì)象使用委托來(lái)處理視頻幀。 代理必須實(shí)現(xiàn)AVCaptureVideoDataOutputSampleBufferDelegate協(xié)議。 當(dāng)你設(shè)置數(shù)據(jù)輸出的委托時(shí),還必須提供一個(gè)隊(duì)列,將在該隊(duì)列上調(diào)用回調(diào)函數(shù)。
dispatch_queue_t queue = dispatch_queue_create("MyQueue", NULL);
[output setSampleBufferDelegate:self queue:queue];
dispatch_release(queue);
你使用隊(duì)列來(lái)修改發(fā)送和處理視頻幀的優(yōu)先級(jí)。
實(shí)現(xiàn)Sample Buffer代理方法
在委托類中,實(shí)現(xiàn)captureOutput:didOutputSampleBuffer:fromConnection:
方法,它會(huì)在樣本緩沖區(qū)被寫(xiě)入時(shí)調(diào)用。 視頻數(shù)據(jù)輸出對(duì)象將幀作為CMSampleBuffer類型傳輸,因此您需要將CMSampleBuffer類型轉(zhuǎn)換為UIImage對(duì)象。 可以參考 Converting CMSampleBuffer to a UIImage Object。
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection {
UIImage *image = imageFromSampleBuffer(sampleBuffer);
// Add your code here that uses the image.
}
記住調(diào)用代理方法會(huì)在setSampleBufferDelegate:queue:中指定的隊(duì)列上調(diào)用; 如果要更新用戶界面,則必須在主線程上調(diào)用相關(guān)的代碼。
開(kāi)始以及結(jié)束錄制
配置捕獲會(huì)話后,您應(yīng)確保有錄制的權(quán)限。
NSString *mediaType = AVMediaTypeVideo;
[AVCaptureDevice requestAccessForMediaType:mediaType completionHandler:^(BOOL granted) {
if (granted)
{
//Granted access to mediaType
[self setDeviceAuthorized:YES];
}
else
{
//Not granted access to mediaType
dispatch_async(dispatch_get_main_queue(), ^{
[[[UIAlertView alloc] initWithTitle:@"AVCam!"
message:@"AVCam doesn't have permission to use Camera, please change privacy settings"
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil] show];
[self setDeviceAuthorized:NO];
});
}
}];
如果配置好了會(huì)話,并且用戶已經(jīng)允許訪問(wèn)攝像機(jī)(如果需要,麥克風(fēng)),就可以發(fā)送startRunning消息開(kāi)始錄制。
重要提示:startRunning方法是一個(gè)阻塞調(diào)用,可能需要一些時(shí)間,因此您應(yīng)該在串行隊(duì)列上執(zhí)行會(huì)話設(shè)置,以使主隊(duì)列不被阻塞。 請(qǐng)參閱AVCam-iOS: Using AVFoundation to Capture Images and Movies。
[session startRunning];
結(jié)束錄制可以發(fā)送stopRunning消息。
高幀率視頻采集
iOS 7.0在所選硬件上引入了對(duì)高幀率視頻捕獲的支持(也稱為慢動(dòng)作視頻)。AVFoundation框架支持高幀率內(nèi)容。
您可以使用AVCaptureDeviceFormat類來(lái)確定設(shè)備的捕獲功能。此類具有返回支持的媒體類型、幀率、視場(chǎng)、最大縮放系數(shù)、是否支持視頻穩(wěn)定等的方法。
捕獲支持720p(1280 x 720像素)分辨率以每秒60幀(fps)的幀率,包括視頻穩(wěn)定和可放置的P幀(H264編碼視頻的功能,使在較慢和較舊的硬件上也能讓視頻播放順暢。 )
播放增強(qiáng)了對(duì)慢速和快速播放音頻的支持,從而可以以更慢或更快的速度播放音頻。
編輯完全支持在可變組件中的縮放編輯。
導(dǎo)出提供兩個(gè)選項(xiàng),支持60 fps視頻。可用的幀率,慢速或快速運(yùn)動(dòng),或者將影片轉(zhuǎn)換為任意較慢的幀速率,例如每秒30幀。
SloPoke(沒(méi)找到=。=)示例代碼演示了AVFoundation支持快速視頻捕獲,確定硬件是否支持高幀速率視頻捕獲,使用各種速率和時(shí)間間距算法的播放以及編輯(包括為部分組件設(shè)置時(shí)間刻度)。
回放
AVPlayer的實(shí)例通過(guò)setRate:方法自動(dòng)管理大部分播放速度。該值用作播放速度的乘數(shù)。值為1.0會(huì)導(dǎo)致正常播放,0.5以半速播放,5.0會(huì)使播放比正常快五倍,依此類推。
AVPlayerItem對(duì)象支持audioTimePitchAlgorithm屬性。該屬性允許您指定使用 Time Pitch Algorithm Settings常數(shù)以各種幀速率播放動(dòng)畫(huà)時(shí)的音頻播放方式。
下表展示了支持的時(shí)間間距算法(Time pitch algorithm),質(zhì)量(Quality),算法是否使音頻捕捉到特定幀速率(Snaps to specific frame rate),以及每個(gè)算法支持的幀速率范圍(Rate range)。
| Time pitch algorithm | Quality | Snaps to specific frame rate | Rate range |
|---|---|---|---|
| AVAudioTimePitchAlgorithmLowQualityZeroLatency | 質(zhì)量低,適合快進(jìn),倒帶或低質(zhì)量的聲音 | YES | 0.5, 0.666667, 0.8, 1.0, 1.25, 1.5, 2.0 rates. |
| AVAudioTimePitchAlgorithmTimeDomain | 質(zhì)量適中,計(jì)算量少,適合聲音。 | NO | 0.5–2x rates. |
| AVAudioTimePitchAlgorithmSpectral | 最高質(zhì)量,計(jì)算量大,保留原始項(xiàng)目的間距。 | NO | 1/32–32 rates. |
| AVAudioTimePitchAlgorithmVarispeed | 高品質(zhì)播放,無(wú)間距校正。 | NO | 1/32–32 rates. |
編輯
編輯時(shí),您可以使用AVMutableComposition類來(lái)創(chuàng)建時(shí)間編輯。
- 使用composition類方法創(chuàng)建一個(gè)新的AVMutableComposition實(shí)例。
- 使用insertTimeRange:ofAsset:atTime:error:插入視頻資源。
- 使用scaleTimeRange:toDuration:設(shè)置組件的時(shí)間大小
導(dǎo)出
導(dǎo)出60 fps視頻時(shí)使用AVAssetExportPresetPassthrough類導(dǎo)出資源。可以使用兩種技術(shù)導(dǎo)出內(nèi)容:
- 使用AVAssetExportPresetPassthrough預(yù)設(shè)來(lái)避免重新編碼影片。媒體將媒體部分標(biāo)記為60 fps,部分放慢或部分加快。
- 使用恒定的幀速率導(dǎo)出以實(shí)現(xiàn)最大播放兼容性。將視頻組件的frameDuration屬性設(shè)置為30 fps。您還可以通過(guò)使用導(dǎo)出會(huì)話的audioTimePitchAlgorithm屬性來(lái)設(shè)置時(shí)間間隔。
錄制
您可以使用AVCaptureMovieFileOutput類捕獲高幀率視頻,該類自動(dòng)支持高幀率錄制。它將自動(dòng)選擇正確的H264間距和比特率。
要進(jìn)行自定義錄制,您必須使用AVAssetWriter類,這需要一些額外的設(shè)置。
assetWriterInput.expectsMediaDataInRealTime=YES;
此設(shè)置確保捕獲可以跟上輸入的數(shù)據(jù)。