From 9a243b98674f9153c0d1874343f0c93746452bab Mon Sep 17 00:00:00 2001 From: nift4 Date: Tue, 11 Mar 2025 19:57:18 +0100 Subject: [PATCH 1/3] notify ShuffleOrder when media item(s) are moved Issue: #1932 Issue: #1381 --- .../androidx/media3/exoplayer/ExoPlayerImpl.java | 7 ++++++- .../media3/exoplayer/source/ShuffleOrder.java | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) 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 fe2a62b2f0f..bec1d7bbec0 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImpl.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImpl.java @@ -703,7 +703,7 @@ public void moveMediaItems(int fromIndex, int toIndex, int newFromIndex) { } Timeline oldTimeline = getCurrentTimeline(); pendingOperationAcks++; - Util.moveItems(mediaSourceHolderSnapshots, fromIndex, toIndex, newFromIndex); + moveMediaSourceHolders(fromIndex, toIndex, newFromIndex); Timeline newTimeline = createMaskingTimeline(); PlaybackInfo newPlaybackInfo = maskTimelineAndPosition( @@ -725,6 +725,11 @@ public void moveMediaItems(int fromIndex, int toIndex, int newFromIndex) { /* repeatCurrentMediaItem= */ false); } + private void moveMediaSourceHolders(int fromIndex, int toIndex, int newFromIndex) { + Util.moveItems(mediaSourceHolderSnapshots, fromIndex, toIndex, newFromIndex); + shuffleOrder = shuffleOrder.cloneAndMove(fromIndex, toIndex, newFromIndex); + } + @Override public void replaceMediaItems(int fromIndex, int toIndex, List mediaItems) { verifyApplicationThread(); 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 e6e2e1b2dcd..47bec157f1e 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 @@ -266,6 +266,22 @@ public ShuffleOrder cloneAndClear() { */ ShuffleOrder cloneAndInsert(int insertionIndex, int insertionCount); + /** + * Returns a copy of the shuffle order with a range of elements moved. + * + * @param indexFrom The starting index in the unshuffled order of the range to move, from before + * the move occurs. + * @param indexToExclusive The smallest index (must be greater or equal to {@code indexFrom}) that + * is not included in the range of elements moved, from before the move occurs. + * @param newIndexFrom The starting index in the unshuffled order of the range to move, from after + * the move occurs. + * @return A copy of this {@link ShuffleOrder} with the elements moved. + */ + default ShuffleOrder cloneAndMove(int indexFrom, int indexToExclusive, int newIndexFrom) { + return cloneAndRemove(indexFrom, indexToExclusive) + .cloneAndInsert(newIndexFrom, indexToExclusive - indexFrom); + } + /** * Returns a copy of the shuffle order with a range of elements removed. * From 3d7e87416981736c767d85740ef0efbddbe640ea Mon Sep 17 00:00:00 2001 From: Marc Baechinger Date: Tue, 10 Jun 2025 10:22:48 +0200 Subject: [PATCH 2/3] Merge release notes --- RELEASENOTES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 54e53770c56..28eb683b0d0 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -13,6 +13,8 @@ * Throw `IllegalStateException` when `PreloadMediaSource` is played by an `ExoPlayer` with a playback thread that is different than the preload thread ([#2495](https://github.com/androidx/media/issues/2495)). + * Add `cloneAndMove` to `ShuffleMode` with a default implementation + ([#2226](https://github.com/androidx/media/pull/2226)). * Transformer: * Add `CodecDbLite` that enables chipset specific optimizations of video encoding settings. From ad92956dce4f8a8b3f5b27bc3a6cf90bf45df8cd Mon Sep 17 00:00:00 2001 From: Marc Baechinger Date: Tue, 20 May 2025 23:01:04 +0200 Subject: [PATCH 3/3] Make default implementation of cloneAndMove a no-op --- .../java/androidx/media3/exoplayer/ExoPlayerImpl.java | 8 ++------ .../androidx/media3/exoplayer/source/ShuffleOrder.java | 8 +++++--- 2 files changed, 7 insertions(+), 9 deletions(-) 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 bec1d7bbec0..11e9a0c5887 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImpl.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImpl.java @@ -703,7 +703,8 @@ public void moveMediaItems(int fromIndex, int toIndex, int newFromIndex) { } Timeline oldTimeline = getCurrentTimeline(); pendingOperationAcks++; - moveMediaSourceHolders(fromIndex, toIndex, newFromIndex); + Util.moveItems(mediaSourceHolderSnapshots, fromIndex, toIndex, newFromIndex); + shuffleOrder = shuffleOrder.cloneAndMove(fromIndex, toIndex, newFromIndex); Timeline newTimeline = createMaskingTimeline(); PlaybackInfo newPlaybackInfo = maskTimelineAndPosition( @@ -725,11 +726,6 @@ public void moveMediaItems(int fromIndex, int toIndex, int newFromIndex) { /* repeatCurrentMediaItem= */ false); } - private void moveMediaSourceHolders(int fromIndex, int toIndex, int newFromIndex) { - Util.moveItems(mediaSourceHolderSnapshots, fromIndex, toIndex, newFromIndex); - shuffleOrder = shuffleOrder.cloneAndMove(fromIndex, toIndex, newFromIndex); - } - @Override public void replaceMediaItems(int fromIndex, int toIndex, List mediaItems) { verifyApplicationThread(); 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 47bec157f1e..dbdf2f272f8 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 @@ -267,7 +267,10 @@ public ShuffleOrder cloneAndClear() { ShuffleOrder cloneAndInsert(int insertionIndex, int insertionCount); /** - * Returns a copy of the shuffle order with a range of elements moved. + * Returns a copy of the shuffle order to be used after a move. + * + *

The default implementation is a no-op. Custom implementation can choose to re-shuffle when + * items are moved. * * @param indexFrom The starting index in the unshuffled order of the range to move, from before * the move occurs. @@ -278,8 +281,7 @@ public ShuffleOrder cloneAndClear() { * @return A copy of this {@link ShuffleOrder} with the elements moved. */ default ShuffleOrder cloneAndMove(int indexFrom, int indexToExclusive, int newIndexFrom) { - return cloneAndRemove(indexFrom, indexToExclusive) - .cloneAndInsert(newIndexFrom, indexToExclusive - indexFrom); + return this; } /**