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

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


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. :)


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.


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.