From f668e51ba37eb448d6d5111f2c39d0f807d10d16 Mon Sep 17 00:00:00 2001 From: Maxr1998 Date: Mon, 21 Dec 2020 20:36:34 +0100 Subject: [PATCH 1/9] Add buffering indicator --- .../player/card/CardPlayerFragment.java | 1 + .../CardPlayerPlaybackControlsFragment.java | 16 +++++++---- .../gramophone/helper/MusicPlayerRemote.java | 4 +++ .../gramophone/service/MultiPlayer.java | 28 ++++++------------- .../gramophone/service/MusicService.java | 15 ++++++---- .../gramophone/service/playback/Playback.java | 4 ++- ...fragment_card_player_playback_controls.xml | 5 ++++ 7 files changed, 43 insertions(+), 30 deletions(-) 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..56462e64 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(ColorUtil.invertColor(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 27ca838e..a422bce0 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; @@ -11,19 +12,19 @@ import android.widget.SeekBar; import androidx.annotation.NonNull; -import com.kabouzeid.appthemehelper.util.ColorUtil; -import com.kabouzeid.appthemehelper.util.MaterialValueHelper; -import com.kabouzeid.appthemehelper.util.TintHelper; import com.dkanada.gramophone.R; -import com.dkanada.gramophone.helper.MusicPlayerRemote; import com.dkanada.gramophone.databinding.FragmentCardPlayerPlaybackControlsBinding; +import com.dkanada.gramophone.fragments.AbsMusicServiceFragment; +import com.dkanada.gramophone.helper.MusicPlayerRemote; import com.dkanada.gramophone.helper.MusicProgressViewUpdateHelper; import com.dkanada.gramophone.helper.PlayPauseButtonOnClickHandler; import com.dkanada.gramophone.misc.SimpleOnSeekbarChangeListener; import com.dkanada.gramophone.service.MusicService; -import com.dkanada.gramophone.fragments.AbsMusicServiceFragment; import com.dkanada.gramophone.util.MusicUtil; import com.dkanada.gramophone.views.PlayPauseDrawable; +import com.kabouzeid.appthemehelper.util.ColorUtil; +import com.kabouzeid.appthemehelper.util.MaterialValueHelper; +import com.kabouzeid.appthemehelper.util.TintHelper; public class CardPlayerPlaybackControlsFragment extends AbsMusicServiceFragment implements MusicProgressViewUpdateHelper.Callback { @@ -133,6 +134,11 @@ public class CardPlayerPlaybackControlsFragment extends AbsMusicServiceFragment } else { playerFabPlayPauseDrawable.setPlay(animate); } + binding.playerBufferingIndicator.setVisibility(MusicPlayerRemote.isBuffering() ? View.VISIBLE : View.GONE); + } + + public void updateBufferingIndicatorColor(int color) { + binding.playerBufferingIndicator.setIndeterminateTintList(ColorStateList.valueOf(color)); } private void setUpMusicControllers() { 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..292df944 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.isBuffering(); + } + 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 b0386073..cf74a75f 100644 --- a/app/src/main/java/com/dkanada/gramophone/service/MultiPlayer.java +++ b/app/src/main/java/com/dkanada/gramophone/service/MultiPlayer.java @@ -12,7 +12,6 @@ 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.MediaItem; import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.database.ExoDatabaseProvider; @@ -54,29 +53,15 @@ public class MultiPlayer implements Playback { private PlaybackCallbacks callbacks; private final ExoPlayer.EventListener eventListener = new ExoPlayer.EventListener() { - @Override - public void onIsLoadingChanged(boolean isLoading) { - Log.i(TAG, String.format("onIsLoadingChanged: %b", isLoading)); - } @Override - public void onPlayWhenReadyChanged(boolean playWhenReady, int reason) { - Log.i(TAG, String.format("onPlayWhenReadyChanged: %b %d", 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 onPlayerStateChanged(boolean playWhenReady, int playbackState) { + Log.i(TAG, String.format("onPlayerStateChanged: %b %d", playWhenReady, playbackState)); + if (callbacks != null) { + callbacks.onPlayerStateChanged(playWhenReady, playbackState); } } - @Override - public void onMediaItemTransition(MediaItem mediaItem, int reason) { - Log.i(TAG, String.format("onMediaItemTransition: %s %d", mediaItem, reason)); - } - @Override public void onPositionDiscontinuity(int reason) { Log.i(TAG, String.format("onPositionDiscontinuity: %d", reason)); @@ -203,6 +188,11 @@ public class MultiPlayer implements Playback { return exoPlayer.isPlaying() || exoPlayer.getPlayWhenReady(); } + @Override + public boolean isBuffering() { + 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 b1ec5c71..79ffc13e 100644 --- a/app/src/main/java/com/dkanada/gramophone/service/MusicService.java +++ b/app/src/main/java/com/dkanada/gramophone/service/MusicService.java @@ -51,6 +51,7 @@ 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; @@ -60,7 +61,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; @@ -483,6 +483,10 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP return playback != null && playback.isPlaying(); } + public boolean isBuffering() { + return playback != null && playback.isBuffering(); + } + public int getPosition() { return position; } @@ -1032,11 +1036,12 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP } @Override - public void onTrackStarted() { - progressHandler.sendEmptyMessage(TRACK_STARTED); - + public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { notifyChange(STATE_CHANGED); - prepareNext(); + if (playWhenReady && playbackState == Player.STATE_READY) { + progressHandler.sendEmptyMessage(TRACK_STARTED); + prepareNext(); + } } @Override 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..c34fe682 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 isBuffering(); + void start(); void pause(); @@ -30,7 +32,7 @@ public interface Playback { int getVolume(); interface PlaybackCallbacks { - void onTrackStarted(); + void onPlayerStateChanged(boolean playWhenReady, int playbackState); void onTrackWentToNext(); 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 5517d271..ab8777dc 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 @@ -122,6 +122,11 @@ app:elevation="4dp" app:pressedTranslationZ="2dp" /> + From 94f244089b2bd1015dc5c4951f8e66de23aea010 Mon Sep 17 00:00:00 2001 From: dkanada Date: Sun, 21 Feb 2021 10:23:11 +0900 Subject: [PATCH 2/9] update imports --- .../card/CardPlayerPlaybackControlsFragment.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 a422bce0..4149768b 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 @@ -12,19 +12,19 @@ import android.widget.SeekBar; import androidx.annotation.NonNull; +import com.kabouzeid.appthemehelper.util.ColorUtil; +import com.kabouzeid.appthemehelper.util.MaterialValueHelper; +import com.kabouzeid.appthemehelper.util.TintHelper; import com.dkanada.gramophone.R; -import com.dkanada.gramophone.databinding.FragmentCardPlayerPlaybackControlsBinding; -import com.dkanada.gramophone.fragments.AbsMusicServiceFragment; import com.dkanada.gramophone.helper.MusicPlayerRemote; +import com.dkanada.gramophone.databinding.FragmentCardPlayerPlaybackControlsBinding; import com.dkanada.gramophone.helper.MusicProgressViewUpdateHelper; import com.dkanada.gramophone.helper.PlayPauseButtonOnClickHandler; import com.dkanada.gramophone.misc.SimpleOnSeekbarChangeListener; import com.dkanada.gramophone.service.MusicService; +import com.dkanada.gramophone.fragments.AbsMusicServiceFragment; import com.dkanada.gramophone.util.MusicUtil; import com.dkanada.gramophone.views.PlayPauseDrawable; -import com.kabouzeid.appthemehelper.util.ColorUtil; -import com.kabouzeid.appthemehelper.util.MaterialValueHelper; -import com.kabouzeid.appthemehelper.util.TintHelper; public class CardPlayerPlaybackControlsFragment extends AbsMusicServiceFragment implements MusicProgressViewUpdateHelper.Callback { From 6bfb72c356673c65a065c2c0106afc292a6ddb2a Mon Sep 17 00:00:00 2001 From: dkanada Date: Sun, 21 Feb 2021 11:51:57 +0900 Subject: [PATCH 3/9] switch to horizontal progress bar --- .../player/card/CardPlayerFragment.java | 2 +- .../CardPlayerPlaybackControlsFragment.java | 5 +++- ...fragment_card_player_playback_controls.xml | 23 +++++++++++++++---- 3 files changed, 23 insertions(+), 7 deletions(-) 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 56462e64..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,7 +274,7 @@ public class CardPlayerFragment extends AbsPlayerFragment implements PlayerAlbum public void onColorChanged(int color) { animateColorChange(color); playbackControlsFragment.setDark(ColorUtil.isColorLight(color)); - playbackControlsFragment.updateBufferingIndicatorColor(ColorUtil.invertColor(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 4149768b..58198a38 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 @@ -134,10 +134,13 @@ public class CardPlayerPlaybackControlsFragment extends AbsMusicServiceFragment } else { playerFabPlayPauseDrawable.setPlay(animate); } - binding.playerBufferingIndicator.setVisibility(MusicPlayerRemote.isBuffering() ? View.VISIBLE : View.GONE); + + binding.progressBarLoading.setVisibility(MusicPlayerRemote.isBuffering() ? View.VISIBLE : View.GONE); + binding.progressBarPlaying.setVisibility(MusicPlayerRemote.isBuffering() ? View.GONE : View.VISIBLE); } public void updateBufferingIndicatorColor(int color) { + binding.playerBufferingIndicator.setProgressBackgroundTintList(ColorStateList.valueOf(getResources().getColor(android.R.color.transparent))); binding.playerBufferingIndicator.setIndeterminateTintList(ColorStateList.valueOf(color)); } 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 ab8777dc..72574fef 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 @@ -8,6 +8,24 @@ android:orientation="vertical"> + + + + + + @@ -122,11 +140,6 @@ app:elevation="4dp" app:pressedTranslationZ="2dp" /> - From e26fe8d017a73e820225b1720179e3d2199602d3 Mon Sep 17 00:00:00 2001 From: dkanada Date: Sun, 21 Feb 2021 21:26:06 +0900 Subject: [PATCH 4/9] add loading indicator for mini player controls --- .../fragments/player/MiniPlayerFragment.java | 4 ++++ .../fragment_card_player_playback_controls.xml | 16 ++++++++-------- app/src/main/res/layout/fragment_mini_player.xml | 9 +++++---- 3 files changed, 17 insertions(+), 12 deletions(-) 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 ad3dae51..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 @@ -55,11 +55,14 @@ public class MiniPlayerFragment extends AbsMusicServiceFragment implements Music private void setUpMiniPlayer() { setUpPlayPauseButton(); + binding.progressBar.setProgressTintList(ColorStateList.valueOf(ThemeStore.accentColor(requireActivity()))); + binding.progressBar.setIndeterminateTintList(ColorStateList.valueOf(ThemeStore.accentColor(requireActivity()))); } private void setUpPlayPauseButton() { miniPlayerPlayPauseDrawable = new PlayPauseDrawable(requireActivity()); + binding.miniPlayerPlayPauseButton.setImageDrawable(miniPlayerPlayPauseDrawable); binding.miniPlayerPlayPauseButton.setColorFilter(ATHUtil.resolveColor(requireActivity(), R.attr.iconColor, ThemeStore.textColorSecondary(requireActivity())), PorterDuff.Mode.SRC_IN); binding.miniPlayerPlayPauseButton.setOnClickListener(new PlayPauseButtonOnClickHandler()); @@ -87,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/res/layout/fragment_card_player_playback_controls.xml b/app/src/main/res/layout/fragment_card_player_playback_controls.xml index 72574fef..c22099ae 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 @@ -13,14 +13,14 @@ android:layout_height="@dimen/progress_container_height" android:background="@color/twenty_percent_black_overlay"> - + diff --git a/app/src/main/res/layout/fragment_mini_player.xml b/app/src/main/res/layout/fragment_mini_player.xml index 25d54e80..29063d1e 100644 --- a/app/src/main/res/layout/fragment_mini_player.xml +++ b/app/src/main/res/layout/fragment_mini_player.xml @@ -6,7 +6,7 @@ android:layout_height="@dimen/mini_player_height" android:background="?cardBackgroundColor" android:clickable="true" - android:focusable="false" + android:focusable="true" android:transitionName="@string/transition_mini_player" tools:ignore="UnusedAttribute"> @@ -49,11 +49,12 @@ + app:mpb_useIntrinsicPadding="false" + app:mpb_setBothDrawables="true" + style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal" /> From c95c8d105e502dc30a8740ec426d5c6ef7ef0098 Mon Sep 17 00:00:00 2001 From: dkanada Date: Sun, 21 Feb 2021 22:48:08 +0900 Subject: [PATCH 5/9] small changes to main loading indicator --- .../CardPlayerPlaybackControlsFragment.java | 6 +-- ...fragment_card_player_playback_controls.xml | 37 +++++++++---------- 2 files changed, 21 insertions(+), 22 deletions(-) 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 58198a38..52df303b 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 @@ -134,9 +134,6 @@ public class CardPlayerPlaybackControlsFragment extends AbsMusicServiceFragment } else { playerFabPlayPauseDrawable.setPlay(animate); } - - binding.progressBarLoading.setVisibility(MusicPlayerRemote.isBuffering() ? View.VISIBLE : View.GONE); - binding.progressBarPlaying.setVisibility(MusicPlayerRemote.isBuffering() ? View.GONE : View.VISIBLE); } public void updateBufferingIndicatorColor(int color) { @@ -238,8 +235,11 @@ 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); + binding.playerSongTotalTime.setText(MusicUtil.getReadableDurationString(total)); binding.playerSongCurrentProgress.setText(MusicUtil.getReadableDurationString(progress)); } 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 c22099ae..3d27383d 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 @@ -7,8 +7,8 @@ android:layout_height="wrap_content" android:orientation="vertical"> - @@ -16,25 +16,20 @@ - - - - + app:layout_constraintStart_toStartOf="parent" + tools:ignore="RtlSymmetry" + tools:text="0:00" /> + app:layout_constraintEnd_toEndOf="parent" + tools:ignore="RtlSymmetry" + tools:text="4:00" /> + app:layout_constraintStart_toEndOf="@id/player_song_current_progress" + app:layout_constraintEnd_toStartOf="@id/player_song_total_time" + style="@style/MusicProgressSlider" /> - + Date: Sat, 6 Mar 2021 15:51:16 +0900 Subject: [PATCH 6/9] use exoplayer design for player callbacks --- .../gramophone/helper/MusicPlayerRemote.java | 2 +- .../gramophone/service/MultiPlayer.java | 45 +++++++++++-------- .../gramophone/service/MusicService.java | 39 +++++++++------- .../gramophone/service/playback/Playback.java | 8 ++-- 4 files changed, 54 insertions(+), 40 deletions(-) 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); } } From d66409797f5f08a2ee89c3d629af28b176796f5c Mon Sep 17 00:00:00 2001 From: dkanada Date: Sat, 6 Mar 2021 16:28:45 +0900 Subject: [PATCH 7/9] add log for position discontinuity --- .../java/com/dkanada/gramophone/service/MultiPlayer.java | 5 +++++ .../java/com/dkanada/gramophone/service/MusicService.java | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) 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 03ba6b9d..d0f5d181 100644 --- a/app/src/main/java/com/dkanada/gramophone/service/MultiPlayer.java +++ b/app/src/main/java/com/dkanada/gramophone/service/MultiPlayer.java @@ -64,6 +64,11 @@ public class MultiPlayer implements Playback { } } + @Override + public void onPositionDiscontinuity(int reason) { + Log.i(TAG, String.format("onPositionDiscontinuity: %d", reason)); + } + @Override public void onPlayerError(ExoPlaybackException error) { Log.i(TAG, String.format("onPlayerError: %s", error.getMessage())); 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 ee773726..c8677a5d 100644 --- a/app/src/main/java/com/dkanada/gramophone/service/MusicService.java +++ b/app/src/main/java/com/dkanada/gramophone/service/MusicService.java @@ -1051,12 +1051,13 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP prepareNext(); } else if (reason == PLAY_WHEN_READY_CHANGE_REASON_END_OF_MEDIA_ITEM) { progressHandler.sendEmptyMessage(TRACK_ENDED); - acquireWakeLock(30000); } } @Override public void onTrackChanged(int reason) { + acquireWakeLock(30000); + if (reason == MEDIA_ITEM_TRANSITION_REASON_AUTO) { playerHandler.sendEmptyMessage(TRACK_CHANGED); progressHandler.sendEmptyMessage(TRACK_CHANGED); From d6e04f50a281f7b5cbc914f9b6bb24fe042338a6 Mon Sep 17 00:00:00 2001 From: dkanada Date: Sat, 6 Mar 2021 16:50:54 +0900 Subject: [PATCH 8/9] remove id from parent layout --- .../main/res/layout/fragment_card_player_playback_controls.xml | 1 - 1 file changed, 1 deletion(-) 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 d5d15088..70f6e7b5 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 @@ -8,7 +8,6 @@ android:orientation="vertical"> From 798cbbe90cfbace3e890506b2d94449da6c1f504 Mon Sep 17 00:00:00 2001 From: dkanada Date: Sat, 6 Mar 2021 16:56:13 +0900 Subject: [PATCH 9/9] add buffering indicator to flat view --- .../fragments/player/flat/FlatPlayerFragment.java | 1 + .../flat/FlatPlayerPlaybackControlsFragment.java | 8 ++++++++ .../fragment_flat_player_playback_controls.xml | 13 +++++++++++++ 3 files changed, 22 insertions(+) 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/res/layout/fragment_flat_player_playback_controls.xml b/app/src/main/res/layout/fragment_flat_player_playback_controls.xml index 7e56079f..5012a653 100644 --- a/app/src/main/res/layout/fragment_flat_player_playback_controls.xml +++ b/app/src/main/res/layout/fragment_flat_player_playback_controls.xml @@ -12,6 +12,19 @@ android:layout_height="@dimen/progress_container_height" android:background="@color/twenty_percent_black_overlay"> + +