【发布时间】:2020-12-19 12:21:12
【问题描述】:
我正在使用AVAssetExportSession 保存带有一些文本/图像覆盖的视频。
它工作得很好,除了保存新视频需要很多时间,我见过其他应用程序做得更快,比如快 2-4 倍。所以我想知道我做错了什么吗?
这是我的代码(我删除了一些不相关的部分以便更好地阅读错误,如果您想查看某些功能的实现,请告诉我):
func saveVideo() {
guard let fileURL = videoMediaURL else { return }
let vidAsset = AVURLAsset(url: fileURL, options: nil)
// Create an AVMutableComposition for editing
let mutableComposition = getVideoComposition(asset: vidAsset)
let videoTrack: AVAssetTrack = mutableComposition.tracks(withMediaType: AVMediaType.video)[0]
var size = videoTrack.naturalSize
//fixing native ios rotated video
if videoTrack.preferredTransform.c == -1 {
size = CGSize(width: size.height, height: size.width)
}
let isLandscape = size.width > size.height
if videoTrack.preferredTransform.a == 1 && videoTrack.preferredTransform.d == 1 && isLandscape {
size = CGSize(width: size.height, height: size.width)
}
let instruction = AVMutableVideoCompositionInstruction()
instruction.timeRange = CMTimeRangeMake(start: CMTime.zero, duration: mutableComposition.duration)
let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)
var transform = videoTrack.preferredTransform
if transform.a == 1 && transform.d == 1 && isLandscape {
let diff = size.height / size.width
let scale = videoTrack.preferredTransform.xScale * diff
transform = videoTrack.preferredTransform.translatedBy(x: (-size.width * scale) / 1.65, y: videoTrack.preferredTransform.yOffset).scaledBy(x: videoTrack.preferredTransform.xScale * diff, y: videoTrack.preferredTransform.yScale * diff)
}
if transform.tx >= 3840 {
transform = videoTrack.preferredTransform.translatedBy(x: 0, y: transform.xOffset / 2)
}
layerInstruction.setTransform(transform, at: .zero)
instruction.layerInstructions = [layerInstruction]
let containerLayer = setupLayers()
let layerComposition = AVMutableVideoComposition()
layerComposition.frameDuration = CMTimeMake(value: 1, timescale: Int32(videoTrack.nominalFrameRate))
layerComposition.renderSize = size
layerComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: containerLayer)
layerComposition.instructions = [instruction]
//Remove existing file
deleteFile(outputURL)
//export the video to as per your requirement conversion
if let exportSession = AVAssetExportSession(asset: mutableComposition, presetName: AVAssetExportPresetHighestQuality) {
self.exportSession = exportSession
exportSession.outputURL = outputURL
exportSession.outputFileType = AVFileType.m4v
exportSession.shouldOptimizeForNetworkUse = true
exportSession.videoComposition = layerComposition
// try to export the file and handle the status cases
exportSession.exportAsynchronously(completionHandler: {
//handle exportSession result
})
}
}
}
【问题讨论】:
-
是不是因为
AVAssetExportPresetHighestQuality? -
@matt 我必须提供高质量的视频,所以不能设置较低的质量。我仍然可以看到其他更快地导出高质量视频的应用
-
导出需要多长时间?您有示例输入和输出文件吗?
-
@RhythmicFistman 10 秒 4k 视频大约需要 10 秒,我可以上传示例输入/输出视频
-
@RhythmicFistman dropbox.com/sh/g9lfxqtolh8m6xq/AAC7T2jQbTVr4lh03W5bxOz1a?dl=0
标签: ios avfoundation avassetexportsession avmutablevideocomposition