From a0ba3ce2e4acbc1d84ca3f7e030222003d80b4c5 Mon Sep 17 00:00:00 2001 From: John Zhen M Date: Sun, 17 Sep 2017 20:14:02 -0700 Subject: [PATCH] -Made playback manager load circular. -Improved play previous button to reset before 5 seconds. --- .../newpipe/player/BackgroundPlayer.java | 4 +-- .../org/schabi/newpipe/player/BasePlayer.java | 29 ++++++++++++++++-- .../newpipe/player/MainVideoPlayer.java | 4 +-- .../newpipe/player/PopupVideoPlayer.java | 4 +-- .../player/playback/PlaybackManager.java | 30 ++++++++++++++----- .../schabi/newpipe/playlist/PlayQueue.java | 10 +++++-- .../newpipe/playlist/PlayQueueItem.java | 2 ++ 7 files changed, 63 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java b/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java index 7748ca313..5e9f505bb 100644 --- a/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java @@ -340,7 +340,7 @@ public final class BackgroundPlayer extends Service { public void onFastRewind() { if (!isPlayerReady()) return; - playQueue.offsetIndex(-1); + onPlayPrevious(); triggerProgressUpdate(); } @@ -348,7 +348,7 @@ public final class BackgroundPlayer extends Service { public void onFastForward() { if (!isPlayerReady()) return; - playQueue.offsetIndex(+1); + onPlayNext(); triggerProgressUpdate(); } diff --git a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java index 174ba8d9b..b016d7b29 100644 --- a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java @@ -153,6 +153,7 @@ public abstract class BasePlayer implements Player.EventListener, //////////////////////////////////////////////////////////////////////////*/ public int FAST_FORWARD_REWIND_AMOUNT = 10000; // 10 Seconds + public int PLAY_PREV_ACTIVATION_LIMIT = 5000; // 5 seconds public static final String CACHE_FOLDER_NAME = "exoplayer"; protected SimpleExoPlayer simpleExoPlayer; @@ -659,11 +660,15 @@ public abstract class BasePlayer implements Player.EventListener, @Override public void onPositionDiscontinuity() { // Refresh the playback if there is a transition to the next video - int newIndex = simpleExoPlayer.getCurrentWindowIndex(); - if (DEBUG) Log.d(TAG, "onPositionDiscontinuity() called with: index = [" + newIndex + "]"); + final int newWindowIndex = simpleExoPlayer.getCurrentWindowIndex(); + final int newQueueIndex = playbackManager.getQueueIndexOf(newWindowIndex); + if (DEBUG) Log.d(TAG, "onPositionDiscontinuity() called with: " + + "window index = [" + newWindowIndex + "], queue index = [" + newQueueIndex + "]"); - if (newIndex == playbackManager.getCurrentSourceIndex() + 1) { + if (newQueueIndex == -1) { playQueue.offsetIndex(+1); + } else { + playQueue.setIndex(newQueueIndex); } } @@ -765,6 +770,24 @@ public abstract class BasePlayer implements Player.EventListener, seekBy(FAST_FORWARD_REWIND_AMOUNT); } + public void onPlayPrevious() { + if (simpleExoPlayer == null || playQueue == null || currentInfo == null) return; + if (DEBUG) Log.d(TAG, "onPlayPrevious() called"); + + if (simpleExoPlayer.getCurrentPosition() <= PLAY_PREV_ACTIVATION_LIMIT) { + playQueue.offsetIndex(-1); + } else { + simpleExoPlayer.seekTo(currentInfo.start_position); + } + } + + public void onPlayNext() { + if (playQueue == null) return; + if (DEBUG) Log.d(TAG, "onPlayNext() called"); + + playQueue.offsetIndex(+1); + } + public void seekBy(int milliSeconds) { if (DEBUG) Log.d(TAG, "seekBy() called with: milliSeconds = [" + milliSeconds + "]"); if (simpleExoPlayer == null || (isCompleted() && milliSeconds > 0) || ((milliSeconds < 0 && simpleExoPlayer.getCurrentPosition() == 0))) diff --git a/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java index b77c01ce3..5b4235a55 100644 --- a/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java @@ -468,10 +468,10 @@ public final class MainVideoPlayer extends Activity { if (!playerImpl.isPlayerReady()) return false; if (e.getX() > playerImpl.getRootView().getWidth() / 2) - playerImpl.playQueue.offsetIndex(+1); + playerImpl.onPlayNext(); //playerImpl.onFastForward(); else - playerImpl.playQueue.offsetIndex(-1); + playerImpl.onPlayPrevious(); //playerImpl.onFastRewind(); return true; diff --git a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java index ea04372c0..e138ee3fa 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java @@ -575,10 +575,10 @@ public final class PopupVideoPlayer extends Service { if (e.getX() > popupWidth / 2) { //playerImpl.onFastForward(); - playerImpl.playQueue.offsetIndex(+1); + playerImpl.onPlayNext(); } else { //playerImpl.onFastRewind(); - playerImpl.playQueue.offsetIndex(-1); + playerImpl.onPlayPrevious(); } return true; diff --git a/app/src/main/java/org/schabi/newpipe/player/playback/PlaybackManager.java b/app/src/main/java/org/schabi/newpipe/player/playback/PlaybackManager.java index 3bd2eb08f..a2dc1ec41 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playback/PlaybackManager.java +++ b/app/src/main/java/org/schabi/newpipe/player/playback/PlaybackManager.java @@ -28,7 +28,8 @@ import io.reactivex.functions.Consumer; public class PlaybackManager { private final String TAG = "PlaybackManager@" + Integer.toHexString(hashCode()); // One-side rolling window size for default loading - // Effectively loads WINDOW_SIZE * 2 streams + // Effectively loads WINDOW_SIZE * 2 + 1 streams, should be at least 1 + // todo: inject this parameter, allow user settings perhaps private static final int WINDOW_SIZE = 3; private final PlaybackListener playbackListener; @@ -73,6 +74,11 @@ public class PlaybackManager { return sourceToQueueIndex.indexOf(playQueue.getIndex()); } + public int getQueueIndexOf(final int sourceIndex) { + if (sourceIndex < 0 || sourceIndex >= sourceToQueueIndex.size()) return -1; + return sourceToQueueIndex.get(sourceIndex); + } + public int expectedTimelineSize() { return sources.getSize(); } @@ -210,11 +216,14 @@ public class PlaybackManager { // The rest are just for seamless playback final int leftBound = Math.max(0, currentIndex - WINDOW_SIZE); - final int rightBound = Math.min(playQueue.size(), currentIndex + WINDOW_SIZE); - final List items = playQueue.getStreams().subList(leftBound, rightBound); - for (final PlayQueueItem item: items) { - load(item); - } + final int rightLimit = currentIndex + WINDOW_SIZE + 1; + final int rightBound = Math.min(playQueue.size(), rightLimit); + final List items = new ArrayList<>(playQueue.getStreams().subList(leftBound, rightBound)); + + final int excess = rightLimit - playQueue.size(); + if (excess >= 0) items.addAll(playQueue.getStreams().subList(0, excess)); + + for (final PlayQueueItem item: items) load(item); } private void load(@Nullable final PlayQueueItem item) { @@ -234,7 +243,9 @@ public class PlaybackManager { @Override public void onSuccess(@NonNull StreamInfo streamInfo) { final MediaSource source = playbackListener.sourceOf(streamInfo, item.getSortedQualityIndex()); - insert(playQueue.indexOf(item), source); + final int itemIndex = playQueue.indexOf(item); + // replace all except the currently playing + insert(itemIndex, source, false); if (tryUnblock()) sync(); } @@ -261,7 +272,7 @@ public class PlaybackManager { // Insert source into playlist with position in respect to the play queue // If the play queue index already exists, then the insert is ignored - private void insert(final int queueIndex, final MediaSource source) { + private void insert(final int queueIndex, final MediaSource source, final boolean replace) { if (queueIndex < 0) return; int pos = Collections.binarySearch(sourceToQueueIndex, queueIndex); @@ -269,6 +280,9 @@ public class PlaybackManager { final int sourceIndex = -pos-1; sourceToQueueIndex.add(sourceIndex, queueIndex); sources.addMediaSource(sourceIndex, source); + } else if (replace) { + sources.addMediaSource(pos + 1, source); + sources.removeMediaSource(pos); } } diff --git a/app/src/main/java/org/schabi/newpipe/playlist/PlayQueue.java b/app/src/main/java/org/schabi/newpipe/playlist/PlayQueue.java index 7aac7fb1c..2b9f7a7ee 100644 --- a/app/src/main/java/org/schabi/newpipe/playlist/PlayQueue.java +++ b/app/src/main/java/org/schabi/newpipe/playlist/PlayQueue.java @@ -126,10 +126,14 @@ public abstract class PlayQueue implements Serializable { //////////////////////////////////////////////////////////////////////////*/ public synchronized void setIndex(final int index) { - if (index < 0 || index >= streams.size()) return; + if (index == getIndex()) return; - queueIndex.set(Math.min(Math.max(0, index), streams.size() - 1)); - indexEventBroadcast.onNext(new SelectEvent(index)); + int newIndex = index; + if (index < 0) newIndex = 0; + if (index >= streams.size()) newIndex = isComplete() ? index % streams.size() : streams.size() - 1; + + queueIndex.set(newIndex); + indexEventBroadcast.onNext(new SelectEvent(newIndex)); } public synchronized void offsetIndex(final int offset) { diff --git a/app/src/main/java/org/schabi/newpipe/playlist/PlayQueueItem.java b/app/src/main/java/org/schabi/newpipe/playlist/PlayQueueItem.java index 3f5182375..8860bd143 100644 --- a/app/src/main/java/org/schabi/newpipe/playlist/PlayQueueItem.java +++ b/app/src/main/java/org/schabi/newpipe/playlist/PlayQueueItem.java @@ -37,6 +37,8 @@ public class PlayQueueItem implements Serializable { this.duration = streamInfo.duration; this.sortedQualityIndex = sortedQualityIndex; + + this.stream = Single.just(streamInfo); } PlayQueueItem(final StreamInfoItem streamInfoItem) {