From 6d24095c5c2716aa4f8af87d00692df39229ac9b Mon Sep 17 00:00:00 2001 From: dkanada Date: Sun, 18 Oct 2020 01:37:36 +0900 Subject: [PATCH] store playback requests when exoplayer is loading --- .../helper/MusicProgressViewUpdateHelper.java | 6 -- .../gramophone/service/MultiPlayer.java | 73 ++++++++++++------- .../gramophone/service/MusicService.java | 24 +++--- .../gramophone/service/playback/Playback.java | 2 +- 4 files changed, 56 insertions(+), 49 deletions(-) diff --git a/app/src/main/java/com/dkanada/gramophone/helper/MusicProgressViewUpdateHelper.java b/app/src/main/java/com/dkanada/gramophone/helper/MusicProgressViewUpdateHelper.java index b2c7335d..ecdf1ffb 100644 --- a/app/src/main/java/com/dkanada/gramophone/helper/MusicProgressViewUpdateHelper.java +++ b/app/src/main/java/com/dkanada/gramophone/helper/MusicProgressViewUpdateHelper.java @@ -29,12 +29,6 @@ public class MusicProgressViewUpdateHelper extends Handler { this.intervalPaused = UPDATE_INTERVAL_PAUSED; } - public MusicProgressViewUpdateHelper(Callback callback, int intervalPlaying, int intervalPaused) { - this.callback = callback; - this.intervalPlaying = intervalPlaying; - this.intervalPaused = intervalPaused; - } - @Override public void handleMessage(@NonNull Message msg) { super.handleMessage(msg); 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 4c9434f2..264abf89 100644 --- a/app/src/main/java/com/dkanada/gramophone/service/MultiPlayer.java +++ b/app/src/main/java/com/dkanada/gramophone/service/MultiPlayer.java @@ -34,6 +34,7 @@ import java.io.File; import okhttp3.Call; import okhttp3.Callback; +import okhttp3.Dispatcher; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; @@ -42,9 +43,9 @@ import okhttp3.internal.annotations.EverythingIsNonNull; public class MultiPlayer implements Playback { public static final String TAG = MultiPlayer.class.getSimpleName(); - private Context context; + private final Context context; + private final OkHttpClient httpClient; - private OkHttpClient httpClient; private SimpleExoPlayer exoPlayer; private ConcatenatingMediaSource mediaSource; @@ -55,7 +56,9 @@ public class MultiPlayer implements Playback { private boolean isReady = false; private boolean isPlaying = false; - private boolean isNew = false; + + private boolean requestPlay = false; + private int requestProgress = 0; private ExoPlayer.EventListener eventListener = new ExoPlayer.EventListener() { @Override @@ -72,6 +75,20 @@ public class MultiPlayer implements Playback { public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { Log.i(TAG, "onPlayerStateChanged playWhenReady: " + playWhenReady); Log.i(TAG, "onPlayerStateChanged playbackState: " + playbackState); + + if (callbacks == null) return; + if (requestProgress != 0 && playbackState == Player.STATE_READY) { + exoPlayer.seekTo(requestProgress); + + requestProgress = 0; + } + + if (exoPlayer.isPlaying() || requestPlay && playbackState == ExoPlayer.STATE_READY) { + requestPlay = false; + + exoPlayer.setPlayWhenReady(true); + callbacks.onTrackStarted(); + } } @Override @@ -81,7 +98,7 @@ public class MultiPlayer implements Playback { if (windowIndex == 1) { mediaSource.removeMediaSource(0); - if (mediaSource.getSize() != 0) { + if (exoPlayer.isPlaying()) { // there are still songs left in the queue callbacks.onTrackWentToNext(); } else { @@ -105,15 +122,22 @@ public class MultiPlayer implements Playback { } }; - public MultiPlayer(final Context context) { + public MultiPlayer(Context context) { this.context = context; - httpClient = new OkHttpClient(); + Dispatcher dispatcher = new Dispatcher(); + dispatcher.setMaxRequests(1); + + httpClient = new OkHttpClient.Builder().dispatcher(dispatcher).build(); if (exoPlayer != null) exoPlayer.release(); exoPlayer = new SimpleExoPlayer.Builder(context).build(); mediaSource = new ConcatenatingMediaSource(); + exoPlayer.addListener(eventListener); + exoPlayer.prepare(mediaSource); + exoPlayer.setRepeatMode(Player.REPEAT_MODE_OFF); + if (simpleCache != null) simpleCache.release(); LeastRecentlyUsedCacheEvictor recentlyUsedCache = new LeastRecentlyUsedCacheEvictor(Long.MAX_VALUE); ExoDatabaseProvider databaseProvider = new ExoDatabaseProvider(context); @@ -126,11 +150,6 @@ public class MultiPlayer implements Playback { @Override public void setDataSource(Song song) { isReady = false; - if (context == null) { - return; - } - - isNew = true; mediaSource = new ConcatenatingMediaSource(); exoPlayer.addListener(eventListener); @@ -139,27 +158,22 @@ public class MultiPlayer implements Playback { // queue and other information is currently handled outside exoplayer exoPlayer.setRepeatMode(Player.REPEAT_MODE_OFF); - appendDataSource(MusicUtil.getSongFileUri(song), 0); - isReady = true; + appendDataSource(MusicUtil.getSongFileUri(song)); } @Override 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); } if (mediaSource.getSize() != 2) { - appendDataSource(path, 1); + appendDataSource(path); } } - private void appendDataSource(String path, int position) { + private void appendDataSource(String path) { Uri uri = Uri.parse(path); httpClient.newCall(new Request.Builder().url(path).head().build()).enqueue(new Callback() { @@ -185,8 +199,8 @@ public class MultiPlayer implements Playback { .createMediaSource(uri); } - mediaSource.addMediaSource(Math.min(mediaSource.getSize(), position), source); - if (position == 0) start(); + mediaSource.addMediaSource(source); + isReady = true; } }); } @@ -208,19 +222,19 @@ public class MultiPlayer implements Playback { } @Override - public boolean isInitialized() { + public boolean isReady() { return isReady; } @Override public void start() { + if (!isReady) { + requestPlay = true; + return; + } + isPlaying = true; exoPlayer.setPlayWhenReady(true); - - if (isNew) { - callbacks.onTrackStarted(); - isNew = false; - } } @Override @@ -256,6 +270,11 @@ public class MultiPlayer implements Playback { @Override public void setProgress(int position) { + if (!isReady) { + requestProgress = position; + return; + } + exoPlayer.seekTo(position); } 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 e6e5bf34..a3ab61e0 100644 --- a/app/src/main/java/com/dkanada/gramophone/service/MusicService.java +++ b/app/src/main/java/com/dkanada/gramophone/service/MusicService.java @@ -409,7 +409,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP this.playingQueue = restoredQueue; position = restoredPosition; - openCurrent(true); + openCurrent(); if (restoredPositionInTrack > 0) seek(restoredPositionInTrack); @@ -458,25 +458,20 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP synchronized (this) { this.position = position; - openCurrent(false); + openCurrent(); + playback.start(); notifyChange(META_CHANGED); notHandledMetaChangedForCurrentTrack = false; } } - private void openCurrent(boolean queue) { + private void openCurrent() { synchronized (this) { // current song will be null when queue is cleared if (getCurrentSong() == null) return; - if (queue) { - // restore queue from database - playback.queueDataSource(getCurrentSong()); - } else { - // set current song and start playback - playback.setDataSource(getCurrentSong()); - } + playback.setDataSource(getCurrentSong()); } } @@ -784,7 +779,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP synchronized (this) { if (requestFocus()) { if (!playback.isPlaying()) { - if (!playback.isInitialized()) { + if (!playback.isReady()) { playSongAt(getPosition()); } else { playback.start(); @@ -945,10 +940,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP case PLAY_STATE_CHANGED: updateNotification(); updateMediaSessionPlaybackState(); - final boolean isPlaying = isPlaying(); - if (!isPlaying && getSongProgressMillis() > 0) { - saveProgress(); - } + if (!isPlaying()) saveProgress(); break; case META_CHANGED: updateNotification(); @@ -1003,6 +995,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP @Override public void onTrackStarted() { + progressHandler.sendEmptyMessage(PLAY_SONG); notifyChange(PLAY_STATE_CHANGED); prepareNext(); } @@ -1244,6 +1237,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP startInfo.setCanSeek(true); startInfo.setIsPaused(false); + App.getApiClient().ensureWebSocket(); App.getApiClient().ReportPlaybackStartAsync(startInfo, new EmptyResponse()); } 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 9b643360..09bafb93 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 @@ -15,7 +15,7 @@ public interface Playback { void stop(); - boolean isInitialized(); + boolean isReady(); boolean isPlaying();