无法打开虚拟数据源:Android ExoPlayer
DummyDataSource cannot be opened : Android ExoPlayer
我正在尝试从 URL 流式传输视频并同时将它们保存在缓存中。
我正在使用 Android Studio 的 DataBaseInspector 检查缓存,它似乎可以正常工作,但并非一直有效。
有时我在尝试播放视频时遇到此错误:
2021-01-21 10:27:12.956 26648-28069/test.com.test E/ExoPlayerImplInternal: Playback error
com.google.android.exoplayer2.ExoPlaybackException: Source error
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:554)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:238)
at android.os.HandlerThread.run(HandlerThread.java:67)
Caused by: java.io.IOException: DummyDataSource cannot be opened
at com.google.android.exoplayer2.upstream.DummyDataSource.open(DummyDataSource.java:39)
at com.google.android.exoplayer2.upstream.cache.CacheDataSource.openNextSource(CacheDataSource.java:764)
at com.google.android.exoplayer2.upstream.cache.CacheDataSource.open(CacheDataSource.java:579)
at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:84)
at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:1017)
at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:415)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
读取错误我们可以看到一个 IOException,所以我检查了缓存中的路径,有时它再次工作......我在 exoplayer 内部数据库中注册的键是 URL(我让 exoplayer 做所有的工作,但之后我检查了自己)。
这是我的代码:
@Inject
public VideoCacheManager(@NonNull SimpleCache simpleCache, @ActivityContext Context context) {
this.simpleCache = simpleCache;
this.context = context;
cacheDataSource = new CacheDataSource.Factory();
cacheDataSource.setCache(simpleCache);
Log.d(TAG, "VideoCacheManager: cache size left : " + simpleCache.getCacheSpace());
cacheDataSource.setEventListener(new CacheDataSource.EventListener() {
@Override
public void onCachedBytesRead(long cacheSizeBytes, long cachedBytesRead) {
Log.d(TAG, "onCachedBytesRead: cached bytes read : " + cachedBytesRead);
}
@Override
public void onCacheIgnored(int reason) {
Log.d(TAG, "onCacheIgnored: cache ignored : " + reason);
}
});
}
public MediaSource buildMediaSource(MediaItem mediaItem) {
return new ProgressiveMediaSource.Factory(cacheDataSource).createMediaSource(mediaItem);
}
而 SimpleCache 是一个注入了 Hilt 的单例:
@Provides
@Singleton
public static SimpleCache simpleCache(@ApplicationContext Context context) {
return new SimpleCache(context.getApplicationContext().getCacheDir(), leastRecentlyUsedCacheEvictor(), exoDatabaseProvider(context));
}
@Provides
@Singleton
public static LeastRecentlyUsedCacheEvictor leastRecentlyUsedCacheEvictor() {
return new LeastRecentlyUsedCacheEvictor(exoPlayerCacheSize());
}
@Provides
@Singleton
public static Long exoPlayerCacheSize() {
return (long) (500 * 1024 * 1024);
}
@Provides
@Singleton
public static ExoDatabaseProvider exoDatabaseProvider(@ApplicationContext Context context) {
return new ExoDatabaseProvider(context);
}
在我的 ExoPlayer class 中,我有一个简单的方法:
public void prepare(MediaItem mediaItem) {
lastMediaItem = mediaItem;
Log.d(TAG, "prepare: media item : " + mediaItem.playbackProperties);
MediaSource mediaSource = videoCacheManager.buildMediaSource(mediaItem);
Log.d(TAG, "prepare: source : " + mediaSource.getInitialTimeline());
simpleExoPlayer.prepare(mediaSource);
}
我已经阅读了足够多的关于 exoplayer 的内容,如果视频不存在,它应该在第一个流式传输会话期间将视频下载到缓存中......那么这个错误是什么以及如何修复它?
我第一次使用此代码时它起作用了,然后我清除了所有内容并重试但没有成功。
好吧,我一定是错误地删除了 DefaultDataSourceFactory
并且忘记将 UpstreamDataSource
设置回 CacheDataSource
实例。
现在一切正常,希望这对其他人有帮助。
在代码中我们需要添加:
DefaultDataSourceFactory defaultDataSourceFactory = new DefaultDataSourceFactory(context, Util.getUserAgent(context, context.getString(R.string.app_name)));
cacheDataSource.setUpstreamDataSourceFactory(defaultDataSourceFactory);
虽然是在 2018 年使用 exoplayer 2.8 版,但我也从 ExoPlayer
中学到了很多东西 video。
我目前使用的是最新的,即2.12.3。
我正在尝试从 URL 流式传输视频并同时将它们保存在缓存中。
我正在使用 Android Studio 的 DataBaseInspector 检查缓存,它似乎可以正常工作,但并非一直有效。
有时我在尝试播放视频时遇到此错误:
2021-01-21 10:27:12.956 26648-28069/test.com.test E/ExoPlayerImplInternal: Playback error
com.google.android.exoplayer2.ExoPlaybackException: Source error
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:554)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:238)
at android.os.HandlerThread.run(HandlerThread.java:67)
Caused by: java.io.IOException: DummyDataSource cannot be opened
at com.google.android.exoplayer2.upstream.DummyDataSource.open(DummyDataSource.java:39)
at com.google.android.exoplayer2.upstream.cache.CacheDataSource.openNextSource(CacheDataSource.java:764)
at com.google.android.exoplayer2.upstream.cache.CacheDataSource.open(CacheDataSource.java:579)
at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:84)
at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:1017)
at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:415)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
读取错误我们可以看到一个 IOException,所以我检查了缓存中的路径,有时它再次工作......我在 exoplayer 内部数据库中注册的键是 URL(我让 exoplayer 做所有的工作,但之后我检查了自己)。
这是我的代码:
@Inject
public VideoCacheManager(@NonNull SimpleCache simpleCache, @ActivityContext Context context) {
this.simpleCache = simpleCache;
this.context = context;
cacheDataSource = new CacheDataSource.Factory();
cacheDataSource.setCache(simpleCache);
Log.d(TAG, "VideoCacheManager: cache size left : " + simpleCache.getCacheSpace());
cacheDataSource.setEventListener(new CacheDataSource.EventListener() {
@Override
public void onCachedBytesRead(long cacheSizeBytes, long cachedBytesRead) {
Log.d(TAG, "onCachedBytesRead: cached bytes read : " + cachedBytesRead);
}
@Override
public void onCacheIgnored(int reason) {
Log.d(TAG, "onCacheIgnored: cache ignored : " + reason);
}
});
}
public MediaSource buildMediaSource(MediaItem mediaItem) {
return new ProgressiveMediaSource.Factory(cacheDataSource).createMediaSource(mediaItem);
}
而 SimpleCache 是一个注入了 Hilt 的单例:
@Provides
@Singleton
public static SimpleCache simpleCache(@ApplicationContext Context context) {
return new SimpleCache(context.getApplicationContext().getCacheDir(), leastRecentlyUsedCacheEvictor(), exoDatabaseProvider(context));
}
@Provides
@Singleton
public static LeastRecentlyUsedCacheEvictor leastRecentlyUsedCacheEvictor() {
return new LeastRecentlyUsedCacheEvictor(exoPlayerCacheSize());
}
@Provides
@Singleton
public static Long exoPlayerCacheSize() {
return (long) (500 * 1024 * 1024);
}
@Provides
@Singleton
public static ExoDatabaseProvider exoDatabaseProvider(@ApplicationContext Context context) {
return new ExoDatabaseProvider(context);
}
在我的 ExoPlayer class 中,我有一个简单的方法:
public void prepare(MediaItem mediaItem) {
lastMediaItem = mediaItem;
Log.d(TAG, "prepare: media item : " + mediaItem.playbackProperties);
MediaSource mediaSource = videoCacheManager.buildMediaSource(mediaItem);
Log.d(TAG, "prepare: source : " + mediaSource.getInitialTimeline());
simpleExoPlayer.prepare(mediaSource);
}
我已经阅读了足够多的关于 exoplayer 的内容,如果视频不存在,它应该在第一个流式传输会话期间将视频下载到缓存中......那么这个错误是什么以及如何修复它?
我第一次使用此代码时它起作用了,然后我清除了所有内容并重试但没有成功。
好吧,我一定是错误地删除了 DefaultDataSourceFactory
并且忘记将 UpstreamDataSource
设置回 CacheDataSource
实例。
现在一切正常,希望这对其他人有帮助。
在代码中我们需要添加:
DefaultDataSourceFactory defaultDataSourceFactory = new DefaultDataSourceFactory(context, Util.getUserAgent(context, context.getString(R.string.app_name)));
cacheDataSource.setUpstreamDataSourceFactory(defaultDataSourceFactory);
虽然是在 2018 年使用 exoplayer 2.8 版,但我也从 ExoPlayer
中学到了很多东西 video。
我目前使用的是最新的,即2.12.3。