如何提升AVAssetExportSession的视频导出保存性能?
嘿,我仔细看了你的代码和问题描述,发现几个很可能拖慢导出速度的关键点,咱们一个个来拆解优化:
1. 换掉AVAssetExportPresetHighestQuality预设
这个预设会强制启用最高规格的编码逻辑,往往以牺牲速度为代价——尤其是处理4K、高帧率视频时,耗时会大幅增加。建议换成匹配原视频分辨率的预设,比如原视频是1080p就用AVAssetExportPreset1920x1080,4K就用AVAssetExportPreset3840x2160;如果原视频编码格式和输出格式兼容,甚至可以用AVAssetExportPresetPassthrough(直接复用原编码,跳过重新编码步骤,速度最快)。
修改代码里的导出会话初始化行:
// 替换成对应原视频分辨率的预设 if let exportSession = AVAssetExportSession(asset: mutableComposition, presetName: AVAssetExportPreset1920x1080) {
2. 关闭shouldOptimizeForNetworkUse
这个属性会让导出的视频做额外的网络友好优化(比如把文件元数据移到开头),但会增加导出耗时。如果你的视频不需要立即上传或流式播放,直接关掉它:
exportSession.shouldOptimizeForNetworkUse = false
3. 确保renderSize和原视频尺寸完全匹配
你代码里手动计算size的逻辑有点复杂,很容易出现渲染尺寸和原视频不匹配的情况,触发额外的像素缩放操作——这是耗时大户。建议直接用原视频轨道的实际展示尺寸:
// 替换你原来的size计算逻辑 let presentationSize = videoTrack.naturalSize.applying(videoTrack.preferredTransform).size layerComposition.renderSize = presentationSize
这样能保证渲染尺寸和原视频完全一致,避免不必要的缩放计算,减轻GPU/CPU负担。
4. 简化Core Animation叠加层的复杂度
你用AVVideoCompositionCoreAnimationTool添加文字/图片叠加层,如果叠加层有复杂动画、多层嵌套或高透明效果,会显著增加渲染时间。建议:
- 把多个静态元素合并成一个图层,减少图层数量
- 避免使用复杂的Core Animation动画(比如渐变、路径动画),静态叠加直接用
CALayer即可 - 确保图层的
contentsScale和视频分辨率匹配,避免额外缩放
5. 尽量复用原Asset而非MutableComposition
如果你的getVideoComposition函数只是简单包装原视频轨道,没有做拼接、裁剪等操作,完全可以不用AVMutableComposition,直接用原AVURLAsset作为导出的asset,跳过composition的额外处理步骤:
// 替换原来的mutableComposition为原vidAsset if let exportSession = AVAssetExportSession(asset: vidAsset, presetName: ...) {
6. 自定义编码参数(进阶优化)
如果上面的优化还不够,你可以手动设置编码参数,强制启用硬件加速,同时设置合理的比特率:
exportSession.videoComposition = layerComposition // 添加自定义编码设置 let exportSettings: [String: Any] = [ AVVideoCodecKey: AVVideoCodecType.h264, AVVideoWidthKey: presentationSize.width, AVVideoHeightKey: presentationSize.height, AVVideoCompressionPropertiesKey: [ AVVideoAverageBitRateKey: Int(presentationSize.width * presentationSize.height * 10), // 根据原视频比特率调整,比如原视频10Mbps就设10*1024*1024 AVVideoProfileLevelKey: AVVideoProfileLevelH264HighAutoLevel, AVVideoAllowFrameReorderingKey: false, // 关闭帧重排,提升速度 AVVideoHardwareAccelerationKey: AVVideoHardwareAccelerationType.prefer // 强制优先使用硬件加速 ] ] exportSession.outputFileType = AVFileType.m4v exportSession.outputSettings = exportSettings // 替换默认预设的设置
最后,你可以检查下getVideoComposition函数里有没有多余的操作,比如不必要的轨道添加、时间范围调整,这些都会增加导出前的处理时间。
内容的提问来源于stack exchange,提问作者Діма Комар

