honour shuffle order when publishing queue to media session
Issue #5360 PiperOrigin-RevId: 235196177
This commit is contained in:
parent
eea1ce3e0a
commit
e8077fb3f4
@ -60,6 +60,8 @@
|
||||
`TrackSelectionDialogBuilder` and add option to select multiple overrides.
|
||||
* MediaSessionConnector: Let apps intercept media button events
|
||||
([#5179](https://github.com/google/ExoPlayer/issues/5179)).
|
||||
* Fix issue with `TimelineQueueNavigator` not publishing the queue in shuffled
|
||||
order when in shuffle mode.
|
||||
|
||||
### 2.9.6 ###
|
||||
|
||||
|
@ -971,6 +971,7 @@ public final class MediaSessionConnector {
|
||||
? PlaybackStateCompat.SHUFFLE_MODE_ALL
|
||||
: PlaybackStateCompat.SHUFFLE_MODE_NONE);
|
||||
invalidateMediaSessionPlaybackState();
|
||||
invalidateMediaSessionQueue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -25,10 +25,10 @@ import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.ControlDispatcher;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.Timeline;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An abstract implementation of the {@link MediaSessionConnector.QueueNavigator} that maps the
|
||||
@ -67,6 +67,7 @@ public abstract class TimelineQueueNavigator implements MediaSessionConnector.Qu
|
||||
* @param maxQueueSize The maximum queue size.
|
||||
*/
|
||||
public TimelineQueueNavigator(MediaSessionCompat mediaSession, int maxQueueSize) {
|
||||
Assertions.checkState(maxQueueSize > 0);
|
||||
this.mediaSession = mediaSession;
|
||||
this.maxQueueSize = maxQueueSize;
|
||||
activeQueueItemId = MediaSessionCompat.QueueItem.UNKNOWN_ID;
|
||||
@ -193,22 +194,50 @@ public abstract class TimelineQueueNavigator implements MediaSessionConnector.Qu
|
||||
// Helper methods.
|
||||
|
||||
private void publishFloatingQueueWindow(Player player) {
|
||||
if (player.getCurrentTimeline().isEmpty()) {
|
||||
Timeline timeline = player.getCurrentTimeline();
|
||||
if (timeline.isEmpty()) {
|
||||
mediaSession.setQueue(Collections.emptyList());
|
||||
activeQueueItemId = MediaSessionCompat.QueueItem.UNKNOWN_ID;
|
||||
return;
|
||||
}
|
||||
int windowCount = player.getCurrentTimeline().getWindowCount();
|
||||
ArrayDeque<MediaSessionCompat.QueueItem> queue = new ArrayDeque<>();
|
||||
int queueSize = Math.min(maxQueueSize, timeline.getWindowCount());
|
||||
|
||||
// Add the active queue item.
|
||||
int currentWindowIndex = player.getCurrentWindowIndex();
|
||||
int queueSize = Math.min(maxQueueSize, windowCount);
|
||||
int startIndex = Util.constrainValue(currentWindowIndex - ((queueSize - 1) / 2), 0,
|
||||
windowCount - queueSize);
|
||||
List<MediaSessionCompat.QueueItem> queue = new ArrayList<>();
|
||||
for (int i = startIndex; i < startIndex + queueSize; i++) {
|
||||
queue.add(new MediaSessionCompat.QueueItem(getMediaDescription(player, i), i));
|
||||
queue.add(
|
||||
new MediaSessionCompat.QueueItem(
|
||||
getMediaDescription(player, currentWindowIndex), currentWindowIndex));
|
||||
|
||||
// Fill queue alternating with next and/or previous queue items.
|
||||
int firstWindowIndex = currentWindowIndex;
|
||||
int lastWindowIndex = currentWindowIndex;
|
||||
boolean shuffleModeEnabled = player.getShuffleModeEnabled();
|
||||
while ((firstWindowIndex != C.INDEX_UNSET || lastWindowIndex != C.INDEX_UNSET)
|
||||
&& queue.size() < queueSize) {
|
||||
// Begin with next to have a longer tail than head if an even sized queue needs to be trimmed.
|
||||
if (lastWindowIndex != C.INDEX_UNSET) {
|
||||
lastWindowIndex =
|
||||
timeline.getNextWindowIndex(
|
||||
lastWindowIndex, Player.REPEAT_MODE_OFF, shuffleModeEnabled);
|
||||
if (lastWindowIndex != C.INDEX_UNSET) {
|
||||
queue.add(
|
||||
new MediaSessionCompat.QueueItem(
|
||||
getMediaDescription(player, lastWindowIndex), lastWindowIndex));
|
||||
}
|
||||
}
|
||||
if (firstWindowIndex != C.INDEX_UNSET && queue.size() < queueSize) {
|
||||
firstWindowIndex =
|
||||
timeline.getPreviousWindowIndex(
|
||||
firstWindowIndex, Player.REPEAT_MODE_OFF, shuffleModeEnabled);
|
||||
if (firstWindowIndex != C.INDEX_UNSET) {
|
||||
queue.addFirst(
|
||||
new MediaSessionCompat.QueueItem(
|
||||
getMediaDescription(player, firstWindowIndex), firstWindowIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
mediaSession.setQueue(queue);
|
||||
mediaSession.setQueue(new ArrayList<>(queue));
|
||||
activeQueueItemId = currentWindowIndex;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user