OC之錄制文件AVCaptureFileOutput

一、抽象類AVCaptureFileOutput

AVCaptureFileOutputAVCaptureOutput的子類,可以將捕獲的數據記錄到文件中。

1、設置屬性

屬性 數據類型 描述
delegate id 委托對象;AVCaptureFileOutputDelegate協議將能夠沿樣本邊界準確的監測和控制記錄。
maxRecordedDuration CMTime 允許錄制的最長時間;默認值為kCMTimeInvalid表示無限制。
maxRecordedFileSize int64_t 允許錄制數據的最大字節;默認值為0,表示沒有限制。
minFreeDiskSpaceLimit int64_t 錄制時要求指定磁盤的最小可用空間量。
outputFileURL NSURL 只讀屬性,錄制文件的存儲路徑URL。
recordedDuration CMTime 只讀屬性,當前錄制的時間
recordedFileSize int64_t 只讀屬性,當前錄制的數據的大小(字節)
recording BOOL 只讀屬性,當前是否正在錄制。
recordingPaused BOOL 只讀屬性,當前錄制是否暫停。

對于錄制文件的限制屬性:maxRecordedFileSizemaxRecordedDurationminFreeDiskSpaceLimit,達到限制時將停止錄制并且調用協議方法-captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error:顯示相應的錯誤。

2、開始,停止,暫停和恢復錄制

2.1、開始錄制

給定文件的存儲路徑URL,開始錄制。

- (void)startRecordingToOutputFileURL:(NSURL *)outputFileURL
recordingDelegate:(id<AVCaptureFileOutputRecordingDelegate>)delegate;
  • 參數 outputFileURL:錄制文件的輸出路徑;如果不是有效的fileURL,則此方法拋出異常NSInvalidArgumentException
  • 參數 delegate:記錄會話的委托對象。

如果錄制開始時已存在給定URL的文件,則記錄到新文件將失敗。

在macOS中,在調用此方法錄制另一個文件時,不需要去調用-stopRecording。如果在已經記錄現有輸出文件的同時調用此方法,則舊文件和新文件之間不會丟棄任何數據。

在iOS中,不支持幀文件精確切換。在再次調用此方法之前,必須調用-stopRecording以避免任何錯誤。

當通過調用-stopRecording、通過使用此方法更改文件或由于錯誤而停止記錄時,需要包含到文件中的其余數據將在后臺寫入。因此,必須指定一個委托,當使用-captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error:方法將所有數據寫入文件時,該委托將被通知。錄制委托還可以選擇性地實現一些方法,當數據開始寫入、錄制暫停并重新開始以及錄制即將結束時通知它。

在macOS中,如果在 -captureOutput:didOutputSampleBuffer:fromConnection:代理方法中調用此方法,則保證寫入新文件的第一個樣本是傳遞給該方法的樣本緩沖區中包含的樣本。

2.2、停止錄制

當前文件停止錄制。

- (void)stopRecording;

如果停止將新數據記錄到當前文件、并且不想繼續記錄到另一個文件時可以調用此方法。
如果要從一個文件切換到另一個文件,則應該使用新的fileURL調用-startRecordingToOutputFileURL:recordingDelegate:方法。

通過調用此方法停止錄制;通過使用-startRecordingToOutputFileURL:recordingDelegate:方法更改文件;或者由于錯誤,需要包含在文件中的剩余數據將在后臺寫入。因此,在使用該文件之前,必須等到使用-captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error:方法將所有數據寫入文件時,通知-startRecordingToOutputFileURL:recordingDelegate:中指定的委托。

在macOS中,如果在-captureOutput:didOutputSampleBuffer:fromConnection:代理方法中調用此方法,則保證寫入當前文件的最后一個樣本是在傳遞給該方法的樣本緩沖區中的那些樣本之前立即輸出的樣本。

2.3、暫停錄制

文件暫停錄制。

- (void)pauseRecording;

調用-resumeRecording方法將多個不連續的媒體段記錄到單個文件中。

在macOS中,如果在-captureOutput:didOutputSampleBuffer:fromConnection:代理方法中調用此方法,則保證寫入當前文件的最后一個樣本是在傳遞給該方法的樣本緩沖區中的那些樣本之前立即輸出的樣本。

