使用exoplayer 2.8.1,在Android SDK版本19和23上进行测试。
我使用以下代码构建缓存和数据源工厂:
private static final long DEFAULT_MAX_CACHE_SIZE = 20*1024*1024L;
cacheEvictor = new LeastRecentlyUsedCacheEvictor(DEFAULT_MAX_CACHE_SIZE);
cache = new SimpleCache(
new File(context.getExternalCacheDir(), "exoplayer-cache"),
cacheEvictor);
uncachedDataSourceFactory = new OkHttpDataSourceFactory(
new OkHttpClient(),
"Android.ExoPlayer",
null);
dataSourceFactory =
new CacheDataSourceFactory(
cache,
uncachedDataSourceFactory);
然后,我使用以下代码预先标准化标准HTTP音频内容:
new Thread (new Runnable () {
public void run() {
try {
CacheUtil.cache(
new DataSpec(uri, DataSpec.FLAG_ALLOW_CACHING_UNKNOWN_LENGTH | DataSpec.FLAG_ALLOW_GZIP),
cache,
uncachedDataSourceFactory.createDataSource(),
null,
null);
} catch (IOException e) {
callback.invoke(false, "Error: " + e.getMessage());
} catch (InterruptedException e) {
callback.invoke(false, "Download interrupted");
}
callback.invoke(true);
}
}).start();
使用true调用回调,因此此过程似乎正在完成。在此之后,我断开网络并尝试播放缓存的内容:
DefaultTrackSelector trackSelector = new DefaultTrackSelector();
player = ExoPlayerFactory.newSimpleInstance(context, trackSelector);
mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory)
.setContinueLoadingCheckIntervalBytes(128 * 1024) // check whether to load more every 128KB
.createMediaSource(uri);
mediaSource.addEventListener(handler, new DefaultMediaSourceEventListener() {
@Override
public void onLoadError(int windowIndex, @Nullable MediaSource.MediaPeriodId mediaPeriodId, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData, IOException error, boolean wasCanceled) {
Log.i(LOG_TAG, "media load error for " + uri + ": " + error);
}
});
player.addListener(new Player.DefaultEventListener() {
boolean preparing = true;
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState)
{
Log.i(LOG_TAG, "player " + uri + " state change " + playbackState + ", " + playWhenReady);
switch (playbackState) {
case Player.STATE_READY:
if (preparing) {
preparing = false;
callback.invoke(null, getInfo(player));
}
break;
case Player.STATE_ENDED:
player.seekTo(0);
emitMessageEvent(playerId, "ended", "playback completed");
if (playerAutoDestroy.get(playerId)) {
Log.d(LOG_TAG, "onPlayerStateChanged(STATE_ENDED): Autodestroying player...");
destroy(playerId);
}
break;
case Player.STATE_BUFFERING:
onLoadingChanged(true);
break;
}
}
@Override
public void onPlayerError(ExoPlaybackException error) {
Log.i(LOG_TAG, "Playback error for " + uri + ": " + error.getMessage(), error);
emitMessageEvent(playerId, "error", "Playback error: " + error.getMessage());
destroy(playerId);
}
});
player.prepare(mediaSource, true, true);
当我这样做时,我收到了几个媒体源错误,最后在我的日志中出现了播放错误:
06-02 11:20:52.839 32762-327/com.tackta.buxton I/ExoPlayerImpl: Init 93903d2 [ExoPlayerLib/2.8.1] [generic_x86, Android SDK built for x86, unknown, 23]
06-02 11:20:52.840 32762-327/com.tackta.buxton I/AudioPlayerModule: player http://clarkesworldmagazine.com/podpress_trac/feed/2043/0/clarkesworld_06_18_tem.mp3 state change 2, false
06-02 11:20:52.844 32762-32762/com.tackta.buxton I/AudioPlayerModule: media load error for http://clarkesworldmagazine.com/podpress_trac/feed/2043/0/clarkesworld_06_18_tem.mp3: com.google.android.exoplayer2.upstream.HttpDataSource$HttpDataSourceException: Unable to connect to http://clarkesworldmagazine.com/podpress_trac/feed/2043/0/clarkesworld_06_18_tem.mp3
06-02 11:20:52.844 32762-32762/com.tackta.buxton I/AudioPlayerModule: media load error for http://clarkesworldmagazine.com/podpress_trac/feed/2043/0/clarkesworld_06_18_tem.mp3: com.google.android.exoplayer2.upstream.HttpDataSource$HttpDataSourceException: Unable to connect to http://clarkesworldmagazine.com/podpress_trac/feed/2043/0/clarkesworld_06_18_tem.mp3
06-02 11:20:53.846 32762-32762/com.tackta.buxton I/AudioPlayerModule: media load error for http://clarkesworldmagazine.com/podpress_trac/feed/2043/0/clarkesworld_06_18_tem.mp3: com.google.android.exoplayer2.upstream.HttpDataSource$HttpDataSourceException: Unable to connect to http://clarkesworldmagazine.com/podpress_trac/feed/2043/0/clarkesworld_06_18_tem.mp3
06-02 11:20:55.848 32762-32762/com.tackta.buxton I/AudioPlayerModule: media load error for http://clarkesworldmagazine.com/podpress_trac/feed/2043/0/clarkesworld_06_18_tem.mp3: com.google.android.exoplayer2.upstream.HttpDataSource$HttpDataSourceException: Unable to connect to http://clarkesworldmagazine.com/podpress_trac/feed/2043/0/clarkesworld_06_18_tem.mp3
06-02 11:20:55.858 32762-407/com.tackta.buxton E/ExoPlayerImplInternal: Source error.
06-02 11:20:55.859 32762-327/com.tackta.buxton I/AudioPlayerModule: Playback error for http://clarkesworldmagazine.com/podpress_trac/feed/2043/0/clarkesworld_06_18_tem.mp3: null
06-02 11:20:55.863 32762-327/com.tackta.buxton I/ExoPlayerImpl: Release 93903d2 [ExoPlayerLib/2.8.1] [generic_x86, Android SDK built for x86, unknown, 23] [goog.exo.core, goog.exo.okhttp]
此代码是否应该从预加载的缓存中访问数据,或者是否有理由尝试联系网络服务器?有没有办法告诉它使用缓存而不试图联系服务器?