我使用ExoPlayer 2播放网络音乐。现在我想使用漂亮的SimpleCache
类来缓存下载的音乐。我的问题如下:每次我请求播放歌曲时,服务器都会返回一个不同的URL(也用于同一首歌曲),由SimpleCache
用作密钥。因此,SimpleCache
为每个URL创建一个新的缓存文件(即同一首歌的不同文件)。
如果有办法问我为特定网址生成的缓存文件的关键字,那会很好。你知道这样做的方法吗?
SimpleCache
类是final
,因此我无法覆盖其方法。
编辑,一个粗略的解决方案:
我创建了CacheDataSource
的副本,并在方法open(DataSpec)
中更改了此行,该方法负责按键'代:
key = dataSpec.key != null ? dataSpec.key : uri.toString();
我可以生成相同的密钥,这要归功于一些uri
的参数,这些参数等于为同一首歌检索的每个网址。这个解决方案解决了我的问题,但对于每种可能的情况都不是那么通用和可利用。
然后按照this comment:
中的说明使用CacheDataSource
private DataSource.Factory buildDataSourceFactory(final boolean useBandwidthMeter) {
return new DataSource.Factory() {
@Override
public DataSource createDataSource() {
LeastRecentlyUsedCacheEvictor evictor = new LeastRecentlyUsedCacheEvictor(100 * 1024 * 1024);
SimpleCache simpleCache = new SimpleCache(new File(getCacheDir(), "media_cache"), evictor);
return new CacheDataSource(
simpleCache,
buildMyDataSourceFactory(useBandwidthMeter).createDataSource(),
CacheDataSource.FLAG_BLOCK_ON_CACHE,
10 * 1024 * 1024
);
}
};
}
private DefaultDataSource.Factory buildMyDataSourceFactory(boolean useBandwidthMeter) {
return new DefaultDataSourceFactory(PlayerActivity.this, userAgent, useBandwidthMeter ? BANDWIDTH_METER : null);
}
答案 0 :(得分:2)
自ExoPlayer 2.10.0起,它已经添加了ProgressiveMediaSource
类,该类代替了ExtractorMediaSource
(已弃用)。
在创建带有Factory
类的ProgressiveMediaSource时,可以调用方法setCustomCacheKey(String)
。
它完全可以满足我的需求!
答案 1 :(得分:0)
这是解决方案(不确定在exoplayer 2.10.2上运行,对于较早的版本不确定)。 要创建您的源:
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(context,
Util.getUserAgent(context, getString(R.string.app_name)));
CacheDataSourceFactory cacheDataSourceFactory =
new CacheDataSourceFactory(downloadUtil.getDownloadCache(context), dataSourceFactory,
new FileDataSourceFactory(),
new CacheDataSinkFactory(downloadUtil.getDownloadCache(context), CacheDataSink.DEFAULT_FRAGMENT_SIZE),
0,null,new CacheKeyProvider());
ProgressiveMediaSource mediaSource = new ProgressiveMediaSource.Factory(cacheDataSourceFactory).createMediaSource(your_uri);
其中CacheKeyProvider()
是您自己的CacheKeyFactory
的实现。此类将定义将用作键的内容。我的看起来像这样:
public class CacheKeyProvider implements CacheKeyFactory
{
@Override
public String buildCacheKey(DataSpec dataSpec) {
if (dataSpec.key!=null) return dataSpec.key;
else return generate_key(dataSpec.uri);
}
private String generate_key(Uri uri){
String string = uri.toString();
String[] parts = string.split("\\?");
String part1 = parts[0];
String part2 = parts[1];
return part1;
}
}
在我的情况下,我要检索的是我的网址更改时没有更改的内容,并将其用作键。