0%

AVFoundation导出API

AVAssetExportSession

AVAssetExportSession可以实现简单的导出。

输入:AVAsset

输出:URL

可配置项:

  • 格式
    • preset
    • timeRange: CMTimeRange
    • outputFileType: AVFileType
  • 限制与优化
    • fileLengthLimit: Int64
    • shouldOptimizeForNetworkUse: Bool
    • canPerformMultiplePassesOverSourceMediaData: BooldirectoryForTemporaryFiles: URL
  • 附加
    • audioMix: AVAudioMix
    • videoComposition: AVVideoComposition
    • audioTimePitchAlgorithm: AVAudioTimePitchAlgorithm
    • metadata: [AVMetadataItem]

操作:exportAsynchronouslycancelExport

获取状态:progressstatuserror

Reader+Writer

AVAssetReader

管理读取输出。

输入:AVAsset

操作:startReadingcancelReading、添加输出

状态:statuserror

AVAssetReaderOutput

输出帧。

输入:AVAssetTrack

配置:alwaysCopiesSampleData: Bool

操作:copyNextSampleBuffermarkConfigurationAsFinal(提前结束)

输出:CMSampleBuffer

具体子类:

  • TrackOutput:最常用
    • 输入:AVAssetTrack
    • 配置:
      • outputSettings: [String : Any]
      • audioTimePitchAlgorithm: AVAudioTimePitchAlgorithm
  • AudioMixOutput
    • 输入:[AVAssetTrack]
    • 配置:
      • audioSettings: [String : Any]
      • audioMix: AVAudioMix
      • audioTimePitchAlgorithm: AVAudioTimePitchAlgorithm
  • VideoCompositionOutput
    • 输入:[AVAssetTrack]
    • 配置:
      • videoSettings: [String : Any]
      • videoComposition: AVVideoComposition
  • SampleReferenceOutput
    • 输入:AVAssetTrack

AVAssetReaderOutputMetadataAdaptor

从TrackOutput输出元数据。

操作:nextTimedMetadataGroup

AVAssetWriter

管理写入输入。

输出:URL

配置:

  • outputFileType: AVFileType
  • directoryForTemporaryFiles: URL
  • metadata: [AVMetadataItem]
  • movieFragmentInterval: CMTime
  • overallDurationHint: CMTime
  • movieTimeScale: CMTimeScale
  • shouldOptimizeForNetworkUse: Bool

操作:startWritingfinishWritingcancelWriting、添加输入(组)、startSessionendSession

状态:statuserror

AVAssetWriterInput

拼接音视频帧。

输入:CMSampleBuffer

配置:

  • mediaType: AVMediaType
  • outputSettings: [String : Any]
  • sourceFormatHint: CMFormatDescription
  • preferredVolume: Float
  • transform: CGAffineTransform
  • naturalSize: CGSize
  • mediaTimeScale: CMTimeScale
  • metadata: [AVMetadataItem]
  • expectsMediaDataInRealTime: Bool
  • marksOutputTrackAsEnabled: Bool
  • performsMultiPassEncodingIfSupported: Bool
  • preferredMediaChunkAlignment: Int
  • preferredMediaChunkDuration: CMTime
  • mediaDataLocation: AVAssetWriterInput.MediaDataLocation

操作:拼接帧、markAsFinishedaddTrackAssociation

状态:requestMediaDataWhenReadyisReadyForMoreMediaData

AVAssetWriterInputGroup

输入:AVAssetWriterInput

AVAssetWriterInputPixelBufferAdaptor

拼接指定PTS的CVPixelBuffer,并提供CVPixelBufferPool。

输出:AVAssetWriterInput

配置:sourcePixelBufferAttributes: [String : Any]

AVAssetWriterInputMetadataAdaptor

拼接AVTimedMetadataGroup到Input。

输出:AVAssetWriterInput

AVOutputSettingsAssistant

辅助生成音视频配置字典。

组合实现导出

先对AVAsset异步加载"tracks"key。

读取流程:

  1. 用AVAsset构建AssetReader;
  2. 根据轨道,使用解码配置字典分别创建ReaderOutput;
  3. 添加到AssetReader;
  4. AssetReader调用startReading开始读取;
  5. ReaderOutput循环逐帧调用copyNextSampleBuffer,输出帧,若帧为空则完成或遇到错误。

写入流程:

  1. 用输出URL、文件类型创建AssetWriter;
  2. 根据轨道类型,使用编码配置字典创建WriterInput;
  3. 添加到AssetWriter;
  4. AssetWriter调用startWritingstartSession开始写入;
  5. WriterInput调用requestMediaDataWhenReady,在其回调中:
    1. isReadyForMoreMediaData == true
    2. WriterInput拼接帧;完成时调用markAsFinished
  6. 各个轨都写入完成时,AssetWriter调用finishWriting完成写入(这会内部调用endSession)。

要想提前结束,调用endSession,再调用finishWriting

配置字典是关键。

组合使用:

  1. 异步读取AVAsset key,进入初始化阶段:
    1. 创建AssetReader,然后AssetWriter。
    2. 取出AssetTrack创建分别创建ReaderOutput和WriterInput。
  2. 读取拼接阶段:
    1. AssetReader调用startReading开始读取;AssetWriter调用startWritingstartSession开始写入;
    2. ReaderOutput循环逐帧调用copyNextSampleBuffer,输出帧;WriterInput检查是否就绪,拼接帧;
  3. ReaderOutput没有帧了,进入完成阶段:
    1. 检查是否有错误;
    2. AssetWriter调用finishWriting完成写入。

多线程应用:

  • 都使用串行队列,分别创建:
    • 主操作队列 ×1
    • 各轨道读写队列 ×N
  • 初始化阶段在主队列进行,即在异步读取AVAsset key后进入主操作队列创建各种对象。
  • 每个轨道的读帧、写帧操作都在对应的一个队列中进行。
  • 使用调度组在所有轨道都读写完成后回调通知。进入各轨道队列前enter,各个轨道读写完成后leave。
  • 完成后进入主操作队列,进行收尾工作。

欢迎关注我的其它发布渠道