I have implemented a custom cache for Exoplayer2 - and am migrating from 2.11.x to 2.12.3. I have reviewed several posts here on SO (ex: here), as well as various parts from the latest Exoplayer2 developer docs (ex: here). I can get the video streamed from a local source or a remote source (ex: Dropbox) and it plays, but I don't see anything being saved in the folder I've designated as my cache other than two files (and both are extremely small):
5eedc471fe18491e.uid
cached_content_index.exi
I am guessing that the .exi file is the index that is supposed to track the cache segments, and the .uid file is a segment - but it is always 0 bytes. So for some reason, Exoplayer recognizes the cache location, but doesn't stream anything into it.
In my app, I do this:
MediaSource mediaSource = getCachedMediaSourceFactory(context, listener).createMediaSource(uri);
exoPlayer.setMediaSource(mediaSource);
exoPlayer.setPlayWhenReady(true);
exoPlayer.prepare();
getCachedMediaSourceFactory() in turn looks like:
private static ProgressiveMediaSource.Factory getCachedMediaSourceFactory(Context context, CacheDataSource.EventListener listener) {
if ( cachedMediaSourceFactory == null ) {
cachedMediaSourceFactory = new ProgressiveMediaSource.Factory(
new InTouchCacheDataSourceFactory(context,
DEFAULT_MEDIA_CACHE_FRAGMENT_SIZE_IN_BYTES,
listener));
}
return cachedMediaSourceFactory;
}
InTouchCacheDataSourceFactory in turn looks like:
public class InTouchCacheDataSourceFactory implements DataSource.Factory {
private final DefaultDataSourceFactory defaultDatasourceFactory;
private final CacheDataSource.EventListener listener;
private final long maxCacheFragmentSize;
public InTouchCacheDataSourceFactory(Context context, long maxCacheFragmentSize) {
this(context, maxCacheFragmentSize, null);
}
public InTouchCacheDataSourceFactory(Context context, long maxCacheFragmentSize, CacheDataSource.EventListener listener) {
this.maxCacheFragmentSize = maxCacheFragmentSize;
this.listener = listener;
defaultDatasourceFactory =
new DefaultDataSourceFactory(context,
new DefaultHttpDataSourceFactory(Util.getUserAgent(context, APP_NAME)));
}
@Override
public DataSource createDataSource() {
return new CacheDataSource(InTouchUtils.getMediaCache(),
defaultDatasourceFactory.createDataSource(),
new FileDataSource(),
new CacheDataSink(InTouchUtils.getMediaCache(), maxCacheFragmentSize),
CacheDataSource.FLAG_BLOCK_ON_CACHE | CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR,
listener);
}
}
And InTouchUtils.getMediaCache looks like:
public static SimpleCache getMediaCache() {
if ( mediaCache == null ) {
Context context = InTouch.getInstance().getApplicationContext();
long requestedCacheSize = Long.parseLong(PreferenceManager.getDefaultSharedPreferences(context).getString(context.getString(R.string.pref_default_cache_size_key), String.valueOf(DEFAULT_MEDIA_CACHE_SIZE_IN_MB)));
File contentDirectory = new File(context.getCacheDir(), MEDIA_CACHE_DIRECTORY);
mediaCache = new SimpleCache(contentDirectory, new LeastRecentlyUsedCacheEvictor(requestedCacheSize*(1024*1024)));
}
return mediaCache;
}
Again, the video plays fine - but it doesn't appear to be actually writing the streamed file into the cache. Why not?
I have also implemented the CacheDataSource.EventListener
interface in my app, and have overridden these two methods:
@Override
public void onCachedBytesRead(long cacheSizeBytes, long cachedBytesRead) {
Timber.d("Lifecycle: Cache read, size in bytes is: %d, bytes read was: %d", cacheSizeBytes, cachedBytesRead);
}
@Override
public void onCacheIgnored(int reason) {
switch (reason) {
case CacheDataSource.CACHE_IGNORED_REASON_ERROR:
Timber.d("Lifecycle: Cache ignored due to error");
break;
case CacheDataSource.CACHE_IGNORED_REASON_UNSET_LENGTH:
Timber.d("Lifecycle: Cache ignored due to unset length");
break;
}
}
I am not seeing either method getting called.