-Modified quality update to no longer invalidate concatenated media sources.
-Improved play queue and timeline update.
This commit is contained in:
parent
6b16b08712
commit
174d040ca3
3 changed files with 35 additions and 15 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
if (cascade) {
|
||||||
// Will be slow on really large arrays, fast enough for typical use case
|
// Will be slow on really large arrays, fast enough for typical use case
|
||||||
for (int i = sourceIndex; i < sourceToQueueIndex.size(); i++) {
|
for (int i = sourceIndex; i < sourceToQueueIndex.size(); i++) {
|
||||||
sourceToQueueIndex.set(i, sourceToQueueIndex.get(i) - 1);
|
sourceToQueueIndex.set(i, sourceToQueueIndex.get(i) - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue