ExoPlayer,概括了SimpleCache的行为

时间:2017-02-06 17:39:07

标签: android exoplayer

我使用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);
}

2 个答案:

答案 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;
    }
}

在我的情况下,我要检索的是我的网址更改时没有更改的内容,并将其用作键。