skip to Main Content

I have searched for cache in/of ExoPlayer but i neither understoond them nor could implement them correctly.

In this asked question for using cache in Exoplayer there are some answers with sample code. The first answer that i’m not able to implement it is in part two of sample code which said to use the class DefaultHttpDataSourceFactory that i suppose it was changed with the class DefaultHttpDataSource.Factory() that does not seem much of a problem but the main problem i faced was this line of code

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);

that says use class ExtractorMediaSource which there is not calss by this name, i even did not find in depricated classes of exoplayer document. Almost evetything has changed in exoplayer in version 2.18.0. For instance, the part that we should set MediaSource for exoplayer now it is sepreated into two parts:

final DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(context, "agent name"); //part one
final ProgressiveMediaSource.Factory mediaSourceFactory = new ProgressiveMediaSource.Factory(dataSourceFactory); //part two

I hope you have seen the differences and my problem with this solution

And now next solution and its problem: This dear friend suggest to use This Library which sound good and some how solved my problem but what this dependency compile 'com.danikula:videocache:2.7.1' actually does is to download the video and save it in app folder. since android Pie(9) and new privacy plicy of google and android phone producers, they do not allow to access app folder.

And the same issue with other solutions that are in Kotlin, the classes in exoplayer are missing.

What i want:
I want to use cache in exoplayer2(or cache of exoplayer2) like Glide that save image in app cache i want to implement similar functionality for my exoplayer2, i have searched almost everywhere.

Note:
I use these dependecies of ExoPlayer:

implementation 'com.google.android.exoplayer:exoplayer-core:2.18.0'
implementation 'com.google.android.exoplayer:exoplayer-dash:2.18.0'
implementation 'com.google.android.exoplayer:exoplayer-ui:2.18.0'
implementation 'com.google.android.exoplayer:exoplayer:2.18.0'

I am finished with my app just need to figure out this part of it.

2

Answers


  1. Use Builder class to create player object and set MediaSourceFactory to caching like this:

                val databaseProvider = StandaloneDatabaseProvider(context)
            context.getExternalFilesDir("voice/$artistId/$albumNumber")?.let {
                simpleCache = SimpleCache(
                    it,
                    NoOpCacheEvictor(),
                    databaseProvider
                )
                val defaultDataSourceFactory = DefaultDataSource.Factory(context)
                val cacheDataSourceFactory = CacheDataSource.Factory()
                    .setCache(simpleCache!!)
                    .setUpstreamDataSourceFactory(defaultDataSourceFactory)
                player = ExoPlayer
                    .Builder(context)
                    .setMediaSourceFactory(DefaultMediaSourceFactory(cacheDataSourceFactory))
                    .build()
            } ?: kotlin.run {
                player = ExoPlayer.Builder(context).build()
            }
    
    Login or Signup to reply.
  2. const val CACHE_DIR_NAME = "cached_audio"
    const val MAX_CACHE_SIZE = 256 * 1024 * 1024L//256MB
    
    class MediaCache private constructor(context: Context) {
    
        val cacheFactory: CacheDataSource.Factory
    
        init {
            cacheFactory = setupExoPlayerCache(context)
        }
    
        companion object {
            @Volatile
            private lateinit var instance: MediaCache
    
            fun getInstance(context: Context): MediaCache {
                synchronized(this) {
                    if (!::instance.isInitialized) {
                        instance = MediaCache(context)
                    }
                    return instance
                }
            }
        }
    
        @SuppressLint("UnsafeOptInUsageError")
        private fun setupExoPlayerCache(context: Context): CacheDataSource.Factory {
            val cacheEvictor = LeastRecentlyUsedCacheEvictor(MAX_CACHE_SIZE)
            val databaseProvider = StandaloneDatabaseProvider(context)
            val cache = SimpleCache(
                File(context.cacheDir, CACHE_DIR_NAME),
                cacheEvictor, databaseProvider
            )
            val upstreamFactory = DefaultDataSource.Factory(context)
            return CacheDataSource.Factory().apply {
                setCache(cache)
                setUpstreamDataSourceFactory(upstreamFactory)
                setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR)
            }
        }
    }
    

    and then everywhere you pass media source to exoplayer:

                val mediaItem = MediaItem.fromUri(uri)
    
                val mediaSourceFactory =
                    ProgressiveMediaSource.Factory(MediaCache.getInstance(this@PlaybackService).cacheFactory)
                val mediaSource = mediaSourceFactory.createMediaSource(mediaItem)
    
                player.setMediaSource(mediaSource, true)
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search