0

I create an animation with layers and I want to export a video with that animations. So I use AVAssetExportSession, but it take a long time to export.

Maybe I can use another thing? I really need help!

    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")
    }
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Carolina
  • 437
  • 3
  • 18
  • Define "a really long time". CPU (what Mac or iPhone you're using) is an impact on export times. The number and style of animations also increases the export times. As a rough rule of thumb, anything under 1 : 1 (60 second video takes 60 seconds to export) is about right. Size matters! 640x360 is going to be way faster than 1280x720. If you move to AVAssetWriter instead of AVAssetExportSession (or use https://github.com/rs/SDAVAssetExportSession), you can also customize Frame and BitRates too, which impact both write and playback performance. – Tim Bull Dec 19 '16 at 17:14
  • To get a solid bench mark, simply load and export your video without any animations or transformations. This is the "least" work your device can do (reading in and writing out) the video. Try a few videos at different lengths and use this as your base line to measure and assess performance impacts. Hope this helps, good luck! – Tim Bull Dec 19 '16 at 17:18

1 Answers1

0

When I test the export in a device the time decreased a lot, it only takes me 20s. In the simulator takes almost 2.5 minutes.

Carolina
  • 437
  • 3
  • 18