使用 AVVideoCompositionCoreAnimationTool 和 AVAssetExportSession SLOW 创建视频
Create video with AVVideoCompositionCoreAnimationTool and AVAssetExportSession SLOW
我创建了一个带图层的动画,我想导出一个带有该动画的视频。所以我用了AVAssetExportSession,但是导出时间比较长
也许我可以用别的东西?我真的需要帮助!
let videoURL = NSURL.init(fileURLWithPath: "/Users/Downloads/img_2040.mp4")
let audioURL = NSURL.init(fileURLWithPath: "/Users/Downloads/music_10sm.m4a")
let videoAsset = AVURLAsset.init(url: videoURL as URL)
let audioAsset = AVURLAsset.init(url: audioURL as URL)
let mixComposition = AVMutableComposition.init()
let compositionVideoTrack = mixComposition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)
// let mixCompositionAudio = AVMutableComposition.init()
let compositionAudioTrack = mixComposition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid)
// AVAssetTrack video of originalVideo
let originalVideoAsset = videoAsset.tracks(withMediaType: AVMediaTypeVideo).first
let originalAudioAsset = audioAsset.tracks(withMediaType: AVMediaTypeAudio).first
do {
try compositionVideoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAsset.duration), of: originalVideoAsset!, at: kCMTimeZero)
compositionVideoTrack.preferredTransform = (videoAsset.tracks(withMediaType: AVMediaTypeVideo).first?.preferredTransform)!
try compositionAudioTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, audioAsset.duration), of: originalAudioAsset!, at: kCMTimeZero)
compositionAudioTrack.preferredTransform = (audioAsset.tracks(withMediaType: AVMediaTypeAudio).first?.preferredTransform)!
let videoSize = originalVideoAsset?.naturalSize
let parentLayer = CALayer()
let videoLayer = CALayer()
parentLayer.bounds = CGRect(x: 0, y: 0, width: (videoSize?.width)!, height: (videoSize?.height)!)
parentLayer.position = CGPoint(x: (videoSize?.width)!/2, y: (videoSize?.height)!/2)
videoLayer.bounds = CGRect(x: 0, y: 0, width: (videoSize?.width)!, height: (videoSize?.height)!)
videoLayer.position = CGPoint(x: (videoSize?.width)!/2 + 20, y: (videoSize?.height)!/2)
let layerTest = CALayer()
layerTest.bounds = CGRect(x: 0, y: 0, width: 100, height: 100)
layerTest.backgroundColor = UIColor.green.cgColor
parentLayer.addSublayer(videoLayer)
parentLayer.insertSublayer(layerTest, below: videoLayer)
// My layer with animations
let cubeLayer = cubeAnimation(videoSize: containerLayer.frame.size, isVideo: true)
containerLayer.addSublayer(cubeLayer)
parentLayer.addSublayer(containerLayer)
parentLayer.isGeometryFlipped = true
let videoComposition = AVMutableVideoComposition.init()
videoComposition.renderSize = videoSize!
videoComposition.frameDuration = CMTimeMake(1, 30)
videoComposition.animationTool = AVVideoCompositionCoreAnimationTool.init(postProcessingAsVideoLayer: videoLayer, in: parentLayer)
// Instruction
let instruction = AVMutableVideoCompositionInstruction.init()
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, mixComposition.duration) // TEST CAMBIAR ESTA DURATION
// Video
let videoTrack = mixComposition.tracks(withMediaType: AVMediaTypeVideo).first
let layerInstructions = AVMutableVideoCompositionLayerInstruction.init(assetTrack: videoTrack!)
instruction.layerInstructions = [layerInstructions]
videoComposition.instructions = [instruction]
let assetExport = AVAssetExportSession.init(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)
assetExport?.videoComposition = videoComposition
let exportPath = "/Users/CarolinaAitcin/Downloads/Test_ScrollBest91.mp4"
let exportUrl = URL.init(fileURLWithPath: exportPath)
assetExport?.outputFileType = AVFileTypeQuickTimeMovie
assetExport?.outputURL = exportUrl
assetExport?.shouldOptimizeForNetworkUse = true
assetExport?.exportAsynchronously {
print("Finish video")
print(NSDate())
}
Timer.schedule(repeatInterval: 1, handler: { (runTime) in
let progress = assetExport?.progress
print(progress)
})
} catch {
print("we have problem")
}
当我在设备中测试导出时,时间减少了很多,只用了 20 秒。在模拟器中大约需要2.5分钟。
我创建了一个带图层的动画,我想导出一个带有该动画的视频。所以我用了AVAssetExportSession,但是导出时间比较长
也许我可以用别的东西?我真的需要帮助!
let videoURL = NSURL.init(fileURLWithPath: "/Users/Downloads/img_2040.mp4")
let audioURL = NSURL.init(fileURLWithPath: "/Users/Downloads/music_10sm.m4a")
let videoAsset = AVURLAsset.init(url: videoURL as URL)
let audioAsset = AVURLAsset.init(url: audioURL as URL)
let mixComposition = AVMutableComposition.init()
let compositionVideoTrack = mixComposition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)
// let mixCompositionAudio = AVMutableComposition.init()
let compositionAudioTrack = mixComposition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid)
// AVAssetTrack video of originalVideo
let originalVideoAsset = videoAsset.tracks(withMediaType: AVMediaTypeVideo).first
let originalAudioAsset = audioAsset.tracks(withMediaType: AVMediaTypeAudio).first
do {
try compositionVideoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAsset.duration), of: originalVideoAsset!, at: kCMTimeZero)
compositionVideoTrack.preferredTransform = (videoAsset.tracks(withMediaType: AVMediaTypeVideo).first?.preferredTransform)!
try compositionAudioTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, audioAsset.duration), of: originalAudioAsset!, at: kCMTimeZero)
compositionAudioTrack.preferredTransform = (audioAsset.tracks(withMediaType: AVMediaTypeAudio).first?.preferredTransform)!
let videoSize = originalVideoAsset?.naturalSize
let parentLayer = CALayer()
let videoLayer = CALayer()
parentLayer.bounds = CGRect(x: 0, y: 0, width: (videoSize?.width)!, height: (videoSize?.height)!)
parentLayer.position = CGPoint(x: (videoSize?.width)!/2, y: (videoSize?.height)!/2)
videoLayer.bounds = CGRect(x: 0, y: 0, width: (videoSize?.width)!, height: (videoSize?.height)!)
videoLayer.position = CGPoint(x: (videoSize?.width)!/2 + 20, y: (videoSize?.height)!/2)
let layerTest = CALayer()
layerTest.bounds = CGRect(x: 0, y: 0, width: 100, height: 100)
layerTest.backgroundColor = UIColor.green.cgColor
parentLayer.addSublayer(videoLayer)
parentLayer.insertSublayer(layerTest, below: videoLayer)
// My layer with animations
let cubeLayer = cubeAnimation(videoSize: containerLayer.frame.size, isVideo: true)
containerLayer.addSublayer(cubeLayer)
parentLayer.addSublayer(containerLayer)
parentLayer.isGeometryFlipped = true
let videoComposition = AVMutableVideoComposition.init()
videoComposition.renderSize = videoSize!
videoComposition.frameDuration = CMTimeMake(1, 30)
videoComposition.animationTool = AVVideoCompositionCoreAnimationTool.init(postProcessingAsVideoLayer: videoLayer, in: parentLayer)
// Instruction
let instruction = AVMutableVideoCompositionInstruction.init()
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, mixComposition.duration) // TEST CAMBIAR ESTA DURATION
// Video
let videoTrack = mixComposition.tracks(withMediaType: AVMediaTypeVideo).first
let layerInstructions = AVMutableVideoCompositionLayerInstruction.init(assetTrack: videoTrack!)
instruction.layerInstructions = [layerInstructions]
videoComposition.instructions = [instruction]
let assetExport = AVAssetExportSession.init(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)
assetExport?.videoComposition = videoComposition
let exportPath = "/Users/CarolinaAitcin/Downloads/Test_ScrollBest91.mp4"
let exportUrl = URL.init(fileURLWithPath: exportPath)
assetExport?.outputFileType = AVFileTypeQuickTimeMovie
assetExport?.outputURL = exportUrl
assetExport?.shouldOptimizeForNetworkUse = true
assetExport?.exportAsynchronously {
print("Finish video")
print(NSDate())
}
Timer.schedule(repeatInterval: 1, handler: { (runTime) in
let progress = assetExport?.progress
print(progress)
})
} catch {
print("we have problem")
}
当我在设备中测试导出时,时间减少了很多,只用了 20 秒。在模拟器中大约需要2.5分钟。