Exoplayer - How to prevent rebuffering when it's on Repeat mode?

3.1k views Asked by At

I'm using exoplayer 2, and have Repeat mode on, meaning it will keep playing the video once it reaches the end. However, after the video ends and plays again, it keeps rebuffering (reloading the video). How do I prevent this from happening?

player = new SimpleExoPlayer.Builder(mContext).build();
player.setPlayWhenReady(false);
player.setRepeatMode(Player.REPEAT_MODE_ONE);

Edit1:

Have tried using LoopingMediaSource, not sure if I am doing it correctly though? Because it still rebuffers when it automatically replays the video.

DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(mContext,
                Util.getUserAgent(mContext, "yourApplicationName"));
        Uri uri = Uri.parse(mUrl);

        MediaSource videoSource =
                new ProgressiveMediaSource.Factory(dataSourceFactory)
                        .createMediaSource(uri);
        LoopingMediaSource loopingMediaSource = new LoopingMediaSource(videoSource);
        player.prepare(loopingMediaSource);
3

There are 3 answers

1
rogalz On

Try to use LoopingMediaSource and put it to player by:

player.prepare(loopingMediaSource)
8
Perraco On

When it comes to video buffering this is inevitable, as only a portion of the video is kept in memory.

What you can try is to adjust the buffering duration by setting a custom load control. Tune the setBufferDurationsMs parameters to achieve your expected results.

 final DefaultTrackSelector trackSelector = new DefaultTrackSelector(context);
 
 final DefaultLoadControl loadControl = new DefaultLoadControl
            .Builder()
            .setBufferDurationsMs(25000, 50000, 1500, 2000)
            .build();

 player = new SimpleExoPlayer
            .Builder(context)
            .setTrackSelector(trackSelector)
            .setLoadControl(loadControl)
            .build();

If by adjusting the parameters in setBufferDurationMs you can't still get the desired results, then you may need to implement the drip-feeding technique to improve rebuffering. Next a tutorial about how to implement such technique, targeted at ExoPlayer:

https://medium.com/@filipluch/how-to-improve-buffering-by-4-times-with-drip-feeding-technique-in-exoplayer-on-android-b59eb0c4d9cc

1
AAV On

You need cache data in ExoPlayer

  • Create a custom cache data source factory
public class CacheDataSourceFactory implements DataSource.Factory {
    private final Context context;
    private final DefaultDataSourceFactory defaultDatasourceFactory;
    private final long maxFileSize, maxCacheSize;

    public CacheDataSourceFactory(Context context, long maxCacheSize, long maxFileSize) {
        super();
        this.context = context;
        this.maxCacheSize = maxCacheSize;
        this.maxFileSize = maxFileSize;
        String userAgent = Util.getUserAgent(context, context.getString(R.string.app_name));
        DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
        defaultDatasourceFactory = new DefaultDataSourceFactory(this.context,
                bandwidthMeter,
                new DefaultHttpDataSourceFactory(userAgent, bandwidthMeter));
    }

    @Override
    public DataSource createDataSource() {
        LeastRecentlyUsedCacheEvictor evictor = new LeastRecentlyUsedCacheEvictor(maxCacheSize);
        SimpleCache simpleCache = new SimpleCache(new File(context.getCacheDir(), "media"), evictor);
        return new CacheDataSource(simpleCache, defaultDatasourceFactory.createDataSource(),
                new FileDataSource(), new CacheDataSink(simpleCache, maxFileSize),
                CacheDataSource.FLAG_BLOCK_ON_CACHE | CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR, null);
    }
}
  • And the player
    BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
    TrackSelection.Factory videoTrackSelectionFactory =
            new AdaptiveTrackSelection.Factory(bandwidthMeter);
    TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
    
    SimpleExoPlayer exoPlayer = ExoPlayerFactory.newSimpleInstance(this, trackSelector);
    MediaSource audioSource = new ExtractorMediaSource(Uri.parse(url),
                new CacheDataSourceFactory(context, 100 * 1024 * 1024, 5 * 1024 * 1024), new DefaultExtractorsFactory(), null, null);
    exoPlayer.setPlayWhenReady(true); 
    exoPlayer.prepare(audioSource);