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!

+3


source to share


1 answer


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

Unable to stop AVPlayer .

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

+1


source







All Articles