Multiple AVPlayers in UIScrollView - only 16 are shown
I am developing a video gallery, I have a ScrollView with several views inside it, each view has one AVPlayer - so far this is a pretty standard option. Please note that all AVPlayers are preloaded with their videos, waiting to be played.
The problem comes when I have a lot of items (videos) in the gallery. At any given time - only 16 of them are shown from start to finish, the rest show a black screen. If I change the order of the items, the remaining 16 are displayed from the new side, and the rest show a black screen.
Also, if I go to another screen and then go back to the gallery - everything goes black and nothing is displayed.
If I replace the players with a random background color for each view, all views are displayed. So I guess the problem is with the players and not the views themselves.
According to Xcode, my app only uses ~ 7-10% CPU and ~ 10-11 MB RAM, so this doesn't seem like a performance issue - more like limiting concurrent active AVPlayers, but I couldn't find information regarding this.
Does anyone have any suggestions? it drives me crazy.
Thanks in advance!
source to share
I faced the same problem as you in a different context (I had a table view that was loading the video and it stopped working after 16 clicks).
These were some of the topics that helped me:
AVPlayer crash after multiple replays -
AVPlayerItem does not work with AVStatusFailed and "Can not Decode" error code
How to close the previous AVPlayer and AVPlayerItem
This is essentially a hard limit of 16 avplayers / avplayerlayers that can be created. If you try to exceed this, you will get uncomfortable behavior.
In your specific case, you will need to buffer 16 videos and remove / add them as they will no longer become visible in the scrollview. I would recommend making the buffer lower (like 8) because 16 causes a serious lag behind the latest iphone.
To remove the player use this code:
player.pause() player = nil playerLayer.removeFromSuperlayer()
Make sure the player is a variable (don't use let) and that it's an optional type.
var player : AVPlayer? = AVPlayer(url: videoURL as URL)
Hope it helps
source to share