11

I have a collectionView and each cell has an AVPlayer which is set to play. So every cell is playing a video at the same time. It seems that iOS only allows you to play 16 videos at the same time. For example, look at my sample app below. Out of 50 cells, only 16 started playing a video. This number always stays the same. This happens on a iPhone 6s running iOS 10. In the Xcode simulator however all 50 videos start playing. This issue only happens on an actual device.

enter image description here

Also, I get these two errors when I print this out:

print("Video player Status Failed: player item error =  (self.player.currentItem.error)")
print("Video player Status Failed: player error = \(self.player.error)")

2016-11-07 15:53:46.548288 SampleApp[1810:515089] Video player Status Failed: player item error = Error Domain=AVFoundationErrorDomain Code=-11839 "Cannot Decode" UserInfo={NSUnderlyingError=0x1704414d0 {Error Domain=NSOSStatusErrorDomain Code=-12913 "(null)"}, NSLocalizedFailureReason=The decoder required for this media is busy., NSLocalizedRecoverySuggestion=Stop any other actions that decode media and try again., NSLocalizedDescription=Cannot Decode} 2016-11-07 15:53:46.548358 SampleApp[1810:515089] Video player Status Failed: player error = (null)

Is there a limit to how many AVPlayer's you could have or am I doing something wrong?

Thanks!

JEL
  • 1,540
  • 4
  • 23
  • 51

2 Answers2

6

Indeed, there's an upper limit on the amount of AVPlayer instances you can keep alive at the same time, but this limit depends on the platform your code is running on. I myself have found that on an iPhone 5s running iOS 8, there was a limit of 4 concurrent AVPlayer instances. Here, for example, the user reports a limit of 7 for tvOS, and the same limit of 4 was reported in 2012 in stack overflow.

In any case, this limit not being officially documented means it can change back and forth between platforms and OS versions, so you should not base any code on this other than just keep concurrent AVPlayer instances as low as possible.

Basix
  • 65
  • 2
  • 11
pevasquez
  • 862
  • 8
  • 14
  • Very likely a function of hardware? – i_am_jorf Nov 08 '16 at 00:06
  • @i_am_jorf well, the fact that they are not documenting it makes it very likely a function of anything. – pevasquez Nov 08 '16 at 01:00
  • @pevasquez For my app, I will have about 10-20 videos playing at the same time. Is there a workaround for this? Any libraries? or is there a way to reuse AVPlayers? Thanks! – JEL Nov 08 '16 at 01:48
  • @pevasquez It seems that `prepareForReuse` is called slower than the delegate methods `willDisplayCell` and `didDisplayCell`. If I have a `collectionView` with about 8 videos on screen at all times and I scroll to see more, it works with `willDisplayCell` and `didDisplayCell`. But with `prepareForReuse`, not all of them play because the `AVPlayer`'s are not being set to `nil` as they go off screen - they seem to stay in memory for a while. Any ideas on this? – JEL Nov 08 '16 at 04:13
  • @pevasquez same problem here... no solutions so far? – Bruno Muniz Jan 26 '17 at 09:27
  • @JEL I suggest replacing the player's underlying asset instead of creating a new player. Way faster. – Daniel Larsson Oct 14 '17 at 17:28
  • @DanielLarsson, sadly that causes a flicker in iOS 11+. Hence why I am now here. – Adrian_H Nov 29 '17 at 11:37
  • 3
    @Adrian_H the best way of achieving what you are looking can probably be found in this Pinterest Engineering blog post about how they built their native player, it's a great read: https://medium.com/@Pinterest_Engineering/building-native-video-pins-7ff89ad3ec33 – Daniel Larsson Nov 29 '17 at 18:03
0

It's not that you can't have multiple AVPLayers, what you can't have is too many AVPlayerItems associated with AVPlayers as in player = AVPlayer(playerItem: playerItem).

For example you might have multiple vcs pushed on, and in each one of those vcs you have a player initialized with a playerItem, eventually your app will crash.

You have to dissociate the playerItem from the player player?.replaceCurrentItem(with: nil) to prevent any problems.

The number of player/playerItems before a crash is dependent on the device but on the iPhone 7+, 14-16 was definitely the limit, afterwards, a crash would occur.

You can read more about it here and here

Lance Samaria
  • 17,576
  • 18
  • 108
  • 256