diff --git a/app/src/main/java/com/dkanada/gramophone/helper/MusicPlayerRemote.java b/app/src/main/java/com/dkanada/gramophone/helper/MusicPlayerRemote.java index 292df944..cfb31b50 100644 --- a/app/src/main/java/com/dkanada/gramophone/helper/MusicPlayerRemote.java +++ b/app/src/main/java/com/dkanada/gramophone/helper/MusicPlayerRemote.java @@ -137,7 +137,7 @@ public class MusicPlayerRemote { } public static boolean isBuffering() { - return musicService != null && musicService.isBuffering(); + return musicService != null && musicService.isLoading(); } public static void resumePlaying() { 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 24c63c4f..03ba6b9d 100644 --- a/app/src/main/java/com/dkanada/gramophone/service/MultiPlayer.java +++ b/app/src/main/java/com/dkanada/gramophone/service/MultiPlayer.java @@ -37,28 +37,30 @@ public class MultiPlayer implements Playback { private PlaybackCallbacks callbacks; private final ExoPlayer.EventListener eventListener = new ExoPlayer.EventListener() { - @Override - public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { - Log.i(TAG, String.format("onPlayerStateChanged: %b %d", playWhenReady, playbackState)); - if (callbacks != null) { - callbacks.onPlayerStateChanged(playWhenReady, playbackState); - } + public void onIsLoadingChanged(boolean isLoading) { + Log.i(TAG, String.format("onIsLoadingChanged: %b", isLoading)); } @Override - public void onPositionDiscontinuity(int reason) { - Log.i(TAG, String.format("onPositionDiscontinuity: %d", reason)); - int windowIndex = exoPlayer.getCurrentWindowIndex(); + public void onPlayWhenReadyChanged(boolean playWhenReady, int reason) { + Log.i(TAG, String.format("onPlayWhenReadyChanged: %b %d", playWhenReady, reason)); + if (callbacks != null) callbacks.onReadyChanged(playWhenReady, reason); + } - if (windowIndex == 1) { + @Override + public void onPlaybackStateChanged(int state) { + Log.i(TAG, String.format("onPlaybackStateChanged: %d", state)); + if (callbacks != null) callbacks.onStateChanged(state); + } + + @Override + public void onMediaItemTransition(MediaItem mediaItem, int reason) { + Log.i(TAG, String.format("onMediaItemTransition: %s %d", mediaItem, reason)); + + if (exoPlayer.getMediaItemCount() > 1) { exoPlayer.removeMediaItem(0); - if (exoPlayer.isPlaying()) { - // there are still songs left in the queue - callbacks.onTrackWentToNext(); - } else { - callbacks.onTrackEnded(); - } + callbacks.onTrackChanged(reason); } } @@ -88,6 +90,13 @@ public class MultiPlayer implements Playback { @Override public void setDataSource(Song song) { + String uri = MusicUtil.getSongFileUri(song); + MediaItem mediaItem = exoPlayer.getCurrentMediaItem(); + + if (mediaItem != null && mediaItem.playbackProperties.uri.toString().equals(uri)) { + return; + } + exoPlayer.clearMediaItems(); appendDataSource(MusicUtil.getSongFileUri(song)); exoPlayer.seekTo(0, 0); @@ -127,7 +136,7 @@ public class MultiPlayer implements Playback { @Override public boolean isReady() { - return true; + return exoPlayer.getPlayWhenReady(); } @Override @@ -136,7 +145,7 @@ public class MultiPlayer implements Playback { } @Override - public boolean isBuffering() { + public boolean isLoading() { return exoPlayer.getPlaybackState() == Player.STATE_BUFFERING; } 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 57027e31..ee773726 100644 --- a/app/src/main/java/com/dkanada/gramophone/service/MusicService.java +++ b/app/src/main/java/com/dkanada/gramophone/service/MusicService.java @@ -51,7 +51,6 @@ import com.dkanada.gramophone.util.Util; import com.dkanada.gramophone.widgets.AppWidgetAlbum; import com.dkanada.gramophone.widgets.AppWidgetCard; import com.dkanada.gramophone.widgets.AppWidgetClassic; -import com.google.android.exoplayer2.Player; import org.jellyfin.apiclient.interaction.EmptyResponse; import org.jellyfin.apiclient.interaction.Response; @@ -69,6 +68,9 @@ import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import static com.google.android.exoplayer2.Player.MEDIA_ITEM_TRANSITION_REASON_AUTO; +import static com.google.android.exoplayer2.Player.PLAY_WHEN_READY_CHANGE_REASON_END_OF_MEDIA_ITEM; + public class MusicService extends Service implements SharedPreferences.OnSharedPreferenceChangeListener, Playback.PlaybackCallbacks { public static final String PACKAGE_NAME = "com.dkanada.gramophone"; @@ -483,8 +485,8 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP return playback != null && playback.isPlaying(); } - public boolean isBuffering() { - return playback != null && playback.isBuffering(); + public boolean isLoading() { + return playback != null && playback.isLoading(); } public int getPosition() { @@ -1036,26 +1038,29 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP } @Override - public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { + public void onStateChanged(int state) { notifyChange(STATE_CHANGED); - if (playWhenReady && playbackState == Player.STATE_READY) { + } + + @Override + public void onReadyChanged(boolean ready, int reason) { + notifyChange(STATE_CHANGED); + + if (ready) { progressHandler.sendEmptyMessage(TRACK_STARTED); prepareNext(); + } else if (reason == PLAY_WHEN_READY_CHANGE_REASON_END_OF_MEDIA_ITEM) { + progressHandler.sendEmptyMessage(TRACK_ENDED); + acquireWakeLock(30000); } } @Override - public void onTrackWentToNext() { - playerHandler.sendEmptyMessage(TRACK_CHANGED); - progressHandler.sendEmptyMessage(TRACK_CHANGED); - } - - @Override - public void onTrackEnded() { - playerHandler.sendEmptyMessage(TRACK_ENDED); - progressHandler.sendEmptyMessage(TRACK_ENDED); - - acquireWakeLock(30000); + public void onTrackChanged(int reason) { + if (reason == MEDIA_ITEM_TRANSITION_REASON_AUTO) { + playerHandler.sendEmptyMessage(TRACK_CHANGED); + progressHandler.sendEmptyMessage(TRACK_CHANGED); + } } private static final class PlaybackHandler extends Handler { @@ -1292,7 +1297,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP info.setPositionTicks(progress * 10000); if (task != null) task.cancel(true); - executorService.shutdownNow(); + if (executorService != null) executorService.shutdownNow(); } } } 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 c34fe682..dddc1089 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 @@ -13,7 +13,7 @@ public interface Playback { boolean isPlaying(); - boolean isBuffering(); + boolean isLoading(); void start(); @@ -32,10 +32,10 @@ public interface Playback { int getVolume(); interface PlaybackCallbacks { - void onPlayerStateChanged(boolean playWhenReady, int playbackState); + void onStateChanged(int state); - void onTrackWentToNext(); + void onReadyChanged(boolean ready, int reason); - void onTrackEnded(); + void onTrackChanged(int reason); } }