AVPlayer takes too much memory when playing AVComposition with multiple videos

I am creating an AVComposition and using it with an AVPlayer. The player works fine and doesn't consume much memory when I do not set playerItem.videoComposition. Here is the code that works without excessive memory usage:

func configurePlayer(composition: AVMutableComposition, videoComposition: AVVideoComposition) {
    player.pause()
    player.replaceCurrentItem(with: nil)
    
    let playerItem = AVPlayerItem(asset: composition)
    player.play()

}

However, when I add playerItem.videoComposition = videoComposition, as in the code below, the memory usage becomes excessive:

func configurePlayer(composition: AVMutableComposition, videoComposition: AVVideoComposition) {
    player.pause()
    player.replaceCurrentItem(with: nil)
    
    let playerItem = AVPlayerItem(asset: composition)
    playerItem.videoComposition = videoComposition
    player.play()
}

Issue Details:

The memory usage seems to depend on the number of video tracks in the composition, rather than their duration. For instance, two videos of 30 minutes each consume less memory than 40 videos of just 2 seconds each.

The excessive memory usage is showing up in the Other Processes section of Xcode's debug panel.

For reference, 42 videos, each less than 30 seconds, are using around 1.4 GB of memory.

I'm struggling to understand why adding videoComposition causes such high memory consumption, especially since it happens even when no layer instructions are applied. Any insights on how to address this would be greatly appreciated. Before After

I initially thought the problem might be due to having too many layer instructions in the video composition, but this doesn't seem to be the case. Even when I set a videoComposition without any layer instructions, the memory consumption remains high.

Answered by vade in 817279022

You need to ensure that you re-use tracks in your composition when creating a composition. Validate that your existing composition video track can be re-used when making a new insert / edit - assuming you dont need multiple tracks for transition effects.

The API for this is mutableTrack(compatibleWith track: AVAssetTrack) -> AVMutableCompositionTrack?

The way this works is

for every source video track you want to edit into your composition:

  • check if there is an existing compatible track on your composition
  • if there is, use it
  • if not, make a new one and use that,

The more times you can re-use the same track (ie for standard edits) the better, and less memory you will consume.

Accepted Answer

You need to ensure that you re-use tracks in your composition when creating a composition. Validate that your existing composition video track can be re-used when making a new insert / edit - assuming you dont need multiple tracks for transition effects.

The API for this is mutableTrack(compatibleWith track: AVAssetTrack) -> AVMutableCompositionTrack?

The way this works is

for every source video track you want to edit into your composition:

  • check if there is an existing compatible track on your composition
  • if there is, use it
  • if not, make a new one and use that,

The more times you can re-use the same track (ie for standard edits) the better, and less memory you will consume.

And note, that video with the same / compatible CMFormatDesc should allow for track re-use. If you happen to have 42 videos with completely incompatible formats (ie resolution, frame rate, pixel format, color space) are all unique combinations, you will get zero re-use.

if all videos are say, 1080p 30, BGRA rec 709 you should get 100% re-use.

AVPlayer takes too much memory when playing AVComposition with multiple videos
 
 
Q