2.4、暫停后恢復錄制

調用-pauseRecording方法暫停后,調用下述方法恢復錄制到當前輸出文件outputFileURL

- (void)resumeRecording;

在macOS中,如果在-captureOutput:didOutputSampleBuffer:fromConnection:代理方法中調用此方法,則保證寫入當前文件的第一個樣本是傳遞給該方法的樣本緩沖區中包含的樣本。

3、AVCaptureFileOutputDelegate

AVCaptureFileOutputDelegate 該協議為AVCaptureFileOutput對象的委托定義了一個接口,用于監視或控制媒體文件錄制。

3.1、是否需要準確的幀記錄

是否允許委托選擇在-captureOutput:didOutputSampleBuffer:fromConnection:方法中構建準確的記錄。

- (BOOL)captureOutputShouldProvideSampleAccurateRecordingStart:(AVCaptureOutput *)output;
  • 參數 captureOutput:與委托關聯的AVCaptureOutput實例。
  • 返回值:是否需要準確的幀記錄。

OS X Mountain Lion系統之前的應用程序中,實現-captureOutput:didOutputSampleBuffer:fromConnection:方法的代理可以通過在回調中調用-startRecordingToOutputFileURL:recordingDelegate:-stopRecording來確保啟動和停止記錄是幀精確的。幀準確記錄要求在AVCaptureSession開始運行時AVCaptureOutput應用outputSettings,因此它可以在任何給定的幀邊界上開始和/或停止記錄。在整個會話期間應用壓縮設置會產生功耗,散熱和CPU影響。

OS X Mountain Lion系統之后的應用程序中,委托必須實施此方法以指示是否需要幀精確記錄。AVCaptureFileOutput僅在添加委托時調用此方法一次,而不再調用。如果返回NO,則AVCaptureFileOutput僅在調用-startRecordingToOutputFileURL:recordingDelegate:時應用壓縮設置,并在錄制停止后禁用這些設置。

3.2、

讓委托有機會檢查錄制的數據,并在準確的時間開始和停止記錄。

- (void)captureOutput:(AVCaptureFileOutput *)output
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection;
  • 參數output:接收媒體數據的AVCaptureFileOutput
  • 參數sampleBuffer:包含樣本數據和有關樣本的其他信息,例如其格式和顯示時間。
  • 參數connection:附加到接收示例數據的文件輸出的AVCaptureConnection對象。

每當文件輸出從給定連接接收到單個示例緩沖區(例如,單個視頻幀或音頻緩沖區)時,就會調用此方法。這使委托有機會在精確的樣本邊界開始和停止記錄或更改輸出文件。如果在此方法中調用,文件輸出的-startRecordingToOutputFileURL:recordingDelegate:-resumeRecording方法保證在新文件中包含接收到的樣本緩沖區,而對-stopRecording-pauseRecording的調用保證在現有文件中包含當前樣本緩沖區中的所有樣本。

可以通過檢查CMSampleBuffer對象來收集特定于樣本的信息。如果從此方法調用,樣本緩沖區始終包含單幀視頻,但也可能包含多個音頻樣本。對于B幀視頻格式,樣本始終按呈現順序傳送。

如果需要在此方法的作用域之外引用CMSampleBuffer對象,則必須保留它,然后在用完之后釋放它。

為了保持最佳性能,一些樣本緩沖區直接引用可能需要由設備系統和其他捕獲輸入重用的內存池。對于未壓縮的設備本機捕獲,通常會出現這種情況,其中盡可能少地復制內存塊。如果多個樣本緩沖區長時間引用此類內存池,則輸入將無法再將新樣本復制到內存中,并且這些樣本將被丟棄。如果應用程序通過保留提供的CMSampleBuffer對象太長時間而導致刪除樣本,但需要長時間訪問樣本數據,請考慮將數據復制到新緩沖區中,然后在樣本緩沖區上調用CFRelease() (如果以前保留過),以便可以重用它引用的內存。

不應該假定這個方法將在特定的線程上被調用。此外,這種方法經常被調用,因此必須有效地防止捕獲性能問題。

4、AVCaptureFileOutputRecordingDelegate

AVCaptureFileOutputRecordingDelegateAVCaptureFileOutput的協議接口,以響應記錄單個文件的過程中發生的事件。AVCaptureFileOutput對象的委托必須實現該協議的方法。

-captureOutput:willFinishRecordingToOutputFileAtURL:fromConnections:error:方法和-captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error:方法總是被調用,即使沒有寫入數據。

4.1、開始錄制
 - (void)captureOutput:(AVCaptureFileOutput *)output
 didStartRecordingToOutputFileAtURL:(NSURL *)fileURL
 fromConnections:(NSArray<AVCaptureConnection *> *)connections;

輸出開始寫入文件時通知委托:

  • 參數output:開始寫入文件的捕獲文件輸出。
  • 參數fileURL:正在寫入的文件的文件URL。
  • 參數connections:附加到文件輸出的AVCaptureConnection對象數組,提供正在寫入文件的數據。

如果錯誤條件阻止寫入任何數據,則可能不會調用此方法。

4.2、即將停止錄制

在以下情況下將調用該方法:

  • 即將停止錄制文件時;
  • 調用了-startRecordingToOutputFileURL:recordingDelegate:方法時;
  • 寫入文件發生錯誤時;
- (void)captureOutput:(AVCaptureFileOutput *)output
willFinishRecordingToOutputFileAtURL:(NSURL *)fileURL
fromConnections:(NSArray<AVCaptureConnection *> *)connections
error:(NSError *)error;

當輸出即將停止向文件寫入新示例時通知委托:

  • 參數output:捕獲文件輸出將完成寫入文件。
  • 參數fileURL:正在寫入的文件的fileURL
  • 參數connections:附加到文件輸出的AVCaptureConnection對象數組,提供正在寫入文件的數據。
  • 參數error:描述導致文件停止錄制的錯誤原因,如果沒有錯誤則為nil。

即使沒有數據成功寫入文件,也始終為每個記錄請求調用此方法。

4.3、已經停止錄制

在以下情況下將調用該方法:

  • 已經停止錄制文件時;
  • 調用了-startRecordingToOutputFileURL:recordingDelegate:方法時;
  • 寫入文件發生錯誤時;
- (void)captureOutput:(AVCaptureFileOutput *)output
didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL
fromConnections:(NSArray<AVCaptureConnection *> *)connections
error:(NSError *)error;

當所有待寫入數據寫入輸出文件時通知委托:

  • 參數output:已完成寫入文件的捕獲文件輸出。
  • 參數outputFileURL:正在寫入的文件的文件fileURL
  • 參數connections:附加到文件輸出的AVCaptureConnection對象數組,提供正在寫入文件的數據。
  • 參數error:描述導致文件停止錄制的錯誤原因,如果沒有錯誤則為nil。

只要文件結束,就會調用此方法。即使沒有數據成功寫入文件,也始終為每個記錄請求調用此方法。

4.4、成功暫停錄制
- (void)captureOutput:(AVCaptureFileOutput *)output
didPauseRecordingToOutputFileAtURL:(NSURL *)fileURL
fromConnections:(NSArray<AVCaptureConnection *> *)connections;

當正在錄制時調用,并根據請求成功暫停錄制:

  • 參數output :暫停其文件記錄的捕獲文件輸出。
  • 參數fileURL :正在寫入的文件的fileURL
  • 參數connections :附加到文件輸出的AVCaptureConnection對象數組,提供正在寫入文件的數據。

只要調用-pauseRecording方法,就會調用此方法。
委托對象可以安全地從此方法中更改文件輸出當前正在執行的操作:例如,啟動新文件。如果手動或由于錯誤而停止記錄到文件,則無法保證調用此方法,即使先前調用了-pauseRecording

4.5、恢復錄制暫停文件
- (void)captureOutput:(AVCaptureFileOutput *)output
didResumeRecordingToOutputFileAtURL:(NSURL *)fileURL
fromConnections:(NSArray<AVCaptureConnection *> *)connections;

