-Modified quality update to no longer invalidate concatenated media sources.

-Improved play queue and timeline update.
This commit is contained in:
John Zhen M 2017-09-14 11:02:18 -07:00 committed by John Zhen Mo
parent 6b16b08712
commit 174d040ca3
3 changed files with 35 additions and 15 deletions

View file

@ -543,23 +543,21 @@ public abstract class BasePlayer implements Player.EventListener,
} }
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////
// ExoPlayer Listener // Timeline
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
@Override private void refreshTimeline() {
public void onTimelineChanged(Timeline timeline, Object manifest) {
if (DEBUG) Log.d(TAG, "onTimelineChanged(), timeline size = " + timeline.getWindowCount());
final int currentSourceIndex = playbackManager.getCurrentSourceIndex(); final int currentSourceIndex = playbackManager.getCurrentSourceIndex();
// Sanity check // Sanity checks
if (currentSourceIndex < 0) return; if (currentSourceIndex < 0) return;
// Check if already playing correct window // Check if already playing correct window
final boolean isCurrentWindowCorrect = simpleExoPlayer.getCurrentWindowIndex() == currentSourceIndex; final boolean isCurrentWindowCorrect = simpleExoPlayer.getCurrentWindowIndex() == currentSourceIndex;
if (isCurrentWindowCorrect && getCurrentState() == STATE_PLAYING) return; 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; if (simpleExoPlayer.getCurrentTimeline().getWindowCount() <= currentSourceIndex) return;
// Check if window is ready // Check if window is ready
@ -574,7 +572,7 @@ public abstract class BasePlayer implements Player.EventListener,
simpleExoPlayer.seekTo(currentSourceIndex, startPos); simpleExoPlayer.seekTo(currentSourceIndex, startPos);
} }
// Check if recovering on correct item // Check if recovering
if (isRecovery && queuePos == playQueue.getIndex() && isCurrentWindowCorrect) { if (isRecovery && queuePos == playQueue.getIndex() && isCurrentWindowCorrect) {
if (DEBUG) Log.d(TAG, "Rewinding to recovery window: " + currentSourceIndex + " at: " + getTimeString((int)videoPos)); if (DEBUG) Log.d(TAG, "Rewinding to recovery window: " + currentSourceIndex + " at: " + getTimeString((int)videoPos));
simpleExoPlayer.seekTo(videoPos); simpleExoPlayer.seekTo(videoPos);
@ -585,6 +583,17 @@ public abstract class BasePlayer implements Player.EventListener,
simpleExoPlayer.setPlayWhenReady(wasPlaying); 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 @Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
} }
@ -699,7 +708,7 @@ public abstract class BasePlayer implements Player.EventListener,
if (DEBUG) Log.d(TAG, "Syncing..."); if (DEBUG) Log.d(TAG, "Syncing...");
currentInfo = info; currentInfo = info;
onTimelineChanged(simpleExoPlayer.getCurrentTimeline(), null); refreshTimeline();
initThumbnail(info.thumbnail_url); initThumbnail(info.thumbnail_url);
} }

View file

@ -12,6 +12,7 @@ import org.schabi.newpipe.playlist.PlayQueue;
import org.schabi.newpipe.playlist.PlayQueueItem; import org.schabi.newpipe.playlist.PlayQueueItem;
import org.schabi.newpipe.playlist.events.PlayQueueMessage; import org.schabi.newpipe.playlist.events.PlayQueueMessage;
import org.schabi.newpipe.playlist.events.RemoveEvent; import org.schabi.newpipe.playlist.events.RemoveEvent;
import org.schabi.newpipe.playlist.events.UpdateEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -71,6 +72,9 @@ public class PlaybackManager {
return sourceToQueueIndex.indexOf(playQueue.getIndex()); return sourceToQueueIndex.indexOf(playQueue.getIndex());
} }
public int size() {
return sourceToQueueIndex.size();
}
public void dispose() { public void dispose() {
if (playQueueReactor != null) playQueueReactor.cancel(); if (playQueueReactor != null) playQueueReactor.cancel();
@ -116,9 +120,13 @@ public class PlaybackManager {
case REMOVE: case REMOVE:
final RemoveEvent removeEvent = (RemoveEvent) event; final RemoveEvent removeEvent = (RemoveEvent) event;
if (removeEvent.isCurrent()) tryBlock(); if (removeEvent.isCurrent()) tryBlock();
remove(removeEvent.index()); remove(removeEvent.index(), true);
break; break;
case UPDATE: case UPDATE:
final UpdateEvent updateEvent = (UpdateEvent) event;
tryBlock();
remove(updateEvent.index(), false);
break;
case SHUFFLE: case SHUFFLE:
tryBlock(); tryBlock();
resetSources(); 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; if (queueIndex < 0) return;
final int sourceIndex = sourceToQueueIndex.indexOf(queueIndex); final int sourceIndex = sourceToQueueIndex.indexOf(queueIndex);
@ -270,9 +278,11 @@ public class PlaybackManager {
sourceToQueueIndex.remove(sourceIndex); sourceToQueueIndex.remove(sourceIndex);
sources.removeMediaSource(sourceIndex); sources.removeMediaSource(sourceIndex);
// Will be slow on really large arrays, fast enough for typical use case if (cascade) {
for (int i = sourceIndex; i < sourceToQueueIndex.size(); i++) { // Will be slow on really large arrays, fast enough for typical use case
sourceToQueueIndex.set(i, sourceToQueueIndex.get(i) - 1); for (int i = sourceIndex; i < sourceToQueueIndex.size(); i++) {
sourceToQueueIndex.set(i, sourceToQueueIndex.get(i) - 1);
}
} }
} }
} }

View file

@ -21,6 +21,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import io.reactivex.BackpressureStrategy; import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable; import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.subjects.BehaviorSubject; import io.reactivex.subjects.BehaviorSubject;
public abstract class PlayQueue implements Serializable { public abstract class PlayQueue implements Serializable {
@ -58,7 +59,7 @@ public abstract class PlayQueue implements Serializable {
broadcastReceiver = Flowable.merge( broadcastReceiver = Flowable.merge(
streamsEventBroadcast.toFlowable(BackpressureStrategy.BUFFER), streamsEventBroadcast.toFlowable(BackpressureStrategy.BUFFER),
indexEventBroadcast.toFlowable(BackpressureStrategy.BUFFER) indexEventBroadcast.toFlowable(BackpressureStrategy.BUFFER)
).startWith(new InitEvent()); ).observeOn(AndroidSchedulers.mainThread()).startWith(new InitEvent());
if (DEBUG) broadcastReceiver.subscribe(getSelfReporter()); if (DEBUG) broadcastReceiver.subscribe(getSelfReporter());
} }