diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java index 7530b2b948..0ce920a16f 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java @@ -107,7 +107,7 @@ import java.util.concurrent.CopyOnWriteArraySet; }; playbackInfo = new ExoPlayerImplInternal.PlaybackInfo(0, 0); internalPlayer = new ExoPlayerImplInternal(renderers, trackSelector, loadControl, playWhenReady, - repeatMode, eventHandler, playbackInfo, this); + repeatMode, shuffleModeEnabled, eventHandler, playbackInfo, this); } @Override @@ -195,6 +195,7 @@ import java.util.concurrent.CopyOnWriteArraySet; public void setShuffleModeEnabled(boolean shuffleModeEnabled) { if (this.shuffleModeEnabled != shuffleModeEnabled) { this.shuffleModeEnabled = shuffleModeEnabled; + internalPlayer.setShuffleModeEnabled(shuffleModeEnabled); for (Player.EventListener listener : listeners) { listener.onShuffleModeEnabledChanged(shuffleModeEnabled); } @@ -530,4 +531,3 @@ import java.util.concurrent.CopyOnWriteArraySet; } } - diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java index b8274126b5..67586cc07a 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java @@ -128,6 +128,7 @@ import java.io.IOException; private static final int MSG_TRACK_SELECTION_INVALIDATED = 10; private static final int MSG_CUSTOM = 11; private static final int MSG_SET_REPEAT_MODE = 12; + private static final int MSG_SET_SHUFFLE_ENABLED = 13; private static final int PREPARING_SOURCE_INTERVAL_MS = 10; private static final int RENDERING_INTERVAL_MS = 10; @@ -173,6 +174,7 @@ import java.io.IOException; private boolean isLoading; private int state; private @Player.RepeatMode int repeatMode; + private boolean shuffleModeEnabled; private int customMessagesSent; private int customMessagesProcessed; private long elapsedRealtimeUs; @@ -189,12 +191,14 @@ import java.io.IOException; public ExoPlayerImplInternal(Renderer[] renderers, TrackSelector trackSelector, LoadControl loadControl, boolean playWhenReady, @Player.RepeatMode int repeatMode, - Handler eventHandler, PlaybackInfo playbackInfo, ExoPlayer player) { + boolean shuffleModeEnabled, Handler eventHandler, PlaybackInfo playbackInfo, + ExoPlayer player) { this.renderers = renderers; this.trackSelector = trackSelector; this.loadControl = loadControl; this.playWhenReady = playWhenReady; this.repeatMode = repeatMode; + this.shuffleModeEnabled = shuffleModeEnabled; this.eventHandler = eventHandler; this.state = Player.STATE_IDLE; this.playbackInfo = playbackInfo; @@ -234,6 +238,10 @@ import java.io.IOException; handler.obtainMessage(MSG_SET_REPEAT_MODE, repeatMode, 0).sendToTarget(); } + public void setShuffleModeEnabled(boolean shuffleModeEnabled) { + handler.obtainMessage(MSG_SET_SHUFFLE_ENABLED, shuffleModeEnabled ? 1 : 0, 0).sendToTarget(); + } + public void seekTo(Timeline timeline, int windowIndex, long positionUs) { handler.obtainMessage(MSG_SEEK_TO, new SeekPosition(timeline, windowIndex, positionUs)) .sendToTarget(); @@ -346,6 +354,10 @@ import java.io.IOException; setRepeatModeInternal(msg.arg1); return true; } + case MSG_SET_SHUFFLE_ENABLED: { + setShuffleModeEnabledInternal(msg.arg1 != 0); + return true; + } case MSG_DO_SOME_WORK: { doSomeWork(); return true; @@ -457,7 +469,17 @@ import java.io.IOException; throws ExoPlaybackException { this.repeatMode = repeatMode; mediaPeriodInfoSequence.setRepeatMode(repeatMode); + validateExistingPeriodHolders(); + } + private void setShuffleModeEnabledInternal(boolean shuffleModeEnabled) + throws ExoPlaybackException { + this.shuffleModeEnabled = shuffleModeEnabled; + mediaPeriodInfoSequence.setShuffleModeEnabled(shuffleModeEnabled); + validateExistingPeriodHolders(); + } + + private void validateExistingPeriodHolders() throws ExoPlaybackException { // Find the last existing period holder that matches the new period order. MediaPeriodHolder lastValidPeriodHolder = playingPeriodHolder != null ? playingPeriodHolder : loadingPeriodHolder; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/MediaPeriodInfoSequence.java b/library/core/src/main/java/com/google/android/exoplayer2/MediaPeriodInfoSequence.java index 0e9c65421c..9e8c2645c1 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/MediaPeriodInfoSequence.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/MediaPeriodInfoSequence.java @@ -102,8 +102,8 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; private final Timeline.Window window; private Timeline timeline; - @RepeatMode - private int repeatMode; + private @RepeatMode int repeatMode; + private boolean shuffleModeEnabled; /** * Creates a new media period info sequence. @@ -129,6 +129,14 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; this.repeatMode = repeatMode; } + /** + * Sets whether shuffling is enabled. Call {@link #getUpdatedMediaPeriodInfo} to update period + * information taking into account the shuffle mode. + */ + public void setShuffleModeEnabled(boolean shuffleModeEnabled) { + this.shuffleModeEnabled = shuffleModeEnabled; + } + /** * Returns the first {@link MediaPeriodInfo} to play, based on the specified playback position. */