Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ExoPlayer, generalize SimpleCache behaviour

I'm using ExoPlayer 2 to play music from the web. Now I want to cache downloaded music by using the beautiful SimpleCache class. My problem is the following: every time I request to play a song, the server returns me a different URL (also for the same song), which is used as key by SimpleCache. Consequently, SimpleCache creates a new cache file for each URL (i.e. also a different file for the same song).

It would be nice if there was a way to ask me what is the key of the cached file generated for a particular url. Do you know a way to do that?

The SimpleCache class is final, so I cannot override its methods.


EDIT, a rough solution:
I created a copy of CacheDataSource and changed just this line in the method open(DataSpec), which is responsible of keys' generation:

key = dataSpec.key != null ? dataSpec.key : uri.toString();

I could generate the same key thanks to some uri's parameters which are equals for each url retrieved for the same song. This solution solves my problem but is not so generic and exploitable for every possible case.

The CacheDataSource has been then used as explained in this comment:

private DataSource.Factory buildDataSourceFactory(final boolean useBandwidthMeter) {
    return new DataSource.Factory() {
        @Override
        public DataSource createDataSource() {
            LeastRecentlyUsedCacheEvictor evictor = new LeastRecentlyUsedCacheEvictor(100 * 1024 * 1024);
            SimpleCache simpleCache = new SimpleCache(new File(getCacheDir(), "media_cache"), evictor);
            return new CacheDataSource(
                simpleCache,
                buildMyDataSourceFactory(useBandwidthMeter).createDataSource(),
                CacheDataSource.FLAG_BLOCK_ON_CACHE,
                10 * 1024 * 1024
            );
        }
    };
}

private DefaultDataSource.Factory buildMyDataSourceFactory(boolean useBandwidthMeter) {
    return new DefaultDataSourceFactory(PlayerActivity.this, userAgent, useBandwidthMeter ? BANDWIDTH_METER : null);
}
like image 497
Massimo Avatar asked Feb 06 '17 17:02

Massimo


People also ask

How do I clear my ExoPlayer cache?

A Cache implementation that maintains an in-memory representation. Only one instance of SimpleCache is allowed for a given directory at a given time. To delete a SimpleCache, use delete(File, DatabaseProvider) rather than deleting the directory and its contents directly.

What is latest version of ExoPlayer?

ExoPlayer 2.16 — What's new As always, we recommend also taking a look at the full release notes. Android 12 compatibility ExoPlayer 2.16 contains a variety of changes to ensure your app can target Android 12.


1 Answers

Since ExoPlayer 2.10.0 it has been added the ProgressiveMediaSource class, which replaces the ExtractorMediaSource (deprecated). When creating a ProgressiveMediaSource with its Factory class you can call the method setCustomCacheKey(String).

It exactly does what I needed!

like image 56
Massimo Avatar answered Oct 13 '22 01:10

Massimo