1

Even when I don't apply any filters the performance of AVAssetExportSession exportAsynchronously is very very bad. It takes more than 10 seconds or so to export a 26 second video. How can I fix that?

let avPlayerItem = AVPlayerItem(asset: video)
avVideoComposition = AVVideoComposition(asset: avPlayerItem.asset, applyingCIFiltersWithHandler: { request in
    request.finish(with: request.sourceImage, context: nil)
})
avPlayerItem.videoComposition = avVideoComposition

// -----------

func exportFilterVideo(videoComposition:AVVideoComposition , completion: @escaping
(_ outputURL : NSURL?) -> ()) {
    let exportSession = AVAssetExportSession(asset: self, presetName: AVAssetExportPresetHighestQuality)!
    let croppedOutputFileUrl = URL( fileURLWithPath: NSTemporaryDirectory() + NSUUID().uuidString + ".mov")
    exportSession.outputURL = croppedOutputFileUrl
    exportSession.outputFileType = AVFileType.mov
    exportSession.videoComposition = videoComposition
    exportSession.exportAsynchronously(completionHandler: {
        guard exportSession.status != .failed else {
            completion(nil)
            return
        }
        if exportSession.status == .completed {
            DispatchQueue.main.async(execute: {
                completion(croppedOutputFileUrl as NSURL)
            })
        }
        else {
            completion(nil)
        }
    })
}

even when I use AVAssetExportPresetLowQuality it does not help!

HangarRash
  • 7,314
  • 5
  • 5
  • 32
SwiftiSwift
  • 7,528
  • 9
  • 56
  • 96

1 Answers1

1

First solution:

if you've tried exportSession with AVAssetExportPresetMediumQuality & AVAssetExportPresetLowQuality and not helped! then consider AVAssetExportPresetHighestQuality

A preset to export a high-quality movie file.

let exportSession = AVAssetExportSession(asset: self, presetName: AVAssetExportPresetHighestQuality)!

Then try setting the videoComposition to nil if you do not need to apply any filters , cause as it says in the videoComposition

videoComposition:

An optional object that provides instructions for how to composite frames of video.

The default value is nil.

exportSession.videoComposition = nil

Try with .mp4 video encoding formats as it may perform better than .mov

exportSession.outputFileType = AVFileType.mp4 // or AVFileType.mov

And if you need your video to be optimized for network usage then try this

exportSession.shouldOptimizeForNetworkUse = true

But please note that this may take a bit longer with the export session!

Second solution:

I've experienced the same problem a while ago and I ended up solving this issue by first compressing the video and then apply changes to it which improve the whole speed of the program.

I used the following library

LightCompressor_iOS

LightCompressor_example

and this is a sample code

let compression: Compression = videoCompressor.compressVideo(source: url, destination: url, quality: .very_high, keepOriginalResolution: true, progressQueue: .main, progressHandler: nil) { (result) in
    print("Compression result \(result)")
    switch result {
    case .onStart:
        print("onStart")
        break
    case .onSuccess(_):
        print("✅onSuccess✅")
        break
    case .onFailure(_):
        print("❌onFailure❌")
        break
    case .onCancelled:
        print("✅Size after compression is \(Int(videoLocalPath!.fileSizeInMB()))MB✅")
    }
}

compression.cancel = true

video editor iOS app (just for reference)

You may fetch and run the app from the following project as it is an iOS app for applying filters, stickers and images to videos so that you can recognize how it perform on your device. OptiVideoEditor-for-iOS

I think the code that you would be interested to read is in the following link

OptiVideoEditor

  • Thanks for the detailed answer but the first solution did not work and I don't want to use any third party library to compress every video to basically apply basic filter. – SwiftiSwift May 24 '23 at 17:33