Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reusing ExoPlayer instance in RecyclerView using ImaMediaSource crash. #3334

Closed
alonaviram opened this issue Oct 10, 2017 · 3 comments
Closed
Labels

Comments

@alonaviram
Copy link

alonaviram commented Oct 10, 2017

Hi,
I have a list of video items,
Im trying to use the same instance of exoplayer in recycler view when scrolling between items.
when i'm using normal HlsMediaSource the player works perfectly and very fast,
when I wrap the HlsMediaSource with ImaAdsMediaSource, the first video plays normally, but when i scroll to the next item i get an IndexOutOfBoundsException in TimeLine.getPeriod (in TimeLine.EMPTY instance) (adding stacktrace below)

java.lang.IndexOutOfBoundsException
  at com.google.android.exoplayer2.Timeline$1.getPeriod(Timeline.java:532)
  at com.google.android.exoplayer2.Timeline.getPeriod(Timeline.java:687)
  at com.google.android.exoplayer2.ExoPlayerImpl.getContentPosition(ExoPlayerImpl.java:375)
  at com.google.android.exoplayer2.SimpleExoPlayer.getContentPosition(SimpleExoPlayer.java:794)
  at com.google.android.exoplayer2.ui.PlaybackControlView.updateProgress(PlaybackControlView.java:797)
  at com.google.android.exoplayer2.ui.PlaybackControlView.updateAll(PlaybackControlView.java:647)
  at com.google.android.exoplayer2.ui.PlaybackControlView.show(PlaybackControlView.java:602)
  at com.google.android.exoplayer2.ui.SimpleExoPlayerView.showController(SimpleExoPlayerView.java:769)
  at com.google.android.exoplayer2.ui.SimpleExoPlayerView.maybeShowController(SimpleExoPlayerView.java:750)
  at com.google.android.exoplayer2.ui.SimpleExoPlayerView.access$500(SimpleExoPlayerView.java:199)
  at com.google.android.exoplayer2.ui.SimpleExoPlayerView$ComponentListener.onPlayerStateChanged(SimpleExoPlayerView.java:907)
  at com.google.android.exoplayer2.ExoPlayerImpl.handleEvent(ExoPlayerImpl.java:422)
  at com.google.android.exoplayer2.ExoPlayerImpl$1.handleMessage(ExoPlayerImpl.java:103)
  at android.os.Handler.dispatchMessage(Handler.java:105)
  at android.os.Looper.loop(Looper.java:164)
  at android.app.ActivityThread.main(ActivityThread.java:6541)
  at java.lang.reflect.Method.invoke(Native Method)
  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

this is my code (relevant to the issue):

public class SingleVideoPlayer {
    private SimpleExoPlayer exoPlayer;
    private Context context;
    private ImaAdsLoader imaAdsLoader;

    public SingleVideoPlayer(Context context, String adTagUrl) {
        this.context = context;

        imaAdsLoader = new ImaAdsLoader(context, Uri.parse(adTagUrl));
        DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
        DefaultTrackSelector trackSelector = new DefaultTrackSelector(bandwidthMeter);
        exoPlayer = ExoPlayerFactory.newSimpleInstance(this.context, trackSelector);
    }


    public void playVideoItem(final VideoListItem videoListItem, final VideoViewHolder viewHolder, int newActiveViewPosition) {
        setNewSource(videoListItem.getVideoUrl(), viewHolder.getSimpleExoPlayerView());
        viewHolder.getSimpleExoPlayerView().setPlayer(exoPlayer);
    }

    public void setNewSource(String videoUrl, FrameLayout adUiContainer) {
        Uri uri = Uri.parse(videoUrl);
        String userAgent = Util.getUserAgent(context, "appName");
        DefaultHttpDataSourceFactory defaultDataSourceFactory = new DefaultHttpDataSourceFactory(userAgent);
        MediaSource mediaSource = new HlsMediaSource(uri, defaultDataSourceFactory, null, null);
        ImaAdsMediaSource imaAdsMediaSource =
                new ImaAdsMediaSource(mediaSource, defaultDataSourceFactory, imaAdsLoader, adUiContainer);
        exoPlayer.prepare(imaAdsMediaSource);
        exoPlayer.setPlayWhenReady(true);
    }

    public void stopPlayback(VideoViewHolder viewHolder, int oldActivePosition) {
        exoPlayer.stop();
    }
}

I managed to solve this by creating a new instance of ExoPlayer every time i start a new video, but i really don't want to do this.
any help would be appreciated :) thanks!

edit:
the exception only occurs when scrolling while there is an ad currently playing and you scroll to another item

@ojw28 ojw28 added the bug label Oct 10, 2017
ojw28 added a commit that referenced this issue Oct 17, 2017
Issue: #3334

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=172447125
ojw28 added a commit that referenced this issue Oct 17, 2017
Issue: #3334

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=172447125
@ojw28
Copy link
Contributor

ojw28 commented Oct 19, 2017

We believe this is fixed in dev-v2. The fix will land in r2.5.4. Please verify and let us know if not.

@ojw28 ojw28 closed this as completed Oct 19, 2017
@alonaviram
Copy link
Author

Seems like its fixed, thanks !

@varun7952
Copy link

can you show us your code,how can we use exoplayer inside recyclerview (Chat type screen) where we can play any video in multiple list of videos(Like whatsapp)

@google google locked and limited conversation to collaborators Mar 7, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants