Exoplayer not looping the video

Viewed 11937

I'm using Exoplayer in my android app to play video and audio files. according to Exoplayer developer's guide,in order to loop a video/audio, this is what you have to do

MediaSource mediaSource = new ExtractorMediaSource(videoUri, ...);
// Loops the video indefinitely.
LoopingMediaSource loopingSource = new LoopingMediaSource(mediaSource);

So I implemented it like this in my Activity's onCreate method

    BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
    TrackSelection.Factory factory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
    TrackSelector trackSelector = new DefaultTrackSelector(factory);

    simpleExoPlayer = ExoPlayerFactory.newSimpleInstance(this,trackSelector);
    simpleExoPlayer.setPlayWhenReady(true);
    simpleExoPlayerView.setPlayer(simpleExoPlayer);

    // Measures bandwidth during playback. Can be null if not required.
    bandwidthMeter2 = new DefaultBandwidthMeter();

// Produces DataSource instances through which media data is loaded.
    dataSourceFactory = new DefaultDataSourceFactory(this,
      Util.getUserAgent(this, applicationName), bandwidthMeter2);

// Produces Extractor instances for parsing the media data.
    extractorsFactory = new DefaultExtractorsFactory();
    mediaSource = new ExtractorMediaSource(videoUri,dataSourceFactory, extractorsFactory, null, null);

    loopingSource = new LoopingMediaSource(mediaSource);
    simpleExoPlayer.prepare(mediaSource);

But looping of my video file is not taking place. it just plays once.

6 Answers

just use player.setRepeatMode(player.REPEAT_MODE_ONE);

You can simply set repeat mode as "Repeat_MODE_ONE".

Example for Kotlin:

  val player: SimpleExoPlayer = ExoPlayerFactory.newSimpleInstance(
        context,
        DefaultRenderersFactory(context),
        DefaultTrackSelector(),
        DefaultLoadControl()
    ).apply {


       repeatMode = Player.REPEAT_MODE_ONE

    }

p.s.The player is from com.google.android.exoplayer2

player = ExoPlayerFactory.newSimpleInstance(this);

The above line of code instantiates the ExoPlayer with the default track selector. We can avoid creating bandwidth meter, track selector if we are not customising the track selector.

Looping can be achieved using LoopingMediaSource. We have to pass the loop count in the LoopingMediaSouce constructor. If we want to loop the media indefinitely, it is better to use setRepeatMode() method of the player.

new LoopingMediaSource(mediaSource, 3)

Attaching a sample for reference.

<code>
    private MediaSource getLoopingMediaSource() {
        DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(ExoPlayerActivity.this, Util.getUserAgent(ExoPlayerActivity.this, "application-name"));
        MediaSource mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(Samples.MP4_URI);
        LoopingMediaSource loopingMediaSource = new LoopingMediaSource(mediaSource, 3);
        return  loopingMediaSource;
        }

    player = ExoPlayerFactory.newSimpleInstance(this);
    playerView.setPlayer(player);
    player.prepare(getLoopingMediaSource());
    player.setPlayWhenReady(true);
</code>

the only solution that worked for me was this:

    simpleExoPlayer.prepare(mediaSource);
    simpleExoPlayer.setPlayWhenReady(true);
    simpleExoPlayer.seekTo(0);
    exoPlayer.requestFocus();
    simpleExoPlayer.addListener(new Player.EventListener() {
        @Override
        public void onLoadingChanged(boolean isLoading) {
        }

        @Override
        public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
            switch (playbackState) {
                case Player.STATE_READY:
                    prog.setVisibility(View.GONE);
                    simpleExoPlayer.setPlayWhenReady(true);
                    break;
                case Player.STATE_BUFFERING:
                    prog.setVisibility(View.VISIBLE);
                    simpleExoPlayer.seekTo(0);
                    break;
                case Player.STATE_IDLE:
                    simpleExoPlayer.retry();
                    break;
            }
        }
    });
}

If you as I need to handle the Ended event, it is possible to do it like this:

    player.addListener(object : Player.Listener {
    override fun onPlaybackStateChanged(playbackState: Int) {
        if (playbackState == Player.STATE_ENDED) {
            ...
            player.seekTo(0)
            player.play()
        }
    }
})
Related