只要調用-resumeRecording方法,就會調用此方法。
委托對象可以安全地從此方法中更改文件輸出當前正在執行的操作:例如,啟動新文件。如果手動或由于錯誤而停止記錄到文件,則無法保證調用此方法,即使先前調用了-resumeRecording也是如此。

二、視頻錄制AVCaptureMovieFileOutput

AVCaptureMovieFileOutput 繼承自AVCaptureFileOutput,將視頻和音頻記錄到QuickTime電影文件的捕獲輸出。

這個類相當于AVCapturePhotoOutput的電影文件。使用它從AVCaptureSession內容導出或保存電影文件。

第一個軌道段的timeMapping.target.start必須是kCMTimeZero,并且當傳入前一個AVCompositionTrackSegmenttimeMapping.target時,每個后續軌道段的timeMapping.target.start必須等于CMTimeRangeGetEnd。可以使用-validateTrackSegments:error:確保軌道段數組符合此規則。

從ios12開始,照片格式不再列出不支持的AVCaptureMovieFileOutput類。如果構造一個以照片格式作為輸入和電影文件輸出的AVCaptureSession,則可以錄制電影。電影中視頻軌道的分辨率遵循AVCaptureVideoDataOutput建立的約定。也就是說,使用photo preset時,會收到與屏幕大小近似的視頻緩沖區。視頻輸出是此配置中照片預覽的代理。如果將AVCaptureDevice格式設置為高分辨率照片格式,將收到全分辨率(5,8,12mp)的視頻緩沖區。如果AVCaptureSessionautomatedConfiguresCaptureDeviceForWideColor屬性設置為YES,則AVCaptureSession選擇sRGB作為影片中的視頻顏色空間。可以通過向AVCaptureSession添加AVCapturePhotoOutput并為照片輸出配置其照片格式或AVCaptureSessionPresetPhoto預設設置來覆蓋此行為。

1、配置電影

每個片段寫入的輸出秒數; 默認值為10秒。kCMTimeInvalid禁用電影片段寫入。

 @property(nonatomic) CMTime movieFragmentInterval;

QuickTime電影包含媒體示例和一個表,表中標識它們在文件中的位置。沒有示例表的電影文件是不可讀的。在處理后的文件中,示例表通常出現在文件的開頭。它也可能出現在文件的末尾,在這種情況下,標頭包含指向末尾示例表的指針。在記錄新影片文件時,由于尚不知道文件的大小,因此不可能編寫示例表。相反,必須在記錄完成時寫入表。如果沒有采取其他操作,這意味著如果記錄沒有成功完成(例如,在發生崩潰的情況下),文件數據就不可用(因為沒有示例表)。通過定期將“電影片段”插入到電影文件中,可以逐步構建示例表。這意味著如果文件沒有完全寫入,那么電影文件仍然是可用的(直到最后一個片段寫入時為止)。

// 輸出文件的元數據。可以使用它向錄制的電影文件添加元數據,例如版權,創建日期等。
 @property(nonatomic, copy) NSArray<AVMetadataItem *> *metadata;

2、管理輸出設置

2.1、目前支持錄制文件的視頻編解碼器類型
 @property(nonatomic, readonly) NSArray<AVVideoCodecType> *availableVideoCodecTypes;

此列表中的第一個編解碼器是錄制電影文件的默認編解碼器。要使用不同的編解碼器進行錄制,調用-setOutputSettings:forConnection:方法,傳遞視頻設置字典,其中包含與此列表中其他值匹配的AVVideoCodecKey值。

2.2、獲取設置字典支持的鍵的列表
 - (NSArray<NSString *> *)supportedOutputSettingsKeysForConnection:(AVCaptureConnection *)connection;
2.3、獲取記錄時用于從給定連接重新編碼媒體的選項
 - (NSDictionary<NSString *,id> *)outputSettingsForConnection:(AVCaptureConnection *)connection;
  • 參數connection:提供要重新編碼的媒體的連接。
  • 返回值:輸出設置字典。

如果返回空字典,則在寫入文件之前,不會更改連接中的媒體格式。
如果使用nil字典調用-setOutputSettings:forConnection:此方法返回一個非nil,反映AVCaptureSession當前sessionPreset使用的設置。

