AVAssetExportSession export fails non-deterministically with error: “Operation Stopped, NSLocalizedFailureReason=The video could not be composed.”

后端 未结 5 581
误落风尘
误落风尘 2020-12-13 19:45

We add subtitles to a video recorded by the user, but the export by our AVAssetExportSession object fails non-deterministically: sometimes it works, and sometimes it doesn\'

相关标签:
5条回答
  • 2020-12-13 20:20

    I'm guessing that some of your videos' sourceVideoTracks are either:

    • tracks that are non contiguous
    • tracks with time range shorter than the video's whole time range

    The mutable track videoTrack, on the other hand, is guaranteed the correct time range (as instructed by the AVMutableVideoCompositionInstruction) so it always works.

    0 讨论(0)
  • 2020-12-13 20:24

    if U set the width or the height to zero could lead to crash with Operation Stopped, NSLocalizedFailureReason=The video could not be composed

    self.mutableVideoComposition.renderSize = CGSizeMake(assetVideoTrack.naturalSize.height,assetVideoTrack.naturalSize.width);
    
    0 讨论(0)
  • 2020-12-13 20:26

    What seems to be the cure is making sure the assetTrack parameter in AVMutableVideoCompositionLayerInstruction is not from the AVURLAsset object, but from the video object returned by addMutableTrackWithMediaType.

    In other words, this line:

    let videoLayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: sourceVideoTrack)
    

    Should be:

    let videoLayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)
    

    Argh. Hours of endless frustration because sometimes the first line worked, and sometimes it didn't.

    Still would like to award the bounty to someone.

    If you can explain why the first line failed non-deterministically, instead of every time, or provide a deeper tutorial into AVMutableComposition and its related classes -- for the purposes of adding text overlays to user-recorded videos -- the bounty is all yours. :)

    0 讨论(0)
  • 2020-12-13 20:31

    Late to the party, but here's what worked for me. The export would fail "randomly". So then I debug the length of the video track and the length of the audio track.

    I noticed that when the audio track was longer than the video track the export would fail.

    So I made this change:

    let assetVideoTrack = asset.tracks(withMediaType: .video).first!
    let assetAudioTrack = asset.tracks(withMediaType: .audio).first!
    
    
    var validTimeRange:CMTimeRange
    if assetVideoTrack.timeRange.duration.value > assetAudioTrack.timeRange.duration.value {
        validTimeRange = assetVideoTrack.timeRange
    } else {
        validTimeRange = assetAudioTrack.timeRange
    }
    

    So then I would use that value here:

    let instruction = AVMutableVideoCompositionInstruction()
    instruction.layerInstructions = [layerInstructions]
    instruction.timeRange = validTimeRange
    

    This has solved the problem for me. Works 100% of the times now.

    Exported video looks good and recorded audio with it sounds great.

    The answer to the questions:

    1) What's causing the problem, and what's the solution?

    2) Suggestions on how to reproduce the error consistently, which hopefully helps debug the problem?

    For me are the following:

    1. slightly different durations between video and audio tracks. Using the shorter time in instruction.timeRange would fail the export.

    2. set instruction.timeRange to the shorter time of the two tracks and the export fails.

    0 讨论(0)
  • 2020-12-13 20:35

    I resolved this problem by using the AVAssetExportPresetPassthrough export preset rather than using a specific resolution or AVAssetExportHighestQuality

    let exportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetPassthrough)
    

    This should use the resolution of the imported video in the exported file.

    0 讨论(0)
提交回复
热议问题