Skip to content

Commit 5751ae5

Browse files
committed
add ShuffleOrder.cloneAndSet() to provide startIndex to shuffle order
Shuffle order may want to ensure that the song that's going to be played (was chosen by user) is also the first song in shuffle playlist, as that makes sure all other songs will be playing afterwards. If first song gets random position in shuffled playlist, playback may stop before playing every song as it will start in the middle of shuffled list.
1 parent d107936 commit 5751ae5

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImpl.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2505,12 +2505,8 @@ private void setMediaSourcesInternal(
25052505
int currentWindowIndex = getCurrentWindowIndexInternal(playbackInfo);
25062506
long currentPositionMs = getCurrentPosition();
25072507
pendingOperationAcks++;
2508-
if (!mediaSourceHolderSnapshots.isEmpty()) {
2509-
removeMediaSourceHolders(
2510-
/* fromIndex= */ 0, /* toIndexExclusive= */ mediaSourceHolderSnapshots.size());
2511-
}
25122508
List<MediaSourceList.MediaSourceHolder> holders =
2513-
addMediaSourceHolders(/* index= */ 0, mediaSources);
2509+
setMediaSourceHolders(mediaSources, startWindowIndex);
25142510
Timeline timeline = createMaskingTimeline();
25152511
if (!timeline.isEmpty() && startWindowIndex >= timeline.getWindowCount()) {
25162512
throw new IllegalSeekPositionException(timeline, startWindowIndex, startPositionMs);
@@ -2556,6 +2552,21 @@ private void setMediaSourcesInternal(
25562552
/* repeatCurrentMediaItem= */ false);
25572553
}
25582554

2555+
private List<MediaSourceList.MediaSourceHolder> setMediaSourceHolders(
2556+
List<MediaSource> mediaSources, int startIndex) {
2557+
mediaSourceHolderSnapshots.clear();
2558+
List<MediaSourceList.MediaSourceHolder> holders = new ArrayList<>();
2559+
for (int i = 0; i < mediaSources.size(); i++) {
2560+
MediaSourceList.MediaSourceHolder holder =
2561+
new MediaSourceList.MediaSourceHolder(mediaSources.get(i), useLazyPreparation);
2562+
holders.add(holder);
2563+
mediaSourceHolderSnapshots.add(
2564+
i, new MediaSourceHolderSnapshot(holder.uid, holder.mediaSource));
2565+
}
2566+
shuffleOrder = shuffleOrder.cloneAndSet(/* insertionCount= */ holders.size(), startIndex);
2567+
return holders;
2568+
}
2569+
25592570
private List<MediaSourceList.MediaSourceHolder> addMediaSourceHolders(
25602571
int index, List<MediaSource> mediaSources) {
25612572
List<MediaSourceList.MediaSourceHolder> holders = new ArrayList<>();

libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ShuffleOrder.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,24 @@ default ShuffleOrder cloneAndMove(int indexFrom, int indexToExclusive, int newIn
284284
return this;
285285
}
286286

287+
/**
288+
* Returns a copy of the shuffle order with all elements replaced.
289+
*
290+
* <p>The default implementation uses {@link #cloneAndClear} and {@link #cloneAndInsert(int, int)}
291+
* to replace all elements in the shuffle order. Custom implementations can override this method
292+
* if access to the {@code startIndex} is desired.
293+
*
294+
* @param insertionCount The number of elements.
295+
* @param startIndex The index of the new element in the unshuffled order that should be the first
296+
* in the shuffled order or {@link C#INDEX_UNSET} if the index is unknown. It should be
297+
* ignored if the new list is empty, or if it is larger than the last index (inclusive) of the
298+
* new list.
299+
* @return A copy of this {@link ShuffleOrder} with the elements replaced.
300+
*/
301+
default ShuffleOrder cloneAndSet(int insertionCount, int startIndex) {
302+
return cloneAndClear().cloneAndInsert(0, insertionCount);
303+
}
304+
287305
/**
288306
* Returns a copy of the shuffle order with a range of elements removed.
289307
*

0 commit comments

Comments
 (0)