10

In the app I have a UICollectionView with item size so that about ~20 items are visible on the screen at the same time. The content that I want to display in each cell is Gif image downloaded from Giphy / Tenor.

However, I realized that gif files take much more space (and time to load) than the relative mp4 files that both Tenor and Giphy provide for each animated image, which is actually obvious, cause mp4 file format has a compressing logic and stuff like that. Sorry if I use wrong terms.

In order to have list loaded faster I decided to switch using UIImageView with GIF images to AVPlayerLayer, cause mp4 file is like ~10x lighter than GIF image. But I faced with the performance issue similar to what described HERE. The flow is mostly the same, I have 20+ items visible at the same time, but because of hardware limitations it only shows 16 videos. I couldn't find any workaround or any other frameworks that would allow to have more than 16 AVPlayerLayer showing video at the same time.

I'm wondering how WhatsApp application works and handles this logic. It also has GIF selection from Tenor. I already checked and figured out that WhatsApp downloads small video files and not gif images. That's why it loads very fast. But I have no idea how they can show 20+ items at the same time. HERE is how that works in WhatsApp - https://media.giphy.com/media/33E84h3RAVn0vQWZak/giphy.gif. Also, I notices during scroll the small static previews are showing, but I don't see the app making requests for it. Probably they gets a first frame of the gif on the fly without any delays in main thread.

I also tried that, but even if I make every single stuff in background thread and the only line on the main thread is "self.imageView.image = myImage", it anyway is lugging a little bit if I have 8 items in the row for example and scrolling very fast.

I see only 2 possible solutions to have it loads fast (so we definitely need to load mp4 instead of gifs), and scroll smooth and without lugs:
1. WhatsApp uses its own custom Video Core to display video in the UICollectionViewCell .
2. WhatsApp downloads video to speed up the download process but then encodes mp4 file to gif one on the fly and use regular animated UIImageView to show the output gif file. However I was not able to have this flow working very fast without lugging during 'massive' scrolling

Any thoughts on how to implement the same to make it works fast and smooth as in WhatsApp? I'm unable to check how it handles the downloaded info, but for sure it downloads mp4 files and not gif ones.

Stas Ivanov
  • 917
  • 1
  • 10
  • 22
  • Nobody? Any ideas? – Stas Ivanov Jul 04 '18 at 06:51
  • I do not have any idea how WhatsApp makes it work, but there is an repo on Github https://github.com/kean/Nuke-Gifu-Plugin. If you do not want to use a 3rd party library, maybe you can look into their code and get some idea. – Faruk Jul 05 '18 at 09:48
  • Your WhatsApp example URL is broken. Can you review that and update your question? I'm not entirely sure what you are asking for... – Mihai Fratu Jul 05 '18 at 15:53
  • @MihaiFratu hello, I've just update link in the post. And also copy it here - https://media.giphy.com/media/33E84h3RAVn0vQWZak/giphy.gif – Stas Ivanov Jul 05 '18 at 16:49
  • The way collections work is that each cell is reused after it's scrolled off the screen. In your example here there are fewer than 20 simultaneously-visible cells so it stands to reason that there are also fewer than 20 player layers simultaneously in memory. If you layout so that you have fewer than 20 visible videos at once you should have no issue implementing the same way as this example with native tools. – Dare Jul 05 '18 at 16:55
  • @Dare based on issue with videos (see 3rd paragraph of my post) I cannot show more videos than the amount that is limited on the hardware/iOS side. At least it won’t work for sure with native AVPlayerLayer, I already tried that. And the layout I have required more than 20 items in a row. Actually the hardware limit is exactly 16 for most of new iPhones, so in WhatsApp there are more than 16 items simultaneously showing on the screen, so they don’t use AVPlayerLayer I believe – Stas Ivanov Jul 05 '18 at 16:59
  • The way I think they do it is they load the videos (as you already said you've noticed) and then extract a couple of frames from each. Those frames are later switched using `animationImages` property of an `UIImageView`. I'll try making a quick example for you in a bit... – Mihai Fratu Jul 05 '18 at 20:17
  • @MihaiFratu, great, thanks. But few more details: I noticed they download an actual video file right in ‘willDisplayCell’. I also tried to generate gif from the video file on the fly but that was too luggy. If you will get something that works so smoothly, that will be great! – Stas Ivanov Jul 05 '18 at 20:51
  • look at this question :https://www.reddit.com/r/iOSProgramming/comments/4512hu/spent_all_day_on_playing_animated_gifs_in_a/ – I_Al-thamary Jul 12 '18 at 09:21

0 Answers0