美文网首页图像音频
OC之录制文件AVCaptureFileOutput

OC之录制文件AVCaptureFileOutput

作者: 苏沫离 | 来源:发表于2018-10-15 21:10 被阅读0次

    一、抽象类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样式元数据项

    相关文章

      网友评论

        本文标题:OC之录制文件AVCaptureFileOutput

        本文链接:https://www.haomeiwen.com/subject/jmesaftx.html