From d7b1221199582aef8b0a11705ac87e94c1e63f85 Mon Sep 17 00:00:00 2001 From: dkanada Date: Wed, 7 Oct 2020 12:18:42 +0900 Subject: [PATCH] add cache for recent songs --- .../gramophone/service/MultiPlayer.java | 46 ++++++++++++++----- .../gramophone/service/MusicService.java | 6 +-- .../gramophone/service/playback/Playback.java | 8 ++-- .../ui/activities/SettingsActivity.java | 2 +- .../xml/{pref_images.xml => pref_cache.xml} | 0 5 files changed, 44 insertions(+), 18 deletions(-) rename app/src/main/res/xml/{pref_images.xml => pref_cache.xml} (100%) diff --git a/app/src/main/java/com/dkanada/gramophone/service/MultiPlayer.java b/app/src/main/java/com/dkanada/gramophone/service/MultiPlayer.java index 6dfd05ee..4a3e9793 100644 --- a/app/src/main/java/com/dkanada/gramophone/service/MultiPlayer.java +++ b/app/src/main/java/com/dkanada/gramophone/service/MultiPlayer.java @@ -2,14 +2,14 @@ package com.dkanada.gramophone.service; import android.content.Context; import android.net.Uri; +import android.os.Environment; import android.util.Log; import android.widget.Toast; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - import com.dkanada.gramophone.R; +import com.dkanada.gramophone.model.Song; import com.dkanada.gramophone.service.playback.Playback; +import com.dkanada.gramophone.util.MusicUtil; import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Player; @@ -21,10 +21,15 @@ import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.hls.HlsMediaSource; import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.upstream.DataSource; -import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory; -import com.google.android.exoplayer2.util.Util; +import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; +import com.google.android.exoplayer2.upstream.FileDataSource; +import com.google.android.exoplayer2.upstream.cache.CacheDataSink; +import com.google.android.exoplayer2.upstream.cache.CacheDataSource; +import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor; +import com.google.android.exoplayer2.upstream.cache.SimpleCache; import java.io.IOException; +import java.io.File; import okhttp3.Call; import okhttp3.Callback; @@ -43,6 +48,8 @@ public class MultiPlayer implements Playback { private ConcatenatingMediaSource mediaSource; private Playback.PlaybackCallbacks callbacks; + private DataSource.Factory dataSource; + private SimpleCache simpleCache; private boolean isReady = false; private boolean isPlaying = false; @@ -83,7 +90,7 @@ public class MultiPlayer implements Playback { @Override public void onPlayerError(ExoPlaybackException error) { - Log.i(TAG, "onPlaybackError: " + error.getMessage()); + Log.i(TAG, "onPlayerError: " + error.getMessage()); if (context != null) { Toast.makeText(context, context.getResources().getString(R.string.unplayable_file), Toast.LENGTH_SHORT).show(); } @@ -98,10 +105,16 @@ public class MultiPlayer implements Playback { httpClient = new OkHttpClient(); exoPlayer = new SimpleExoPlayer.Builder(context).build(); mediaSource = new ConcatenatingMediaSource(); + + if (dataSource != null) return; + dataSource = buildDataSourceFactory(); + if (simpleCache != null) return; + LeastRecentlyUsedCacheEvictor evictor = new LeastRecentlyUsedCacheEvictor(Long.MAX_VALUE); + simpleCache = new SimpleCache(new File(Environment.getExternalStorageDirectory() + "/Gelli/cache"), evictor); } @Override - public void setDataSource(@NonNull final String path) { + public void setDataSource(Song song) { isReady = false; if (context == null) { return; @@ -116,16 +129,17 @@ public class MultiPlayer implements Playback { // queue and other information is currently handled outside exoplayer exoPlayer.setRepeatMode(Player.REPEAT_MODE_OFF); - appendDataSource(path, 0); + appendDataSource(MusicUtil.getSongFileUri(song), 0); isReady = true; } @Override - public void queueDataSource(@Nullable final String path) { + public void queueDataSource(Song song) { if (context == null) { return; } + String path = MusicUtil.getSongFileUri(song); if (mediaSource.getSize() == 2 && mediaSource.getMediaSource(1).getTag() != path) { mediaSource.removeMediaSource(1); } @@ -138,7 +152,6 @@ public class MultiPlayer implements Playback { private void appendDataSource(String path, int position) { Uri uri = Uri.parse(path); - DataSource.Factory dataSource = new DefaultHttpDataSourceFactory(Util.getUserAgent(context, this.getClass().getName())); httpClient.newCall(new Request.Builder().url(path).head().build()).enqueue(new Callback() { @Override @EverythingIsNonNull @@ -173,8 +186,19 @@ public class MultiPlayer implements Playback { }); } + private DataSource.Factory buildDataSourceFactory() { + return () -> new CacheDataSource( + simpleCache, + new DefaultDataSourceFactory(context, context.getPackageName(), null).createDataSource(), + new FileDataSource(), + new CacheDataSink(simpleCache, 10 * 1024 * 1024), + CacheDataSource.FLAG_BLOCK_ON_CACHE, + null + ); + } + @Override - public void setCallbacks(@Nullable Playback.PlaybackCallbacks callbacks) { + public void setCallbacks(Playback.PlaybackCallbacks callbacks) { this.callbacks = callbacks; } diff --git a/app/src/main/java/com/dkanada/gramophone/service/MusicService.java b/app/src/main/java/com/dkanada/gramophone/service/MusicService.java index 9d139f94..34deef82 100644 --- a/app/src/main/java/com/dkanada/gramophone/service/MusicService.java +++ b/app/src/main/java/com/dkanada/gramophone/service/MusicService.java @@ -467,10 +467,10 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP if (queue) { // restore queue from database - playback.queueDataSource(MusicUtil.getSongFileUri(getCurrentSong())); + playback.queueDataSource(getCurrentSong()); } else { // set current song and start playback - playback.setDataSource(MusicUtil.getSongFileUri(getCurrentSong())); + playback.setDataSource(getCurrentSong()); } } } @@ -483,7 +483,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP private void prepareNextImpl() { synchronized (this) { nextPosition = getNextPosition(false); - playback.queueDataSource(MusicUtil.getSongFileUri(getSongAt(nextPosition))); + playback.queueDataSource(getSongAt(nextPosition)); } } diff --git a/app/src/main/java/com/dkanada/gramophone/service/playback/Playback.java b/app/src/main/java/com/dkanada/gramophone/service/playback/Playback.java index cd8982b2..00d221db 100644 --- a/app/src/main/java/com/dkanada/gramophone/service/playback/Playback.java +++ b/app/src/main/java/com/dkanada/gramophone/service/playback/Playback.java @@ -1,9 +1,11 @@ package com.dkanada.gramophone.service.playback; -public interface Playback { - void setDataSource(String path); +import com.dkanada.gramophone.model.Song; - void queueDataSource(String path); +public interface Playback { + void setDataSource(Song song); + + void queueDataSource(Song song); void setCallbacks(PlaybackCallbacks callbacks); diff --git a/app/src/main/java/com/dkanada/gramophone/ui/activities/SettingsActivity.java b/app/src/main/java/com/dkanada/gramophone/ui/activities/SettingsActivity.java index 3ebe925e..0d6ed79c 100644 --- a/app/src/main/java/com/dkanada/gramophone/ui/activities/SettingsActivity.java +++ b/app/src/main/java/com/dkanada/gramophone/ui/activities/SettingsActivity.java @@ -121,7 +121,7 @@ public class SettingsActivity extends AbsBaseActivity implements ColorChooserDia addPreferencesFromResource(R.xml.pref_now_playing); addPreferencesFromResource(R.xml.pref_lock_screen); addPreferencesFromResource(R.xml.pref_playback); - addPreferencesFromResource(R.xml.pref_images); + addPreferencesFromResource(R.xml.pref_cache); } @Nullable diff --git a/app/src/main/res/xml/pref_images.xml b/app/src/main/res/xml/pref_cache.xml similarity index 100% rename from app/src/main/res/xml/pref_images.xml rename to app/src/main/res/xml/pref_cache.xml