Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple AVPlayers in a UIScrollView - only 16 of them are shown

I'm developing a video gallery, I have a ScrollView with multiple views inside of it, each view has a single AVPlayer - so far it's pretty standard I guess. Note that all of the AVPlayers are pre-loaded with their video, waiting to be played.

The problem occurs when I have many items (videos) in the gallery. At any given time - only 16 of them are shown, from start to end, the rest shows a black screen. If I'm reversing the order of the items - the other 16 from the new side are shown, and the rest shows a black screen too.

Additionally, if I go to another screen and then come back to the gallery - everything becomes black and nothing shown.

If i'm replacing the players with a random color background for each view - all of the views are shown. So I assume the problem is with the players and not with the views themselves.

According to Xcode my app only use ~7-10% CPU and ~10-11 MB of RAM so it doesn't looks like a performance problem - more like a limitation of concurrent active AVPlayers but I couldn't find any information regarding that.

Does anyone have any suggestions? this is driving me crazy.

Thanks in advance!

like image 369
Yuri J Avatar asked Nov 10 '22 22:11

Yuri J


1 Answers

I was running into the same problem as you in a different context (I had a tableview that loaded a video and it stopped working after 16 clicks).

These were some of the threads that helped me out:

AVPlayer crashes after multiple playbacks-

AVPlayerItem fails with AVStatusFailed and error code "Cannot Decode"

How to close previous AVPlayer and AVPlayerItem

Impossible to stop AVPlayer.

Essentially theres a hard limit of 16 avplayers/avplayerlayers that can be created. If you try to exceed this you get wonky behaviour.

In your particular case you will have to create a buffer of 16 videos and remove/add them as they no longer become visible on the scrollview. I would recommend making the buffer lower (like 8) cause 16 causes some serious lag on the latest iphone model.

To remove the player use this code:

player.pause()
player = nil
playerLayer.removeFromSuperlayer()

Make sure the player is a variable (dont use let) and that it is an optional type.

var player : AVPlayer?  = AVPlayer(url: videoURL as URL)

Hope this helps

like image 130
Aditya Garg Avatar answered Nov 14 '22 22:11

Aditya Garg