Samik Prakash
Samik Prakash

Reputation: 17

How to reuse an ExoPlayer inside a recyclerview?

I have to create an app where there are video objects on the screen and I have to play them without opening a new screen. From what I have understood, the only way to implement is to add exoplayer inside my recyclerview. The only problem with this is that if I have to create a new exoplayer for each item in the recyclerview, it would perform very bad and will not be scalable at all. Is there any way to reuse my exoplayer and give the same instance to different playerviews?

Upvotes: 0

Views: 3518

Answers (3)

Praveen's answer is good, but I don't recommend u to use unofficial libs, especially in app's release. Just save current played item position in view model as live data and pass this live data to RV adapter constructor with life cycle owner. Next observe item ID in your ViewHolder bind function and compare with current item ID. If they matches - attach player to view, if not - view thumbnail and hide player, set to playerView null value. When play button clicked just pass to livedata new item ID and play player, meanwhile livedata observer update your player or thumbnail visibilty.

Upvotes: 0

Praveen
Praveen

Reputation: 3484

The only problem with this is that if I have to create a new exoplayer for each item in the recyclerview, it would perform very bad and will not be scalable at all.

You shouldn't use more than a single exoplayer, Most of the android devices have limited hardware resources, Although most of the devices would provide you more than 2 hardware decoders, but some devices are only capable of providing only single hardware decoder. So you should never rely on the idea of creating multiple exoplayers. Here's a comment from one of the maintainer of the exoplayer about creating multiple exoplayers

Is there any way to reuse my exoplayer and give the same instance to different playerviews

Yes, there is, so the basic idea here is. You use a single player-view and an exoplayer.

For playing a video at an item position.

  1. You get the item position in the recycler-view where you want to play the video.
  2. Attach player-view to this item position.
  3. Hide the thumbnail of this item position.
  4. Change media item for exo-player according to the item position.
  5. Play video.

Now for playing video at the some-other position in recycler-view

  1. Stop exoplayer playback.
  2. Hide player-view from the previously playing item position.
  3. Show thumbnail for the previously playing item position.
  4. Repeat all previous steps to play video at this new position.

You can implement this by implementing a custom Recycler-view, where you can easily get the scroll position, number of items on the screen, items height, and all other properties which are needed for the implementation of this approach.

Here is this Github Repo with this custom recycler-view implementation, You can also watch this video for this custom recycler-view implementation.

Upvotes: 2

Simon
Simon

Reputation: 566

There are going to be other ways to do it but here's an example using the information available on this page: https://exoplayer.dev/ui-components.html

If you want the video objects to play simultaneously I guess you'll need multiple exoplayer instances, however I'm assuming that you will be using some sort of scroll events to determine when one video stops and another one starts (for example the video that is most central). If this is the case you could do it by:

  • Having your exoplayer instance owned by the same thing that owns you recyclerview (so that they have the same object lifetimes)
  • Each of your recyclerview cells will have a StyledPlayerView or similar
  • Have the owning object monitor the recycler view current scroll position and determine when one cell is going to stop playing and the next start (or have the recyclerview emit an event when what it whats playing needs to change).
  • Stop playback on the current item and call setPlayer(null) on the StyledPlayerView that is currently playing back
  • Find the StyledPlayerView thats going to do the next bit of playback and call setPlayer(yourExoPlayerInstance) on it
  • Prepare/Start exoplayer again.

You might want to think about using two exoplayer instances in order to do some sort of transition/handover and also what the behaviours going to be if the user flings the list one way or the other.

Upvotes: 1

Related Questions