【问题标题】:Create video with AVVideoCompositionCoreAnimationTool and AVAssetExportSession SLOW使用 AVVideoCompositionCoreAnimationTool 和 AVAssetExportSession SLOW 创建视频
【发布时间】:2023-03-29 05:29:01
【问题描述】:

我创建了一个带有图层的动画,我想导出一个带有该动画的视频。所以我用了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")
    }

【问题讨论】:

  • 定义“很长一段时间”。 CPU(您使用的 Mac 或 iPhone)对导出时间有影响。动画的数量和样式也增加了导出时间。作为一个粗略的经验法则,任何低于 1 : 1(60 秒视频需要 60 秒导出)的东西都是正确的。大小事项! 640x360 将比 1280x720 快得多。如果您改用 AVAssetWriter 而不是 AVAssetExportSession(或使用 github.com/rs/SDAVAssetExportSession),您还可以自定义 Frame 和 BitRates,这会影响写入和播放性能。
  • 要获得可靠的基准,只需加载和导出您的视频,无需任何动画或转换。这是您的设备可以做的“最少”工作(读入和写出)视频。尝试一些不同长度的视频,并将其用作衡量和评估性能影响的基准。希望这会有所帮助,祝你好运!

标签: xcode video avassetexportsession avasset avmutablecomposition


【解决方案1】:

当我在设备中测试导出时,时间减少了很多,我只需要 20 秒。在模拟器中大约需要 2.5 分钟。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-28
    • 1970-01-01
    • 1970-01-01
    • 2016-11-20
    • 1970-01-01
    • 2012-02-23
    相关资源
    最近更新 更多