使用 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分钟。