4

使用https://google.github.io/ExoPlayer/doc/reference/com/google/android/exoplayer2/upstream/cache/CacheDataSourceFactory.html有没有办法获取所有已缓存的 MediaSource?

4

2 回答 2

7

Cache 没有提供方便的 API 来获取所有完全缓存的 URI 或类似的。

如果您创建自己的CacheEvictor(例如通过包装LeastRecentlyUsedCacheEvictor),您可以在添加或删除跨度时自己记账,然后委托给 LRUCacheEvictor。通过这种方式,您可以维护缓存 URL 的列表。

您可以检查给定 uri 的哪些部分被缓存:

// create the data spec of a given media file
Uri uri = Uri.parse("http://cool.stuff.com/song-123.mp3")
DataSpec dataSpec = new DataSpec(uri);
// get information about what is cached for the given data spec
CacheUtil.CachingCounters counters = new CacheUtil.CachingCounters();
CacheUtil.getCached(dataSpec, cache, counters);
if (counters.contentLength == counters.totalCachedBytes()) {
  // all bytes cached
} else if (counters.totalCachedBytes() == 0){
  // not cached at all
} else {
  // partially cached
}

如果给定 uri 的数据仅被部分缓存,您可以检查哪些 span 可用,如下所示:

NavigableSet<CacheSpan> cachedSpans =
   cache.getCachedSpans(CacheUtil.generateKey(uri));
于 2018-01-04T16:26:02.190 回答
0

CacheUtil 不再存在,https://github.com/google/ExoPlayer/blob/2a88f0fb295ff5b56e6fbcbe7e91bdf922cbae13/RELEASENOTES.md#2120-2020-09-11

还有另一种检查缓存内容的方法:

import com.google.android.exoplayer2.upstream.DataSpec
import com.google.android.exoplayer2.upstream.cache.CacheDataSource
import com.google.android.exoplayer2.upstream.cache.ContentMetadata
import com.google.android.exoplayer2.upstream.cache.Cache

/* the same instance, used in player build pipeline */
lateinit var cacheDataSourceFactory: CacheDataSource.Factory
/* usually this is SimpleCache instance, also used in player build pipeline */
lateinit var cacheImpl: Cache

fun isCompletelyCached(urL :String) :Boolean {
  val uri = Uri.parse(urL)
  // factory which is used to generate "content key" for uri.
  // content keys are not always equal to urL
  // in complex cases the factory may be different from default implementation
  val cacheKeyFactory = cacheDataSourceFactory.cacheKeyFactory
  // content key used to retrieve metadata for cache entry
  val contentKey = cacheKeyFactory.buildCacheKey(DataSpec(uri))
  val contentMetadata = cache.getContentMetadata(contentKey)
  val contentLength = ContentMetadata.getContentLength(contentMetadata)
  if(contentLength < 0){
    // this happens when player has never queried this urL over network 
    // or has no info about size of the source
    return false
  }
  // this is summary for all cache spans, cached by exoplayer, which belongs to given urL.
  // each span is a chunk of content, which may be randomly downloaded
  val cachedLength = cache.getCachedBytes(contentKey, 0L, contentLength)

  return contentLength == cachedLength
}
于 2021-10-22T10:11:27.827 回答