diff --git a/app/src/main/java/com/dkanada/gramophone/fragments/player/MiniPlayerFragment.java b/app/src/main/java/com/dkanada/gramophone/fragments/player/MiniPlayerFragment.java
index 994f86de..ecb8caf5 100644
--- a/app/src/main/java/com/dkanada/gramophone/fragments/player/MiniPlayerFragment.java
+++ b/app/src/main/java/com/dkanada/gramophone/fragments/player/MiniPlayerFragment.java
@@ -57,6 +57,7 @@ public class MiniPlayerFragment extends AbsMusicServiceFragment implements Music
setUpPlayPauseButton();
binding.progressBar.setProgressTintList(ColorStateList.valueOf(ThemeStore.accentColor(requireActivity())));
+ binding.progressBar.setIndeterminateTintList(ColorStateList.valueOf(ThemeStore.accentColor(requireActivity())));
}
private void setUpPlayPauseButton() {
@@ -89,6 +90,7 @@ public class MiniPlayerFragment extends AbsMusicServiceFragment implements Music
@Override
public void onUpdateProgressViews(int progress, int total) {
+ binding.progressBar.setIndeterminate(MusicPlayerRemote.isBuffering());
binding.progressBar.setMax(total);
binding.progressBar.setProgress(progress);
}
diff --git a/app/src/main/java/com/dkanada/gramophone/fragments/player/card/CardPlayerFragment.java b/app/src/main/java/com/dkanada/gramophone/fragments/player/card/CardPlayerFragment.java
index bf4e453a..02dde037 100644
--- a/app/src/main/java/com/dkanada/gramophone/fragments/player/card/CardPlayerFragment.java
+++ b/app/src/main/java/com/dkanada/gramophone/fragments/player/card/CardPlayerFragment.java
@@ -274,6 +274,7 @@ public class CardPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
public void onColorChanged(int color) {
animateColorChange(color);
playbackControlsFragment.setDark(ColorUtil.isColorLight(color));
+ playbackControlsFragment.updateBufferingIndicatorColor(color);
getCallbacks().onPaletteColorChanged();
}
diff --git a/app/src/main/java/com/dkanada/gramophone/fragments/player/card/CardPlayerPlaybackControlsFragment.java b/app/src/main/java/com/dkanada/gramophone/fragments/player/card/CardPlayerPlaybackControlsFragment.java
index 8e68037f..5bd29117 100644
--- a/app/src/main/java/com/dkanada/gramophone/fragments/player/card/CardPlayerPlaybackControlsFragment.java
+++ b/app/src/main/java/com/dkanada/gramophone/fragments/player/card/CardPlayerPlaybackControlsFragment.java
@@ -1,5 +1,6 @@
package com.dkanada.gramophone.fragments.player.card;
+import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.os.Bundle;
@@ -133,6 +134,11 @@ public class CardPlayerPlaybackControlsFragment extends AbsMusicServiceFragment
}
}
+ public void updateBufferingIndicatorColor(int color) {
+ binding.playerBufferingIndicator.setProgressBackgroundTintList(ColorStateList.valueOf(getResources().getColor(android.R.color.transparent)));
+ binding.playerBufferingIndicator.setIndeterminateTintList(ColorStateList.valueOf(color));
+ }
+
private void setUpMusicControllers() {
setUpPlayPauseFab();
setUpPrevNext();
@@ -227,6 +233,8 @@ public class CardPlayerPlaybackControlsFragment extends AbsMusicServiceFragment
@Override
public void onUpdateProgressViews(int progress, int total) {
+ binding.playerBufferingIndicator.setVisibility(MusicPlayerRemote.isBuffering() ? View.VISIBLE : View.GONE);
+
binding.playerProgressSlider.setMax(total);
binding.playerProgressSlider.setProgress(progress);
diff --git a/app/src/main/java/com/dkanada/gramophone/fragments/player/flat/FlatPlayerFragment.java b/app/src/main/java/com/dkanada/gramophone/fragments/player/flat/FlatPlayerFragment.java
index 1262d955..a5432c94 100644
--- a/app/src/main/java/com/dkanada/gramophone/fragments/player/flat/FlatPlayerFragment.java
+++ b/app/src/main/java/com/dkanada/gramophone/fragments/player/flat/FlatPlayerFragment.java
@@ -277,6 +277,7 @@ public class FlatPlayerFragment extends AbsPlayerFragment implements PlayerAlbum
public void onColorChanged(int color) {
animateColorChange(color);
playbackControlsFragment.setDark(ColorUtil.isColorLight(color));
+ playbackControlsFragment.updateBufferingIndicatorColor(color);
getCallbacks().onPaletteColorChanged();
}
diff --git a/app/src/main/java/com/dkanada/gramophone/fragments/player/flat/FlatPlayerPlaybackControlsFragment.java b/app/src/main/java/com/dkanada/gramophone/fragments/player/flat/FlatPlayerPlaybackControlsFragment.java
index c9865984..de8f32c3 100644
--- a/app/src/main/java/com/dkanada/gramophone/fragments/player/flat/FlatPlayerPlaybackControlsFragment.java
+++ b/app/src/main/java/com/dkanada/gramophone/fragments/player/flat/FlatPlayerPlaybackControlsFragment.java
@@ -4,6 +4,7 @@ import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
+import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.os.Bundle;
@@ -138,6 +139,11 @@ public class FlatPlayerPlaybackControlsFragment extends AbsMusicServiceFragment
}
}
+ public void updateBufferingIndicatorColor(int color) {
+ binding.playerBufferingIndicator.setProgressBackgroundTintList(ColorStateList.valueOf(getResources().getColor(android.R.color.transparent)));
+ binding.playerBufferingIndicator.setIndeterminateTintList(ColorStateList.valueOf(color));
+ }
+
private void setUpMusicControllers() {
setUpPlayPauseButton();
setUpPrevNext();
@@ -282,6 +288,8 @@ public class FlatPlayerPlaybackControlsFragment extends AbsMusicServiceFragment
@Override
public void onUpdateProgressViews(int progress, int total) {
+ binding.playerBufferingIndicator.setVisibility(MusicPlayerRemote.isBuffering() ? View.VISIBLE : View.GONE);
+
binding.playerProgressSlider.setMax(total);
binding.playerProgressSlider.setProgress(progress);
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 f13938e0..cfb31b50 100644
--- a/app/src/main/java/com/dkanada/gramophone/helper/MusicPlayerRemote.java
+++ b/app/src/main/java/com/dkanada/gramophone/helper/MusicPlayerRemote.java
@@ -136,6 +136,10 @@ public class MusicPlayerRemote {
return musicService != null && musicService.isPlaying();
}
+ public static boolean isBuffering() {
+ return musicService != null && musicService.isLoading();
+ }
+
public static void resumePlaying() {
if (musicService != null) {
musicService.play();
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 70d84c20..d0f5d181 100644
--- a/app/src/main/java/com/dkanada/gramophone/service/MultiPlayer.java
+++ b/app/src/main/java/com/dkanada/gramophone/service/MultiPlayer.java
@@ -12,6 +12,7 @@ import com.dkanada.gramophone.util.MusicUtil;
import com.dkanada.gramophone.util.PreferenceUtil;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
+import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.database.ExoDatabaseProvider;
@@ -44,35 +45,28 @@ public class MultiPlayer implements Playback {
@Override
public void onPlayWhenReadyChanged(boolean playWhenReady, int reason) {
Log.i(TAG, String.format("onPlayWhenReadyChanged: %b %d", playWhenReady, reason));
+ if (callbacks != null) callbacks.onReadyChanged(playWhenReady, reason);
}
@Override
- public void onPlaybackStateChanged(int playbackState) {
- Log.i(TAG, String.format("onPlaybackStateChanged: %d", playbackState));
- if (callbacks != null && exoPlayer.isPlaying()) {
- callbacks.onTrackStarted();
- }
+ 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);
+ callbacks.onTrackChanged(reason);
+ }
}
@Override
public void onPositionDiscontinuity(int reason) {
Log.i(TAG, String.format("onPositionDiscontinuity: %d", reason));
- int windowIndex = exoPlayer.getCurrentWindowIndex();
-
- if (windowIndex == 1) {
- exoPlayer.removeMediaItem(0);
- if (exoPlayer.isPlaying()) {
- // there are still songs left in the queue
- callbacks.onTrackWentToNext();
- } else {
- callbacks.onTrackEnded();
- }
- }
}
@Override
@@ -101,6 +95,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);
@@ -140,7 +141,7 @@ public class MultiPlayer implements Playback {
@Override
public boolean isReady() {
- return true;
+ return exoPlayer.getPlayWhenReady();
}
@Override
@@ -148,6 +149,11 @@ public class MultiPlayer implements Playback {
return exoPlayer.isPlaying() || exoPlayer.getPlayWhenReady();
}
+ @Override
+ public boolean isLoading() {
+ return exoPlayer.getPlaybackState() == Player.STATE_BUFFERING;
+ }
+
@Override
public void start() {
exoPlayer.setPlayWhenReady(true);
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 b470a15e..c8677a5d 100644
--- a/app/src/main/java/com/dkanada/gramophone/service/MusicService.java
+++ b/app/src/main/java/com/dkanada/gramophone/service/MusicService.java
@@ -60,7 +60,6 @@ import org.jellyfin.apiclient.model.session.PlaybackStopInfo;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Random;
@@ -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,6 +485,10 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
return playback != null && playback.isPlaying();
}
+ public boolean isLoading() {
+ return playback != null && playback.isLoading();
+ }
+
public int getPosition() {
return position;
}
@@ -1032,25 +1038,30 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
}
@Override
- public void onTrackStarted() {
- progressHandler.sendEmptyMessage(TRACK_STARTED);
-
+ public void onStateChanged(int state) {
notifyChange(STATE_CHANGED);
- prepareNext();
}
@Override
- public void onTrackWentToNext() {
- playerHandler.sendEmptyMessage(TRACK_CHANGED);
- progressHandler.sendEmptyMessage(TRACK_CHANGED);
+ 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);
+ }
}
@Override
- public void onTrackEnded() {
- playerHandler.sendEmptyMessage(TRACK_ENDED);
- progressHandler.sendEmptyMessage(TRACK_ENDED);
-
+ public void onTrackChanged(int reason) {
acquireWakeLock(30000);
+
+ if (reason == MEDIA_ITEM_TRANSITION_REASON_AUTO) {
+ playerHandler.sendEmptyMessage(TRACK_CHANGED);
+ progressHandler.sendEmptyMessage(TRACK_CHANGED);
+ }
}
private static final class PlaybackHandler extends Handler {
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 d99ce93f..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,6 +13,8 @@ public interface Playback {
boolean isPlaying();
+ boolean isLoading();
+
void start();
void pause();
@@ -30,10 +32,10 @@ public interface Playback {
int getVolume();
interface PlaybackCallbacks {
- void onTrackStarted();
+ void onStateChanged(int state);
- void onTrackWentToNext();
+ void onReadyChanged(boolean ready, int reason);
- void onTrackEnded();
+ void onTrackChanged(int reason);
}
}
diff --git a/app/src/main/res/layout/fragment_card_player_playback_controls.xml b/app/src/main/res/layout/fragment_card_player_playback_controls.xml
index 6e1444e3..1312d7a1 100644
--- a/app/src/main/res/layout/fragment_card_player_playback_controls.xml
+++ b/app/src/main/res/layout/fragment_card_player_playback_controls.xml
@@ -12,6 +12,19 @@
android:layout_height="@dimen/progress_container_height"
android:background="@color/twenty_percent_black_overlay">
+
+
+
+