2.4、設置用于在記錄時從給定連接重新編碼媒體的選項字典
- (void)setOutputSettings:(NSDictionary<NSString *,id> *)outputSettings
forConnection:(AVCaptureConnection *)connection;
  • 參數 outputSettings :輸出設置字典。傳遞一個空字典,指定在寫入文件之前不應更改連接中的媒體格式。傳遞nil以指定輸出格式應由會話預設確定。
  • 參數connection :提供要重新編碼的媒體的連接。

有關輸出設置的詳細信息,請參閱音頻設置和音頻連接格式或視頻連接的視頻設置詞典

3、設置方向

3.1、獲取捕獲設備是否記錄視頻方向
 - (BOOL)recordsVideoOrientationAndMirroringChangesAsMetadataTrackForConnection:(AVCaptureConnection *)connection;
3.2、設置捕獲設備是否設置視頻方向
 - (void)setRecordsVideoOrientationAndMirroringChanges:(BOOL)doRecordChanges
 asMetadataTrackForConnection:(AVCaptureConnection *)connection;

三、音頻錄制AVCaptureAudioFileOutput

AVCaptureAudioFileOutput 繼承自AVCaptureFileOutput,用于記錄音頻并將錄制的音頻保存到文件中。

AVCaptureAudioFileOutput實現AVCaptureFileOutput聲明的完整文件記錄接口,用于將媒體數據寫入音頻文件。 此外,還可以配置特定于音頻文件格式的選項,包括將元數據集合寫入每個文件以及指定音頻編碼選項。然而,AVCaptureAudioFileOutput并不能調用-startRecordingToOutputFileURL:recordingDelegate:方法,改用-startRecordingToOutputFileURL:outputFileType:recordingDelegate:方法。

1、發現支持的類型

返回包含UTI的數組,標識AVCaptureAudioFileOutput可以寫入的文件類型。

 + (NSArray<AVFileType> *)availableOutputFileTypes;

2、開始錄制

告知接收方開始記錄指定格式的新文件,并指定在記錄完成時將通知的代理。

 - (void)startRecordingToOutputFileURL:(NSURL *)outputFileURL
 outputFileType:(AVFileType)fileType
 recordingDelegate:(id<AVCaptureFileOutputRecordingDelegate>)delegate;
  • 參數 outputFileURL:輸出文件路徑;如果URL不是有效的fileURL,則此方法拋出NSInvalidArgumentException;如果錄制開始時已存在給定URL的文件,則記錄到新文件將失敗。
  • 參數fileType:UTI,指示要寫入的文件的格式;常見音頻文件類型的UTI在AVMediaFormat.h中聲明。
  • 參數delegate:必須指定一個AVCaptureFileOutputRecordingDelegate委托,以便在錄制完成時收到通知。

在另一個錄制正在進行時,無需在調用此方法之前調用-stopRecording。如果在已經記錄現有輸出文件的同時調用此方法,則舊文件和新文件之間不會丟棄任何媒體樣本。

當調用-stopRecording``錄制停止時,通過使用此方法更改文件,或者由于錯誤,需要包含在文件中的剩余數據將在后臺寫入。因此,必須指定一個委托,當使用將所有數據寫入文件時將通知該委托-captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error:```方法。委托還可以選擇性地實現在數據開始寫入時,暫停和恢復記錄時以及即將完成記錄時通知它的方法。

在macOS中,如果在-captureOutput:didOutputSampleBuffer:fromConnection:代理方法中調用此方法,則保證寫入新文件的第一個樣本是傳遞給該方法的樣本緩沖區中包含的樣本。

3、配置輸出

屬性 數據類型 描述
audioSettings NSDictionary 輸出之前解碼或重新編碼的設置字典。此屬性的值是一個字典,音頻設置鍵值包含AVAudioSettings.h中。如果將此屬性的值設置為nil,則輸出將以其設備本機格式檢出樣本。
metadata NSArray 錄制文件的元數據集合。僅支持ID3 v2.2,v2.3或v2.4樣式元數據項
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。