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 dc5ed49f5..929a0302c 100644 --- a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java @@ -543,23 +543,21 @@ public abstract class BasePlayer implements Player.EventListener, } /*////////////////////////////////////////////////////////////////////////// - // ExoPlayer Listener + // Timeline //////////////////////////////////////////////////////////////////////////*/ - @Override - public void onTimelineChanged(Timeline timeline, Object manifest) { - if (DEBUG) Log.d(TAG, "onTimelineChanged(), timeline size = " + timeline.getWindowCount()); - + private void refreshTimeline() { final int currentSourceIndex = playbackManager.getCurrentSourceIndex(); - // Sanity check + // Sanity checks if (currentSourceIndex < 0) return; // Check if already playing correct window final boolean isCurrentWindowCorrect = simpleExoPlayer.getCurrentWindowIndex() == currentSourceIndex; if (isCurrentWindowCorrect && getCurrentState() == STATE_PLAYING) return; - // Check timeline has window + // Check timeline is up-to-date and has window + if (playbackManager.size() != simpleExoPlayer.getCurrentTimeline().getWindowCount()) return; if (simpleExoPlayer.getCurrentTimeline().getWindowCount() <= currentSourceIndex) return; // Check if window is ready @@ -574,7 +572,7 @@ public abstract class BasePlayer implements Player.EventListener, simpleExoPlayer.seekTo(currentSourceIndex, startPos); } - // Check if recovering on correct item + // Check if recovering if (isRecovery && queuePos == playQueue.getIndex() && isCurrentWindowCorrect) { if (DEBUG) Log.d(TAG, "Rewinding to recovery window: " + currentSourceIndex + " at: " + getTimeString((int)videoPos)); simpleExoPlayer.seekTo(videoPos); @@ -585,6 +583,17 @@ public abstract class BasePlayer implements Player.EventListener, simpleExoPlayer.setPlayWhenReady(wasPlaying); } + /*////////////////////////////////////////////////////////////////////////// + // ExoPlayer Listener + //////////////////////////////////////////////////////////////////////////*/ + + @Override + public void onTimelineChanged(Timeline timeline, Object manifest) { + if (DEBUG) Log.d(TAG, "onTimelineChanged(), timeline size = " + timeline.getWindowCount()); + + refreshTimeline(); + } + @Override public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { } @@ -699,7 +708,7 @@ public abstract class BasePlayer implements Player.EventListener, if (DEBUG) Log.d(TAG, "Syncing..."); currentInfo = info; - onTimelineChanged(simpleExoPlayer.getCurrentTimeline(), null); + refreshTimeline(); initThumbnail(info.thumbnail_url); } 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 a34a38198..3b12e517d 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 @@ -12,6 +12,7 @@ import org.schabi.newpipe.playlist.PlayQueue; import org.schabi.newpipe.playlist.PlayQueueItem; import org.schabi.newpipe.playlist.events.PlayQueueMessage; import org.schabi.newpipe.playlist.events.RemoveEvent; +import org.schabi.newpipe.playlist.events.UpdateEvent; import java.util.ArrayList; import java.util.Collections; @@ -71,6 +72,9 @@ public class PlaybackManager { return sourceToQueueIndex.indexOf(playQueue.getIndex()); } + public int size() { + return sourceToQueueIndex.size(); + } public void dispose() { if (playQueueReactor != null) playQueueReactor.cancel(); @@ -116,9 +120,13 @@ public class PlaybackManager { case REMOVE: final RemoveEvent removeEvent = (RemoveEvent) event; if (removeEvent.isCurrent()) tryBlock(); - remove(removeEvent.index()); + remove(removeEvent.index(), true); break; case UPDATE: + final UpdateEvent updateEvent = (UpdateEvent) event; + tryBlock(); + remove(updateEvent.index(), false); + break; case SHUFFLE: tryBlock(); resetSources(); @@ -261,7 +269,7 @@ public class PlaybackManager { } } - private void remove(final int queueIndex) { + private void remove(final int queueIndex, final boolean cascade) { if (queueIndex < 0) return; final int sourceIndex = sourceToQueueIndex.indexOf(queueIndex); @@ -270,9 +278,11 @@ public class PlaybackManager { sourceToQueueIndex.remove(sourceIndex); sources.removeMediaSource(sourceIndex); - // Will be slow on really large arrays, fast enough for typical use case - for (int i = sourceIndex; i < sourceToQueueIndex.size(); i++) { - sourceToQueueIndex.set(i, sourceToQueueIndex.get(i) - 1); + if (cascade) { + // Will be slow on really large arrays, fast enough for typical use case + for (int i = sourceIndex; i < sourceToQueueIndex.size(); i++) { + sourceToQueueIndex.set(i, sourceToQueueIndex.get(i) - 1); + } } } } 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 14698b402..6e53fcfca 100644 --- a/app/src/main/java/org/schabi/newpipe/playlist/PlayQueue.java +++ b/app/src/main/java/org/schabi/newpipe/playlist/PlayQueue.java @@ -21,6 +21,7 @@ import java.util.concurrent.atomic.AtomicInteger; import io.reactivex.BackpressureStrategy; import io.reactivex.Flowable; +import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.subjects.BehaviorSubject; public abstract class PlayQueue implements Serializable { @@ -58,7 +59,7 @@ public abstract class PlayQueue implements Serializable { broadcastReceiver = Flowable.merge( streamsEventBroadcast.toFlowable(BackpressureStrategy.BUFFER), indexEventBroadcast.toFlowable(BackpressureStrategy.BUFFER) - ).startWith(new InitEvent()); + ).observeOn(AndroidSchedulers.mainThread()).startWith(new InitEvent()); if (DEBUG) broadcastReceiver.subscribe(getSelfReporter()); }