Skip to content

Commit 777e57e

Browse files
committed
Fixed issues with shuffle and repeat
1 parent 2d2c91c commit 777e57e

4 files changed

Lines changed: 48 additions & 29 deletions

File tree

common/src/main/java/xyz/gianlu/librespot/common/Utils.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,13 @@ public static boolean optBoolean(@NotNull JsonObject obj, @NotNull String key, b
233233
return elm.getAsBoolean();
234234
}
235235

236+
@Nullable
237+
public static Boolean optBoolean(@NotNull JsonObject obj, @NotNull String key) {
238+
JsonElement elm = obj.get(key);
239+
if (elm == null || !elm.getAsJsonPrimitive().isBoolean()) return null;
240+
return elm.getAsBoolean();
241+
}
242+
236243
public static double optDouble(@NotNull JsonObject obj, @NotNull String key, double fallback) {
237244
JsonElement elm = obj.get(key);
238245
if (elm == null || !elm.getAsJsonPrimitive().isNumber()) return fallback;

core/src/main/java/xyz/gianlu/librespot/player/Player.java

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.io.IOException;
2525
import java.util.List;
2626
import java.util.Objects;
27+
import java.util.Optional;
2728

2829
/**
2930
* @author Gianlu
@@ -128,7 +129,7 @@ private void handleFrame(@NotNull Spirc.MessageType type, @NotNull Spirc.Frame s
128129
break;
129130
case kMessageTypeReplace:
130131
if (frame != null && frame.endpoint == Remote3Frame.Endpoint.UpdateContext) {
131-
updatedTracks(frame);
132+
updatedTracks(frame, true);
132133
stateUpdated();
133134
}
134135
break;
@@ -236,14 +237,14 @@ private int getPosition() {
236237
}
237238

238239
private void handleShuffle() {
239-
if (state.getShuffle()) shuffleTracks();
240+
if (state.getShuffle()) shuffleTracks(false);
240241
else unshuffleTracks();
241242
stateUpdated();
242243
}
243244

244-
private void shuffleTracks() {
245+
private void shuffleTracks(boolean fully) {
245246
if (tracksProvider instanceof PlaylistProvider)
246-
((PlaylistProvider) tracksProvider).shuffleTracks(session.random());
247+
((PlaylistProvider) tracksProvider).shuffleTracks(session.random(), fully);
247248
else
248249
LOGGER.warn("Cannot shuffle TracksProvider: " + tracksProvider);
249250
}
@@ -262,7 +263,7 @@ private void handleSeek(int pos) {
262263
stateUpdated();
263264
}
264265

265-
private void updatedTracks(@NotNull Remote3Frame frame) {
266+
private void updatedTracks(@NotNull Remote3Frame frame, boolean fromFrame) {
266267
if (frame.context.uri != null) {
267268
state.update(frame);
268269

@@ -273,9 +274,16 @@ private void updatedTracks(@NotNull Remote3Frame frame) {
273274
tracksProvider = new PlaylistProvider(session, state.state, conf);
274275
}
275276

276-
state.setRepeat(frame.options.playerOptionsOverride.repeatingContext);
277-
state.setShuffle(frame.options.playerOptionsOverride.shufflingContext);
278-
if (state.getShuffle() && conf.defaultUnshuffleBehaviour()) shuffleTracks();
277+
Optional.ofNullable(frame.options.playerOptionsOverride.repeatingContext).ifPresent(state::setRepeat);
278+
Optional.ofNullable(frame.options.playerOptionsOverride.shufflingContext).ifPresent(state::setShuffle);
279+
280+
if (fromFrame) {
281+
if (state.getShuffle() && conf.defaultUnshuffleBehaviour())
282+
shuffleTracks(true);
283+
} else {
284+
if (state.getShuffle())
285+
shuffleTracks(true);
286+
}
279287
}
280288

281289
@Override
@@ -351,10 +359,10 @@ private void handleLoad(@NotNull Remote3Frame frame) {
351359

352360
LOGGER.debug(String.format("Loading context, uri: %s", frame.context.uri));
353361

354-
updatedTracks(frame);
362+
updatedTracks(frame, frame.context.pages != null);
355363

356364
if (state.getTrackCount() > 0) {
357-
state.setPositionMs(frame.options.seekTo);
365+
state.setPositionMs(frame.options.seekTo == -1 ? 0 : frame.options.seekTo);
358366
state.setPositionMeasuredAt(TimeProvider.currentTimeMillis());
359367
loadTrack(!frame.options.initiallyPaused);
360368
} else {
@@ -613,15 +621,15 @@ void update(@NotNull Remote3Frame frame) {
613621

614622
for (Remote3Track track : tracks) state.addTrack(track.toTrackRef());
615623

616-
if (frame.options != null && frame.options.skipTo != null)
624+
if (frame.options != null && frame.options.skipTo != null && frame.options.skipTo.trackIndex != -1)
617625
state.setPlayingTrackIndex(frame.options.skipTo.trackIndex);
618626
else
619627
state.setPlayingTrackIndex(0);
620628
}
621629

622630
if (frame.options != null && frame.options.playerOptionsOverride != null) {
623-
state.setRepeat(frame.options.playerOptionsOverride.repeatingContext);
624-
state.setShuffle(frame.options.playerOptionsOverride.shufflingContext);
631+
Optional.ofNullable(frame.options.playerOptionsOverride.repeatingContext).ifPresent(state::setRepeat);
632+
Optional.ofNullable(frame.options.playerOptionsOverride.shufflingContext).ifPresent(state::setShuffle);
625633
}
626634
}
627635

core/src/main/java/xyz/gianlu/librespot/player/remote/Remote3Frame.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -313,14 +313,14 @@ public static SkipTo opt(@NotNull JsonObject obj, @NotNull String key) {
313313
}
314314

315315
public static class PlayerOptionsOverride {
316-
public final boolean shufflingContext;
317-
public final boolean repeatingContext;
318-
public final boolean repeatingTrack;
316+
public final Boolean shufflingContext;
317+
public final Boolean repeatingContext;
318+
public final Boolean repeatingTrack;
319319

320320
private PlayerOptionsOverride(@NotNull JsonObject obj) {
321-
shufflingContext = Utils.optBoolean(obj, "shuffling_context", false);
322-
repeatingContext = Utils.optBoolean(obj, "repeating_context", false);
323-
repeatingTrack = Utils.optBoolean(obj, "repeating_track", false);
321+
shufflingContext = Utils.optBoolean(obj, "shuffling_context");
322+
repeatingContext = Utils.optBoolean(obj, "repeating_context");
323+
repeatingTrack = Utils.optBoolean(obj, "repeating_track");
324324
}
325325

326326
@Nullable

core/src/main/java/xyz/gianlu/librespot/player/tracks/PlaylistProvider.java

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,24 @@ private static int[] getShuffleExchanges(int size, long seed) {
3939
return exchanges;
4040
}
4141

42-
public void shuffleTracks(@NotNull Random random) {
42+
public void shuffleTracks(@NotNull Random random, boolean fully) {
4343
shuffleSeed = random.nextLong();
4444

4545
List<Spirc.TrackRef> tracks = new ArrayList<>(state.getTrackList());
46-
if (state.getPlayingTrackIndex() != 0) {
47-
Collections.swap(tracks, 0, state.getPlayingTrackIndex());
48-
state.setPlayingTrackIndex(0);
49-
}
46+
if (fully) {
47+
Collections.shuffle(tracks, new Random(shuffleSeed));
48+
} else {
49+
if (state.getPlayingTrackIndex() != 0) {
50+
Collections.swap(tracks, 0, state.getPlayingTrackIndex());
51+
state.setPlayingTrackIndex(0);
52+
}
5053

51-
int size = tracks.size() - 1;
52-
int[] exchanges = getShuffleExchanges(size, shuffleSeed);
53-
for (int i = size - 1; i > 1; i--) {
54-
int n = exchanges[size - 1 - i];
55-
Collections.swap(tracks, i, n + 1);
54+
int size = tracks.size() - 1;
55+
int[] exchanges = getShuffleExchanges(size, shuffleSeed);
56+
for (int i = size - 1; i > 1; i--) {
57+
int n = exchanges[size - 1 - i];
58+
Collections.swap(tracks, i, n + 1);
59+
}
5660
}
5761

5862
state.clearTrack();

0 commit comments

Comments
 (0)