diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImpl.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImpl.java index 5d5ce726c2..b627730596 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImpl.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImpl.java @@ -2454,12 +2454,8 @@ private void setMediaSourcesInternal( int currentWindowIndex = getCurrentWindowIndexInternal(playbackInfo); long currentPositionMs = getCurrentPosition(); pendingOperationAcks++; - if (!mediaSourceHolderSnapshots.isEmpty()) { - removeMediaSourceHolders( - /* fromIndex= */ 0, /* toIndexExclusive= */ mediaSourceHolderSnapshots.size()); - } List holders = - addMediaSourceHolders(/* index= */ 0, mediaSources); + setMediaSourceHolders(mediaSources, startWindowIndex); Timeline timeline = createMaskingTimeline(); if (!timeline.isEmpty() && startWindowIndex >= timeline.getWindowCount()) { throw new IllegalSeekPositionException(timeline, startWindowIndex, startPositionMs); @@ -2505,6 +2501,21 @@ private void setMediaSourcesInternal( /* repeatCurrentMediaItem= */ false); } + private List setMediaSourceHolders( + List mediaSources, int startIndex) { + mediaSourceHolderSnapshots.clear(); + List holders = new ArrayList<>(); + for (int i = 0; i < mediaSources.size(); i++) { + MediaSourceList.MediaSourceHolder holder = + new MediaSourceList.MediaSourceHolder(mediaSources.get(i), useLazyPreparation); + holders.add(holder); + mediaSourceHolderSnapshots.add( + i, new MediaSourceHolderSnapshot(holder.uid, holder.mediaSource)); + } + shuffleOrder = shuffleOrder.cloneAndSet(/* insertionCount= */ holders.size(), startIndex); + return holders; + } + private List addMediaSourceHolders( int index, List mediaSources) { List holders = new ArrayList<>(); diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ShuffleOrder.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ShuffleOrder.java index dbdf2f272f..e4a28f93fd 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ShuffleOrder.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ShuffleOrder.java @@ -284,6 +284,22 @@ default ShuffleOrder cloneAndMove(int indexFrom, int indexToExclusive, int newIn return this; } + /** + * Returns a copy of the shuffle order with all elements replaced. + * + *

The default implementation uses {@link #cloneAndClear} and {@link #cloneAndInsert(int, int)} + * to replace all elements in the shuffle order. Custom implementations can override this method + * if access to the {@code startIndex} is desired. + * + * @param insertionCount The number of elements. + * @param startIndex The index playback will start from after replacement, or {@link + * C#INDEX_UNSET} if the new list is empty or the index is unknown. + * @return A copy of this {@link ShuffleOrder} with the elements replaced. + */ + default ShuffleOrder cloneAndSet(int insertionCount, int startIndex) { + return cloneAndClear().cloneAndInsert(0, insertionCount); + } + /** * Returns a copy of the shuffle order with a range of elements removed. *