fix: keep observer until data is received on continuous play (#421)

This commit is contained in:
eddyizm 2026-02-08 10:18:36 -08:00 committed by GitHub
parent 54612c6b74
commit d215581e19
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 39 additions and 28 deletions

View file

@ -33,6 +33,8 @@ import com.google.common.collect.ImmutableList
import com.google.common.util.concurrent.Futures import com.google.common.util.concurrent.Futures
import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.ListenableFuture
private const val TAG = "BaseMediaService"
@UnstableApi @UnstableApi
open class BaseMediaService : MediaLibraryService() { open class BaseMediaService : MediaLibraryService() {
companion object { companion object {
@ -82,7 +84,7 @@ open class BaseMediaService : MediaLibraryService() {
} }
fun updateMediaItems(player: Player) { fun updateMediaItems(player: Player) {
Log.d(javaClass.toString(), "update items") Log.d(TAG, "update items")
val n = player.mediaItemCount val n = player.mediaItemCount
val k = player.currentMediaItemIndex val k = player.currentMediaItemIndex
val current = player.currentPosition val current = player.currentPosition
@ -121,7 +123,7 @@ open class BaseMediaService : MediaLibraryService() {
fun initializePlayerListener(player: Player) { fun initializePlayerListener(player: Player) {
player.addListener(object : Player.Listener { player.addListener(object : Player.Listener {
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) { override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
Log.d(javaClass.toString(), "onMediaItemTransition" + player.currentMediaItemIndex) Log.d(TAG, "onMediaItemTransition" + player.currentMediaItemIndex)
if (mediaItem == null) return if (mediaItem == null) return
if (reason == Player.MEDIA_ITEM_TRANSITION_REASON_SEEK || reason == Player.MEDIA_ITEM_TRANSITION_REASON_AUTO) { if (reason == Player.MEDIA_ITEM_TRANSITION_REASON_SEEK || reason == Player.MEDIA_ITEM_TRANSITION_REASON_AUTO) {
@ -131,7 +133,7 @@ open class BaseMediaService : MediaLibraryService() {
} }
override fun onTracksChanged(tracks: Tracks) { override fun onTracksChanged(tracks: Tracks) {
Log.d(javaClass.toString(), "onTracksChanged " + player.currentMediaItemIndex) Log.d(TAG, "onTracksChanged " + player.currentMediaItemIndex)
ReplayGainUtil.setReplayGain(player, tracks) ReplayGainUtil.setReplayGain(player, tracks)
val currentMediaItem = player.currentMediaItem val currentMediaItem = player.currentMediaItem
if (currentMediaItem != null) { if (currentMediaItem != null) {
@ -151,7 +153,7 @@ open class BaseMediaService : MediaLibraryService() {
if (player is ExoPlayer) { if (player is ExoPlayer) {
// https://stackoverflow.com/questions/56937283/exoplayer-shuffle-doesnt-reproduce-all-the-songs // https://stackoverflow.com/questions/56937283/exoplayer-shuffle-doesnt-reproduce-all-the-songs
if (MediaManager.justStarted.get()) { if (MediaManager.justStarted.get()) {
Log.d(javaClass.toString(), "update shuffle order") Log.d(TAG, "update shuffle order")
MediaManager.justStarted.set(false) MediaManager.justStarted.set(false)
val shuffledList = IntArray(player.mediaItemCount) { i -> i } val shuffledList = IntArray(player.mediaItemCount) { i -> i }
shuffledList.shuffle() shuffledList.shuffle()
@ -169,7 +171,7 @@ open class BaseMediaService : MediaLibraryService() {
} }
override fun onIsPlayingChanged(isPlaying: Boolean) { override fun onIsPlayingChanged(isPlaying: Boolean) {
Log.d(javaClass.toString(), "onIsPlayingChanged " + player.currentMediaItemIndex) Log.d(TAG, "onIsPlayingChanged " + player.currentMediaItemIndex)
if (!isPlaying) { if (!isPlaying) {
MediaManager.setPlayingPausedTimestamp( MediaManager.setPlayingPausedTimestamp(
player.currentMediaItem, player.currentMediaItem,
@ -187,7 +189,7 @@ open class BaseMediaService : MediaLibraryService() {
} }
override fun onPlaybackStateChanged(playbackState: Int) { override fun onPlaybackStateChanged(playbackState: Int) {
Log.d(javaClass.toString(), "onPlaybackStateChanged") Log.d(TAG, "onPlaybackStateChanged")
super.onPlaybackStateChanged(playbackState) super.onPlaybackStateChanged(playbackState)
if (!player.hasNextMediaItem() && if (!player.hasNextMediaItem() &&
playbackState == Player.STATE_ENDED && playbackState == Player.STATE_ENDED &&
@ -204,7 +206,7 @@ open class BaseMediaService : MediaLibraryService() {
newPosition: Player.PositionInfo, newPosition: Player.PositionInfo,
reason: Int reason: Int
) { ) {
Log.d(javaClass.toString(), "onPositionDiscontinuity") Log.d(TAG, "onPositionDiscontinuity")
super.onPositionDiscontinuity(oldPosition, newPosition, reason) super.onPositionDiscontinuity(oldPosition, newPosition, reason)
if (reason == Player.DISCONTINUITY_REASON_AUTO_TRANSITION) { if (reason == Player.DISCONTINUITY_REASON_AUTO_TRANSITION) {
@ -228,7 +230,7 @@ open class BaseMediaService : MediaLibraryService() {
} }
override fun onAudioSessionIdChanged(audioSessionId: Int) { override fun onAudioSessionIdChanged(audioSessionId: Int) {
Log.d(javaClass.toString(), "onAudioSessionIdChanged") Log.d(TAG, "onAudioSessionIdChanged")
attachEqualizerIfPossible(audioSessionId) attachEqualizerIfPossible(audioSessionId)
} }
}) })
@ -320,7 +322,7 @@ open class BaseMediaService : MediaLibraryService() {
} }
private fun initializeMediaLibrarySession(player: Player) { private fun initializeMediaLibrarySession(player: Player) {
Log.d(javaClass.toString(), "initializeMediaLibrarySession") Log.d(TAG, "initializeMediaLibrarySession")
val sessionActivityPendingIntent = val sessionActivityPendingIntent =
TaskStackBuilder.create(this).run { TaskStackBuilder.create(this).run {
addNextIntent(Intent(baseContext, MainActivity::class.java)) addNextIntent(Intent(baseContext, MainActivity::class.java))
@ -467,7 +469,7 @@ open class BaseMediaService : MediaLibraryService() {
customCommand: SessionCommand, customCommand: SessionCommand,
args: Bundle args: Bundle
): ListenableFuture<SessionResult> { ): ListenableFuture<SessionResult> {
Log.d(javaClass.toString(), "onCustomCommand") Log.d(TAG, "onCustomCommand")
when (customCommand.customAction) { when (customCommand.customAction) {
CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON -> session.player.shuffleModeEnabled = true CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON -> session.player.shuffleModeEnabled = true
CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF -> session.player.shuffleModeEnabled = false CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF -> session.player.shuffleModeEnabled = false
@ -492,7 +494,7 @@ open class BaseMediaService : MediaLibraryService() {
controller: ControllerInfo, controller: ControllerInfo,
mediaItems: List<MediaItem> mediaItems: List<MediaItem>
): ListenableFuture<List<MediaItem>> { ): ListenableFuture<List<MediaItem>> {
Log.d(javaClass.toString(), "onAddMediaItems") Log.d(TAG, "onAddMediaItems")
val updatedMediaItems = mediaItems.map { mediaItem -> val updatedMediaItems = mediaItems.map { mediaItem ->
val mediaMetadata = mediaItem.mediaMetadata val mediaMetadata = mediaItem.mediaMetadata
val newMetadata = mediaMetadata.buildUpon() val newMetadata = mediaMetadata.buildUpon()

View file

@ -444,25 +444,34 @@ public class MediaManager {
} }
@OptIn(markerClass = UnstableApi.class) @OptIn(markerClass = UnstableApi.class)
public static void continuousPlay(MediaItem mediaItem, ListenableFuture<MediaBrowser> existingBrowserFuture) { public static void continuousPlay(MediaItem mediaItem,
if (mediaItem != null && Preferences.isContinuousPlayEnabled() && Preferences.isInstantMixUsable()) { ListenableFuture<MediaBrowser> existingBrowserFuture) {
if (mediaItem == null
|| !Preferences.isContinuousPlayEnabled()
|| !Preferences.isInstantMixUsable()) {
return;
}
Preferences.setLastInstantMix(); Preferences.setLastInstantMix();
LiveData<List<Child>> instantMix = getSongRepository().getContinuousMix(mediaItem.mediaId, 25); LiveData<List<Child>> instantMix =
getSongRepository().getContinuousMix(mediaItem.mediaId, 25);
instantMix.observeForever(new Observer<List<Child>>() { instantMix.observeForever(new Observer<List<Child>>() {
@Override @Override
public void onChanged(List<Child> media) { public void onChanged(List<Child> media) {
if (media != null && existingBrowserFuture != null) { if (media == null || media.isEmpty()) {
Log.d(TAG, "Continuous play: adding " + media.size() + " tracks"); return;
enqueue(existingBrowserFuture, media, false);
} }
if (existingBrowserFuture != null) {
Log.d(TAG, "Continuous play: adding " + media.size() + " tracks");
enqueue(existingBrowserFuture, media, true);
}
instantMix.removeObserver(this); instantMix.removeObserver(this);
} }
}); });
} }
}
public static void saveChronology(MediaItem mediaItem) { public static void saveChronology(MediaItem mediaItem) {
if (mediaItem != null) { if (mediaItem != null) {