AVAssetExportSession
AVAssetExportSession可以实现简单的导出。
输入:AVAsset
输出:URL
可配置项:
- 格式
preset
timeRange: CMTimeRange
outputFileType: AVFileType
- 限制与优化
fileLengthLimit: Int64
shouldOptimizeForNetworkUse: Bool
canPerformMultiplePassesOverSourceMediaData: Bool
、directoryForTemporaryFiles: URL
- 附加
audioMix: AVAudioMix
videoComposition: AVVideoComposition
audioTimePitchAlgorithm: AVAudioTimePitchAlgorithm
metadata: [AVMetadataItem]
操作:exportAsynchronously
、cancelExport
获取状态:progress
、status
、error
Reader+Writer
AVAssetReader
管理读取输出。
输入:AVAsset
操作:startReading
、cancelReading
、添加输出
状态:status
、error
AVAssetReaderOutput
输出帧。
输入:AVAssetTrack
配置:alwaysCopiesSampleData: Bool
操作:copyNextSampleBuffer
、markConfigurationAsFinal
(提前结束)
输出: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
操作:startWriting
、finishWriting
、cancelWriting
、添加输入(组)、startSession
、endSession
状态:status
、error
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
操作:拼接帧、markAsFinished
、addTrackAssociation
状态:requestMediaDataWhenReady
、isReadyForMoreMediaData
AVAssetWriterInputGroup
AVAssetWriterInputPixelBufferAdaptor
拼接指定PTS的CVPixelBuffer,并提供CVPixelBufferPool。
输出:AVAssetWriterInput
配置:sourcePixelBufferAttributes: [String : Any]
AVAssetWriterInputMetadataAdaptor
拼接AVTimedMetadataGroup到Input。
输出:AVAssetWriterInput
AVOutputSettingsAssistant
辅助生成音视频配置字典。
组合实现导出
先对AVAsset异步加载"tracks"
key。
读取流程:
- 用AVAsset构建AssetReader;
- 根据轨道,使用解码配置字典分别创建ReaderOutput;
- 添加到AssetReader;
- AssetReader调用
startReading
开始读取; - ReaderOutput循环逐帧调用
copyNextSampleBuffer
,输出帧,若帧为空则完成或遇到错误。
写入流程:
- 用输出URL、文件类型创建AssetWriter;
- 根据轨道类型,使用编码配置字典创建WriterInput;
- 添加到AssetWriter;
- AssetWriter调用
startWriting
、startSession
开始写入; - WriterInput调用
requestMediaDataWhenReady
,在其回调中:isReadyForMoreMediaData == true
- WriterInput拼接帧;完成时调用
markAsFinished
。
- 各个轨都写入完成时,AssetWriter调用
finishWriting
完成写入(这会内部调用endSession
)。
要想提前结束,调用endSession
,再调用finishWriting
。
配置字典是关键。
组合使用:
- 异步读取AVAsset key,进入初始化阶段:
- 创建AssetReader,然后AssetWriter。
- 取出AssetTrack创建分别创建ReaderOutput和WriterInput。
- 读取拼接阶段:
- AssetReader调用
startReading
开始读取;AssetWriter调用startWriting
、startSession
开始写入; - ReaderOutput循环逐帧调用
copyNextSampleBuffer
,输出帧;WriterInput检查是否就绪,拼接帧;
- AssetReader调用
- ReaderOutput没有帧了,进入完成阶段:
- 检查是否有错误;
- AssetWriter调用
finishWriting
完成写入。
多线程应用:
- 都使用串行队列,分别创建:
- 主操作队列 ×1
- 各轨道读写队列 ×N
- 初始化阶段在主队列进行,即在异步读取AVAsset key后进入主操作队列创建各种对象。
- 每个轨道的读帧、写帧操作都在对应的一个队列中进行。
- 使用调度组在所有轨道都读写完成后回调通知。进入各轨道队列前enter,各个轨道读写完成后leave。
- 完成后进入主操作队列,进行收尾工作。