Создавайте видео с помощью AVVideoCompositionCoreAnimationTool и 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")
    }

person Carolina    schedule 15.12.2016    source источник
comment
Определить действительно долго. ЦП (какой Mac или iPhone вы используете) влияет на время экспорта. Количество и стиль анимации также увеличивают время экспорта. По общему правилу, все, что меньше 1: 1 (экспорт 60-секундного видео занимает 60 секунд), является правильным. Размер имеет значение! 640x360 будет намного быстрее, чем 1280x720. Если вы перейдете к AVAssetWriter вместо AVAssetExportSession (или используете github.com/rs/SDAVAssetExportSession), вы можете также можно настроить Frame и BitRates, которые влияют на производительность как записи, так и воспроизведения.   -  person Tim Bull    schedule 19.12.2016
comment
Чтобы получить надежную оценку, просто загрузите и экспортируйте видео без каких-либо анимаций или преобразований. Это наименьшая работа, которую ваше устройство может выполнять (чтение и запись) видео. Попробуйте несколько видеороликов разной длины и используйте их в качестве основы для измерения и оценки влияния на производительность. Надеюсь это поможет. Удачи!   -  person Tim Bull    schedule 19.12.2016


Ответы (1)


Когда я тестирую экспорт на устройстве, время сильно уменьшилось, у меня это занимает всего 20 секунд. В тренажере занимает почти 2,5 минуты.

person Carolina    schedule 10.01.2017