Pre-caching/Downloading progressive streams in ExoPlayer

Erdem Guven
AndroidX Media3
Published in
2 min readAug 2, 2017

In this post, we’ll show how to download both the whole and part of a progressive stream, how to query the download progress, and finally how to remove downloaded content.

Downloading

Using the CacheUtil.cache() method, it’s fairly easy to pre-cache/download progressive streams, such as mp4 files, in ExoPlayer:

public static void cache(
DataSpec dataSpec,
Cache cache,
DataSource upstream,
CachingCounters counters)

It is a blocking method and it won’t return until the download is finished. So it’s a good idea to call it on a background thread.

Pre-caching

If you want to pre-cache just the beginning of a piece of media, you can define a range in the DataSpec that’s passed to cache():

dataSpec = new DataSpec(uri, 0, 100 * 1024, null);

This will make cache() download only the first 100KB of the file.

Querying download progress

The cache() method accepts an optional CachingCounters, which is updated during the download. The fields of the passed CachingCounters instance can be read whilst downloading, for example to update a progress bar.

# In thread A
CacheUtil.cache(dataSpec, cache, upstreamDataSource, counters);
# In thread B
double downloadPercentage = (counters.totalCachedBytes() * 100d)
/ counters.contentLength;

Advanced settings

The cache() method has an overload for advanced settings:

public static void cache(
DataSpec dataSpec,
Cache cache,
CacheDataSource dataSource,
byte[] buffer,
PriorityTaskManager priorityTaskManager,
int priority,
CachingCounters counters,
boolean enableEOFException)

In this version you can provide a PriorityTaskManager and a priority to use. This allows prioritizing one download over another, or de-prioritizing downloads so that they are paused whilst foreground playbacks take place.

Querying downloaded content

Another useful method in CacheUtil class is getCached() method:

public static void getCached(
DataSpec dataSpec,
Cache cache,
CachingCounters counters)

Calling this you can learn how much of a file has been cached previously.

Removing downloaded content

One final method to mention is:

public static void remove(Cache cache, String key)

This method can be used to remove downloaded content for the given cache key. To remove downloaded content for a given DataSpec, call:

CacheUtil.remove(cache, CacheUtil.getKey(dataSpec));

Happy caching!

--

--