How to improve AVAssetExportSession saving performance

281 Views Asked by At

I'm using AVAssetExportSession to save video with some text / image overlays on it. It's working pretty fine except It takes way to much time to save new video, I've seen other apps that do it much faster like 2-4x faster. So I'm wondering is there something I do in a wrong way?

Here is my code (I removed some unrelated parts for better reading bug if you would like to see realisation of some func please tell me):

 func saveVideo() {
    guard let fileURL = videoMediaURL else { return }

    let vidAsset = AVURLAsset(url: fileURL, options: nil)

    // Create an AVMutableComposition for editing
    let mutableComposition = getVideoComposition(asset: vidAsset)

    let videoTrack: AVAssetTrack = mutableComposition.tracks(withMediaType: AVMediaType.video)[0]
    var size = videoTrack.naturalSize

    //fixing native ios rotated video
    if videoTrack.preferredTransform.c == -1 {
        size = CGSize(width: size.height, height: size.width)
    }

    let isLandscape = size.width > size.height
    if videoTrack.preferredTransform.a == 1 && videoTrack.preferredTransform.d == 1 && isLandscape {
        size = CGSize(width: size.height, height: size.width)
    }

    let instruction = AVMutableVideoCompositionInstruction()
    instruction.timeRange = CMTimeRangeMake(start: CMTime.zero, duration: mutableComposition.duration)
    let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)

    var transform = videoTrack.preferredTransform

    if transform.a == 1 && transform.d == 1 && isLandscape {
        let diff = size.height / size.width
        let scale = videoTrack.preferredTransform.xScale * diff
        transform = videoTrack.preferredTransform.translatedBy(x: (-size.width * scale) / 1.65, y: videoTrack.preferredTransform.yOffset).scaledBy(x: videoTrack.preferredTransform.xScale * diff, y: videoTrack.preferredTransform.yScale * diff)
    }

    if transform.tx >= 3840 {
        transform = videoTrack.preferredTransform.translatedBy(x: 0, y: transform.xOffset / 2)
    }

    layerInstruction.setTransform(transform, at: .zero)
    instruction.layerInstructions = [layerInstruction]


    let containerLayer = setupLayers()

    let layerComposition = AVMutableVideoComposition()
    layerComposition.frameDuration = CMTimeMake(value: 1, timescale: Int32(videoTrack.nominalFrameRate))
    layerComposition.renderSize = size
    layerComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: containerLayer)
    layerComposition.instructions = [instruction]

    //Remove existing file
    deleteFile(outputURL)

    //export the video to as per your requirement conversion
    if let exportSession = AVAssetExportSession(asset: mutableComposition, presetName: AVAssetExportPresetHighestQuality) {
        self.exportSession = exportSession
        exportSession.outputURL = outputURL
        exportSession.outputFileType = AVFileType.m4v
        exportSession.shouldOptimizeForNetworkUse = true
        exportSession.videoComposition = layerComposition
        // try to export the file and handle the status cases
        exportSession.exportAsynchronously(completionHandler: {
            //handle exportSession result

        })
    }
}

}

1

There are 1 best solutions below

1
On

I am chasing this issue with AVAssetExportSession which may be linked to this AVAssetExportSession never starts on older devices, device needs to be rebooted.

Have you been able to resolve your issue? I am asking since the two issue are close in time and may be caused by a bug in iOS 14.3.