Using cache in ExoPlayer

后端 未结 10 2177
暖寄归人
暖寄归人 2020-11-29 18:29

I\'m looking for any example of implementing cache in ExoPlayer.

ExoPlayer has in its library different classes concerning cache and Google explain in this video th

相关标签:
10条回答
  • 2020-11-29 18:40

    To resolve the problem of multiple videos or processes trying to access the same cache, you need a true Singleton. A reliable way would be to do it this way:

    object VideoCache {
        private var sDownloadCache: SimpleCache? = null
        private const val maxCacheSize: Long = 100 * 1024 * 1024
    
        fun getInstance(context: Context): SimpleCache {
            val evictor = LeastRecentlyUsedCacheEvictor(maxCacheSize)
            if (sDownloadCache == null) sDownloadCache = SimpleCache(File(context.cacheDir, "koko-media"), evictor)
            return sDownloadCache as SimpleCache
        }
    }
    

    which you can now use:

    private val simpleCache: SimpleCache by lazy {
            VideoCache.getInstance(context)
        }
    
    0 讨论(0)
  • 2020-11-29 18:44

    I've implemented it like this in the renderer builder

    private static final int BUFFER_SEGMENT_SIZE = 64 * 1024;
    private static final int BUFFER_SEGMENT_COUNT = 160;
    
    final String userAgent = Util.getUserAgent(mContext, appName);
    final DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
    final Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);*
    
    Cache cache = new SimpleCache(context.getCacheDir(), new LeastRecentlyUsedCacheEvictor(1024 * 1024 * 10));
    DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
    CacheDataSource cacheDataSource = new CacheDataSource(cache, dataSource, false, false);
    ExtractorSampleSource sampleSource = new ExtractorSampleSource(uri
                    , cacheDataSource
                    , allocator
                    , BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE
                    , new Mp4Extractor());
    
    0 讨论(0)
  • 2020-11-29 18:49

    In addition to Bao Le's answer, here's ready to use Kotlin version of CacheDataSourceFactory that keeps one instance of SimpleCache to solve the problem of multiple Cache objects writing to the same directory.

    class CacheDataSourceFactory(private val context: Context,
                                          private val maxCacheSize: Long,
                                          private val maxFileSize: Long) : DataSource.Factory {
    
        private val defaultDatasourceFactory: DefaultDataSourceFactory
        private val simpleCache: SimpleCache by lazy {
            val evictor = LeastRecentlyUsedCacheEvictor(maxCacheSize)
            SimpleCache(File(context.cacheDir, "media"), evictor)
        }
    
        init {
            val userAgent = Util.getUserAgent(context, context.packageName)
            val bandwidthMeter = DefaultBandwidthMeter()
            defaultDatasourceFactory = DefaultDataSourceFactory(context,
                    bandwidthMeter,
                    DefaultHttpDataSourceFactory(userAgent, bandwidthMeter))
        }
    
        override fun createDataSource(): DataSource {
            return CacheDataSource(simpleCache,
                    defaultDatasourceFactory.createDataSource(),
                    FileDataSource(),
                    CacheDataSink(simpleCache, maxFileSize),
                    CacheDataSource.FLAG_BLOCK_ON_CACHE or CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR,
                    null)
        }
    }
    
    0 讨论(0)
  • 2020-11-29 18:57

    I answered this similar question here: https://stackoverflow.com/a/58678192/2029134

    Basically, I use this library: https://github.com/danikula/AndroidVideoCache To cache file from URL Then put it in ExoPlayer.

    Here is the sample code:

    String mediaURL = "https://my_cool_vid.com/vi.mp4";
    SimpleExoPlayer exoPlayer = ExoPlayerFactory.newSimpleInstance(getContext());
    HttpProxyCacheServer proxyServer = HttpProxyCacheServer.Builder(getContext()).maxCacheSize(1024 * 1024 * 1024).build();
    
    String proxyURL = proxyServer.getProxyUrl(mediaURL);
    
    
    DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(getContext(),
                    Util.getUserAgent(getContext(), getActivity().getApplicationContext().getPackageName()));
    
    
    exoPlayer.prepare(new ProgressiveMediaSource.Factory(dataSourceFactory)
                    .createMediaSource(Uri.parse(proxyURL)););
    

    Hope that helps.

    0 讨论(0)
提交回复
热议问题