-Made playback manager load circular.

-Improved play previous button to reset before 5 seconds.
This commit is contained in:
John Zhen M 2017-09-17 20:14:02 -07:00 committed by John Zhen Mo
parent 6b816a11f7
commit a0ba3ce2e4
7 changed files with 63 additions and 20 deletions

View file

@ -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();
}

View file

@ -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)))

View file

@ -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;

View file

@ -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;

View file

@ -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<PlayQueueItem> 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<PlayQueueItem> 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);
}
}

View file

@ -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) {

View file

@ -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) {