-Added seamless shuffling.

-Reenabled full window loading in MediaSourceManager.
This commit is contained in:
John Zhen Mo 2018-03-03 20:58:06 -08:00
parent a88e19a8ed
commit 59558efed1
5 changed files with 50 additions and 25 deletions

View File

@ -384,9 +384,11 @@ public final class BackgroundPlayer extends Service {
@Nullable final StreamInfo info,
final int newPlayQueueIndex,
final boolean hasPlayQueueItemChanged) {
resetNotification();
updateNotification(-1);
updateMetadata();
if (shouldUpdateOnProgress || hasPlayQueueItemChanged) {
resetNotification();
updateNotification(-1);
updateMetadata();
}
}
@Override
@ -434,7 +436,8 @@ public final class BackgroundPlayer extends Service {
private void updatePlayback() {
if (activityListener != null && simpleExoPlayer != null && playQueue != null) {
activityListener.onPlaybackUpdate(currentState, getRepeatMode(), playQueue.isShuffled(), getPlaybackParameters());
activityListener.onPlaybackUpdate(currentState, getRepeatMode(),
playQueue.isShuffled(), getPlaybackParameters());
}
}

View File

@ -494,14 +494,8 @@ public abstract class BasePlayer implements
public void onShuffleClicked() {
if (DEBUG) Log.d(TAG, "onShuffleClicked() called");
if (playQueue == null) return;
setRecovery();
if (playQueue.isShuffled()) {
playQueue.unshuffle();
} else {
playQueue.shuffle();
}
if (simpleExoPlayer == null) return;
simpleExoPlayer.setShuffleModeEnabled(!simpleExoPlayer.getShuffleModeEnabled());
}
/*//////////////////////////////////////////////////////////////////////////
@ -765,6 +759,12 @@ public abstract class BasePlayer implements
public void onShuffleModeEnabledChanged(final boolean shuffleModeEnabled) {
if (DEBUG) Log.d(TAG, "ExoPlayer - onShuffleModeEnabledChanged() called with: " +
"mode = [" + shuffleModeEnabled + "]");
if (playQueue == null) return;
if (shuffleModeEnabled) {
playQueue.shuffle();
} else {
playQueue.unshuffle();
}
}
@Override
@ -803,7 +803,7 @@ public abstract class BasePlayer implements
public void onPlaybackSynchronize(@NonNull final PlayQueueItem item,
@Nullable final StreamInfo info) {
if (DEBUG) Log.d(TAG, "Playback - onPlaybackSynchronize() called with " +
(info == null ? "available" : "null") + " info, " +
(info != null ? "available" : "null") + " info, " +
"item=[" + item.getTitle() + "], url=[" + item.getUrl() + "]");
final boolean hasPlayQueueItemChanged = currentItem != item;

View File

@ -6,6 +6,7 @@ import android.util.Log;
import com.google.android.exoplayer2.source.DynamicConcatenatingMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.ShuffleOrder;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
@ -19,6 +20,7 @@ import org.schabi.newpipe.playlist.PlayQueueItem;
import org.schabi.newpipe.playlist.events.MoveEvent;
import org.schabi.newpipe.playlist.events.PlayQueueEvent;
import org.schabi.newpipe.playlist.events.RemoveEvent;
import org.schabi.newpipe.playlist.events.ReorderEvent;
import java.util.ArrayList;
import java.util.Collections;
@ -216,7 +218,6 @@ public class MediaSourceManager {
// Event specific action
switch (event.type()) {
case INIT:
case REORDER:
case ERROR:
reset();
break;
@ -231,6 +232,12 @@ public class MediaSourceManager {
final MoveEvent moveEvent = (MoveEvent) event;
move(moveEvent.getFromIndex(), moveEvent.getToIndex());
break;
case REORDER:
// Need to move to ensure the playing index from play queue matches that of
// the source timeline, and then window correction can take care of the rest
final ReorderEvent reorderEvent = (ReorderEvent) event;
move(reorderEvent.getFromSelectedIndex(), reorderEvent.getToSelectedIndex());
break;
case SELECT:
case RECOVERY:
default:
@ -305,7 +312,7 @@ public class MediaSourceManager {
}
/*//////////////////////////////////////////////////////////////////////////
// Metadata Synchronization TODO: maybe this should be a separate manager
// Metadata Synchronization
//////////////////////////////////////////////////////////////////////////*/
private void maybeSync() {
@ -389,8 +396,8 @@ public class MediaSourceManager {
if (playQueue.indexOf(item) >= sources.getSize()) return;
if (!loadingItems.contains(item) && isCorrectionNeeded(item)) {
if (DEBUG) Log.d(TAG, "MediaSource - Loading: [" + item.getTitle() +
"] with url: " + item.getUrl());
if (DEBUG) Log.d(TAG, "MediaSource - Loading=[" + item.getTitle() +
"] with url=[" + item.getUrl() + "]");
loadingItems.add(item);
final Disposable loader = getLoadedMediaSource(item)
@ -423,16 +430,16 @@ public class MediaSourceManager {
private void onMediaSourceReceived(@NonNull final PlayQueueItem item,
@NonNull final ManagedMediaSource mediaSource) {
if (DEBUG) Log.d(TAG, "MediaSource - Loaded: [" + item.getTitle() +
"] with url: " + item.getUrl());
if (DEBUG) Log.d(TAG, "MediaSource - Loaded=[" + item.getTitle() +
"] with url=[" + item.getUrl() + "]");
loadingItems.remove(item);
final int itemIndex = playQueue.indexOf(item);
// Only update the playlist timeline for items at the current index or after.
if (itemIndex >= playQueue.getIndex() && isCorrectionNeeded(item)) {
if (DEBUG) Log.d(TAG, "MediaSource - Updating: [" + item.getTitle() +
"] with url: " + item.getUrl());
if (DEBUG) Log.d(TAG, "MediaSource - Updating index=[" + itemIndex + "] with " +
"title=[" + item.getTitle() + "] at url=[" + item.getUrl() + "]");
update(itemIndex, mediaSource, this::maybeSynchronizePlayer);
}
}
@ -468,7 +475,8 @@ public class MediaSourceManager {
if (DEBUG) Log.d(TAG, "resetSources() called.");
this.sources.releaseSource();
this.sources = new DynamicConcatenatingMediaSource();
this.sources = new DynamicConcatenatingMediaSource(false,
new ShuffleOrder.UnshuffledShuffleOrder(0));
}
private void populateSources() {

View File

@ -351,6 +351,7 @@ public abstract class PlayQueue implements Serializable {
if (backup == null) {
backup = new ArrayList<>(streams);
}
final int originIndex = getIndex();
final PlayQueueItem current = getItem();
Collections.shuffle(streams);
@ -360,7 +361,7 @@ public abstract class PlayQueue implements Serializable {
}
queueIndex.set(0);
broadcast(new ReorderEvent());
broadcast(new ReorderEvent(originIndex, queueIndex.get()));
}
/**
@ -373,6 +374,7 @@ public abstract class PlayQueue implements Serializable {
* */
public synchronized void unshuffle() {
if (backup == null) return;
final int originIndex = getIndex();
final PlayQueueItem current = getItem();
streams.clear();
@ -386,7 +388,7 @@ public abstract class PlayQueue implements Serializable {
queueIndex.set(0);
}
broadcast(new ReorderEvent());
broadcast(new ReorderEvent(originIndex, queueIndex.get()));
}
/*//////////////////////////////////////////////////////////////////////////

View File

@ -1,12 +1,24 @@
package org.schabi.newpipe.playlist.events;
public class ReorderEvent implements PlayQueueEvent {
private final int fromSelectedIndex;
private final int toSelectedIndex;
@Override
public PlayQueueEventType type() {
return PlayQueueEventType.REORDER;
}
public ReorderEvent() {
public ReorderEvent(final int fromSelectedIndex, final int toSelectedIndex) {
this.fromSelectedIndex = fromSelectedIndex;
this.toSelectedIndex = toSelectedIndex;
}
public int getFromSelectedIndex() {
return fromSelectedIndex;
}
public int getToSelectedIndex() {
return toSelectedIndex;
}
}