1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2024-12-24 09:00:31 +00:00

-Modified player repeat mode to use exoplayer repeat mode.

-Merged playback manager init load logic with normal load logic.
This commit is contained in:
John Zhen M 2017-09-04 15:38:58 -07:00 committed by John Zhen Mo
parent a91ef2ce9e
commit 705028c79d
8 changed files with 109 additions and 159 deletions

View File

@ -35,6 +35,8 @@ import android.support.v4.app.NotificationCompat;
import android.util.Log; import android.util.Log;
import android.widget.RemoteViews; import android.widget.RemoteViews;
import com.google.android.exoplayer2.Player;
import org.schabi.newpipe.BuildConfig; import org.schabi.newpipe.BuildConfig;
import org.schabi.newpipe.MainActivity; import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
@ -192,15 +194,16 @@ public class BackgroundPlayer extends Service {
remoteViews.setOnClickPendingIntent(R.id.notificationFForward, remoteViews.setOnClickPendingIntent(R.id.notificationFForward,
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_FAST_FORWARD), PendingIntent.FLAG_UPDATE_CURRENT)); PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_FAST_FORWARD), PendingIntent.FLAG_UPDATE_CURRENT));
switch (basePlayerImpl.getCurrentRepeatMode()) { switch (basePlayerImpl.simpleExoPlayer.getRepeatMode()) {
case REPEAT_DISABLED: case Player.REPEAT_MODE_OFF:
remoteViews.setInt(R.id.notificationRepeat, setAlphaMethodName, 77); remoteViews.setInt(R.id.notificationRepeat, setAlphaMethodName, 77);
break; break;
case REPEAT_ONE: case Player.REPEAT_MODE_ONE:
// todo change image
remoteViews.setInt(R.id.notificationRepeat, setAlphaMethodName, 255); remoteViews.setInt(R.id.notificationRepeat, setAlphaMethodName, 255);
break; break;
case REPEAT_ALL: case Player.REPEAT_MODE_ALL:
// Waiting :) remoteViews.setInt(R.id.notificationRepeat, setAlphaMethodName, 255);
break; break;
} }
} }
@ -319,14 +322,15 @@ public class BackgroundPlayer extends Service {
int opacity = 255; int opacity = 255;
switch (currentRepeatMode) { switch (currentRepeatMode) {
case REPEAT_DISABLED: case Player.REPEAT_MODE_OFF:
opacity = 77; opacity = 77;
break; break;
case REPEAT_ONE: case Player.REPEAT_MODE_ONE:
opacity = 255; // todo change image
opacity = 168;
break; break;
case REPEAT_ALL: case Player.REPEAT_MODE_ALL:
// Waiting :) opacity = 255;
break; break;
} }
if (notRemoteView != null) notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, opacity); if (notRemoteView != null) notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, opacity);

View File

@ -125,6 +125,9 @@ public abstract class BasePlayer implements Player.EventListener,
protected MediaSourceManager playbackManager; protected MediaSourceManager playbackManager;
protected PlayQueue playQueue; protected PlayQueue playQueue;
private int windowIndex;
private long windowPos;
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////
// Player // Player
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
@ -452,35 +455,36 @@ public abstract class BasePlayer implements Player.EventListener,
public void onCompleted() { public void onCompleted() {
if (DEBUG) Log.d(TAG, "onCompleted() called"); if (DEBUG) Log.d(TAG, "onCompleted() called");
if (isProgressLoopRunning.get()) stopProgressLoop(); if (isProgressLoopRunning.get()) stopProgressLoop();
if (currentRepeatMode == RepeatMode.REPEAT_ONE) {
changeState(STATE_LOADING);
simpleExoPlayer.seekTo(0);
}
} }
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////
// Repeat // Repeat
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
protected RepeatMode currentRepeatMode = RepeatMode.REPEAT_DISABLED; protected int currentRepeatMode = Player.REPEAT_MODE_OFF;
public enum RepeatMode {
REPEAT_DISABLED,
REPEAT_ONE,
REPEAT_ALL
}
public void onRepeatClicked() { public void onRepeatClicked() {
if (DEBUG) Log.d(TAG, "onRepeatClicked() called"); if (DEBUG) Log.d(TAG, "onRepeatClicked() called");
// TODO: implement repeat all when playlist is implemented // TODO: implement repeat all when playlist is implemented
// Switch the modes between DISABLED and REPEAT_ONE, till playlist is implemented final int mode;
setCurrentRepeatMode(getCurrentRepeatMode() == RepeatMode.REPEAT_DISABLED ?
RepeatMode.REPEAT_ONE :
RepeatMode.REPEAT_DISABLED);
if (DEBUG) Log.d(TAG, "onRepeatClicked() currentRepeatMode = " + getCurrentRepeatMode().name()); switch (simpleExoPlayer.getRepeatMode()) {
case Player.REPEAT_MODE_OFF:
mode = Player.REPEAT_MODE_ONE;
break;
case Player.REPEAT_MODE_ONE:
mode = Player.REPEAT_MODE_ALL;
break;
case Player.REPEAT_MODE_ALL:
default:
mode = Player.REPEAT_MODE_OFF;
break;
}
// Switch the modes between DISABLED and REPEAT_ONE, till playlist is implemented
simpleExoPlayer.setRepeatMode(mode);
if (DEBUG) Log.d(TAG, "onRepeatClicked() currentRepeatMode = " + simpleExoPlayer.getRepeatMode());
} }
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////
@ -557,15 +561,10 @@ public abstract class BasePlayer implements Player.EventListener,
// Playback Listener // Playback Listener
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
private int windowIndex;
private long windowPos;
@Override @Override
public void block() { public void block() {
Log.d(TAG, "Blocking..."); Log.d(TAG, "Blocking...");
if (currentState != STATE_PLAYING) return;
simpleExoPlayer.stop(); simpleExoPlayer.stop();
windowIndex = simpleExoPlayer.getCurrentWindowIndex(); windowIndex = simpleExoPlayer.getCurrentWindowIndex();
windowPos = Math.max(0, simpleExoPlayer.getContentPosition()); windowPos = Math.max(0, simpleExoPlayer.getContentPosition());
@ -577,8 +576,6 @@ public abstract class BasePlayer implements Player.EventListener,
public void unblock() { public void unblock() {
Log.d(TAG, "Unblocking..."); Log.d(TAG, "Unblocking...");
if (currentState != STATE_BUFFERING) return;
if (windowIndex != playbackManager.getCurrentSourceIndex()) { if (windowIndex != playbackManager.getCurrentSourceIndex()) {
windowIndex = playbackManager.getCurrentSourceIndex(); windowIndex = playbackManager.getCurrentSourceIndex();
windowPos = 0; windowPos = 0;
@ -587,11 +584,10 @@ public abstract class BasePlayer implements Player.EventListener,
simpleExoPlayer.prepare(playbackManager.getMediaSource()); simpleExoPlayer.prepare(playbackManager.getMediaSource());
simpleExoPlayer.seekTo(windowIndex, windowPos); simpleExoPlayer.seekTo(windowIndex, windowPos);
simpleExoPlayer.setPlayWhenReady(true); simpleExoPlayer.setPlayWhenReady(true);
changeState(STATE_PLAYING);
} }
@Override @Override
public void sync(final int windowIndex, final long windowPos, final StreamInfo info) { public void sync(final int windowIndex, final StreamInfo info) {
Log.d(TAG, "Syncing..."); Log.d(TAG, "Syncing...");
videoUrl = info.url; videoUrl = info.url;
@ -600,22 +596,10 @@ public abstract class BasePlayer implements Player.EventListener,
if (simpleExoPlayer.getCurrentWindowIndex() != windowIndex) { if (simpleExoPlayer.getCurrentWindowIndex() != windowIndex) {
Log.w(TAG, "Rewinding to correct window"); Log.w(TAG, "Rewinding to correct window");
simpleExoPlayer.seekTo(windowIndex, windowPos); simpleExoPlayer.seekTo(windowIndex, 0L);
} else {
simpleExoPlayer.seekTo(windowPos);
} }
} }
@Override
public void init() {
Log.d(TAG, "Initializing...");
if (simpleExoPlayer.getPlaybackState() != Player.STATE_IDLE) simpleExoPlayer.stop();
simpleExoPlayer.prepare(playbackManager.getMediaSource());
simpleExoPlayer.seekToDefaultPosition();
simpleExoPlayer.setPlayWhenReady(true);
}
@Override @Override
public MediaSource sourceOf(final StreamInfo info) { public MediaSource sourceOf(final StreamInfo info) {
return null; return null;
@ -785,14 +769,6 @@ public abstract class BasePlayer implements Player.EventListener,
return sharedPreferences; return sharedPreferences;
} }
public RepeatMode getCurrentRepeatMode() {
return currentRepeatMode;
}
public void setCurrentRepeatMode(RepeatMode mode) {
currentRepeatMode = mode;
}
public int getCurrentState() { public int getCurrentState() {
return currentState; return currentState;
} }

View File

@ -39,6 +39,8 @@ import android.widget.SeekBar;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.google.android.exoplayer2.Player;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.util.AnimationUtils; import org.schabi.newpipe.util.AnimationUtils;
@ -229,8 +231,8 @@ public class MainVideoPlayer extends Activity {
} }
@Override @Override
public void sync(final int windowIndex, final long windowPos, final StreamInfo info) { public void sync(final int windowIndex, final StreamInfo info) {
super.sync(windowIndex, windowPos, info); super.sync(windowIndex, info);
titleTextView.setText(getVideoTitle()); titleTextView.setText(getVideoTitle());
channelTextView.setText(getUploaderName()); channelTextView.setText(getUploaderName());
@ -266,19 +268,22 @@ public class MainVideoPlayer extends Activity {
public void onRepeatClicked() { public void onRepeatClicked() {
super.onRepeatClicked(); super.onRepeatClicked();
if (DEBUG) Log.d(TAG, "onRepeatClicked() called"); if (DEBUG) Log.d(TAG, "onRepeatClicked() called");
switch (getCurrentRepeatMode()) { switch (simpleExoPlayer.getRepeatMode()) {
case REPEAT_DISABLED: case Player.REPEAT_MODE_OFF:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) repeatButton.setImageAlpha(77); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) repeatButton.setImageAlpha(77);
else repeatButton.setAlpha(77); else repeatButton.setAlpha(77);
break; break;
case REPEAT_ONE: case Player.REPEAT_MODE_ONE:
// todo change image
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) repeatButton.setImageAlpha(168);
else repeatButton.setAlpha(168);
break;
case Player.REPEAT_MODE_ALL:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) repeatButton.setImageAlpha(255); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) repeatButton.setImageAlpha(255);
else repeatButton.setAlpha(255); else repeatButton.setAlpha(255);
break;
case REPEAT_ALL:
// Waiting :)
break; break;
} }
} }
@ -387,9 +392,6 @@ public class MainVideoPlayer extends Activity {
@Override @Override
public void onCompleted() { public void onCompleted() {
if (getCurrentRepeatMode() == RepeatMode.REPEAT_ONE) {
playPauseButton.setImageResource(R.drawable.ic_pause_white);
} else {
showSystemUi(); showSystemUi();
animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 0, 0, new Runnable() { animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, false, 0, 0, new Runnable() {
@Override @Override
@ -398,7 +400,7 @@ public class MainVideoPlayer extends Activity {
animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, true, 300); animateView(playPauseButton, AnimationUtils.Type.SCALE_AND_ALPHA, true, 300);
} }
}); });
}
getRootView().setKeepScreenOn(false); getRootView().setKeepScreenOn(false);
super.onCompleted(); super.onCompleted();
} }

View File

@ -1,5 +1,6 @@
package org.schabi.newpipe.player; package org.schabi.newpipe.player;
import android.support.annotation.Nullable;
import android.util.Log; import android.util.Log;
import com.google.android.exoplayer2.source.DynamicConcatenatingMediaSource; import com.google.android.exoplayer2.source.DynamicConcatenatingMediaSource;
@ -48,13 +49,6 @@ class MediaSourceManager {
private boolean isBlocked; private boolean isBlocked;
interface PlaybackListener { interface PlaybackListener {
/*
* Called when the initial video has been loaded.
* Signals to the listener that the media source is prepared, and
* the player is ready to go.
* */
void init();
/* /*
* Called when the stream at the current queue index is not ready yet. * Called when the stream at the current queue index is not ready yet.
* Signals to the listener to block the player from playing anything. * Signals to the listener to block the player from playing anything.
@ -73,7 +67,7 @@ class MediaSourceManager {
* Signals to the listener to synchronize the player's window to the manager's * Signals to the listener to synchronize the player's window to the manager's
* window. * window.
* */ * */
void sync(final int windowIndex, final long windowPos, final StreamInfo info); void sync(final int windowIndex, final StreamInfo info);
/* /*
* Requests the listener to resolve a stream info into a media source respective * Requests the listener to resolve a stream info into a media source respective
@ -132,7 +126,7 @@ class MediaSourceManager {
playQueue.remove(index); playQueue.remove(index);
resetSources(); resetSources();
init(); load();
} }
void dispose() { void dispose() {
@ -163,8 +157,7 @@ class MediaSourceManager {
// why no pattern matching in Java =( // why no pattern matching in Java =(
switch (event.type()) { switch (event.type()) {
case INIT: case INIT:
init(); isBlocked = true;
break;
case APPEND: case APPEND:
load(); load();
break; break;
@ -213,18 +206,22 @@ class MediaSourceManager {
return getCurrentSourceIndex() != -1; return getCurrentSourceIndex() != -1;
} }
private void tryBlock() { private boolean tryBlock() {
if (!isBlocked) { if (!isBlocked) {
playbackListener.block(); playbackListener.block();
isBlocked = true; isBlocked = true;
return true;
} }
return false;
} }
private void tryUnblock() { private boolean tryUnblock() {
if (isPlayQueueReady() && isCurrentIndexLoaded() && isBlocked) { if (isPlayQueueReady() && isCurrentIndexLoaded() && isBlocked) {
isBlocked = false; isBlocked = false;
playbackListener.unblock(); playbackListener.unblock();
return true;
} }
return false;
} }
/* /*
@ -246,7 +243,7 @@ class MediaSourceManager {
final Consumer<StreamInfo> onSuccess = new Consumer<StreamInfo>() { final Consumer<StreamInfo> onSuccess = new Consumer<StreamInfo>() {
@Override @Override
public void accept(StreamInfo streamInfo) throws Exception { public void accept(StreamInfo streamInfo) throws Exception {
playbackListener.sync(getCurrentSourceIndex(), 0L, streamInfo); playbackListener.sync(getCurrentSourceIndex(), streamInfo);
} }
}; };
@ -254,9 +251,12 @@ class MediaSourceManager {
} }
private void load() { private void load() {
// The current item has higher priority
final int currentIndex = playQueue.getIndex(); final int currentIndex = playQueue.getIndex();
load(playQueue.get(currentIndex)); final PlayQueueItem currentItem = playQueue.get(currentIndex);
if (currentItem != null) load(currentItem);
// The rest are just for seamless playback
final int leftBound = Math.max(0, currentIndex - WINDOW_SIZE); final int leftBound = Math.max(0, currentIndex - WINDOW_SIZE);
final int rightBound = Math.min(playQueue.size(), currentIndex + WINDOW_SIZE); final int rightBound = Math.min(playQueue.size(), currentIndex + WINDOW_SIZE);
final List<PlayQueueItem> items = playQueue.getStreams().subList(leftBound, rightBound); final List<PlayQueueItem> items = playQueue.getStreams().subList(leftBound, rightBound);
@ -265,42 +265,9 @@ class MediaSourceManager {
} }
} }
private void init() { private void load(@Nullable final PlayQueueItem item) {
final PlayQueueItem init = playQueue.getCurrent(); if (item == null) return;
init.getStream().subscribe(new SingleObserver<StreamInfo>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
if (disposables != null) {
disposables.add(d);
} else {
d.dispose();
}
}
@Override
public void onSuccess(@NonNull StreamInfo streamInfo) {
final MediaSource source = playbackListener.sourceOf(streamInfo);
insert(playQueue.indexOf(init), source);
if (getCurrentSourceIndex() != -1) {
playbackListener.init();
sync();
load();
} else {
init();
}
}
@Override
public void onError(@NonNull Throwable e) {
playQueue.remove(playQueue.indexOf(init));
init();
}
});
}
private void load(final PlayQueueItem item) {
item.getStream().subscribe(new SingleObserver<StreamInfo>() { item.getStream().subscribe(new SingleObserver<StreamInfo>() {
@Override @Override
public void onSubscribe(@NonNull Disposable d) { public void onSubscribe(@NonNull Disposable d) {
@ -315,7 +282,7 @@ class MediaSourceManager {
public void onSuccess(@NonNull StreamInfo streamInfo) { public void onSuccess(@NonNull StreamInfo streamInfo) {
final MediaSource source = playbackListener.sourceOf(streamInfo); final MediaSource source = playbackListener.sourceOf(streamInfo);
insert(playQueue.indexOf(item), source); insert(playQueue.indexOf(item), source);
tryUnblock(); if (tryUnblock()) sync();
} }
@Override @Override

View File

@ -49,6 +49,7 @@ import android.widget.SeekBar;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.google.android.exoplayer2.Player;
import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener; import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
@ -266,14 +267,14 @@ public class PopupVideoPlayer extends Service {
notRemoteView.setOnClickPendingIntent(R.id.notificationRepeat, notRemoteView.setOnClickPendingIntent(R.id.notificationRepeat,
PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_REPEAT), PendingIntent.FLAG_UPDATE_CURRENT)); PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_REPEAT), PendingIntent.FLAG_UPDATE_CURRENT));
switch (playerImpl.getCurrentRepeatMode()) { switch (playerImpl.simpleExoPlayer.getRepeatMode()) {
case REPEAT_DISABLED: case Player.REPEAT_MODE_OFF:
notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, 77); notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, 77);
break; break;
case REPEAT_ONE: case Player.REPEAT_MODE_ONE:
notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, 255); notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, 255);
break; break;
case REPEAT_ALL: case Player.REPEAT_MODE_ALL:
// Waiting :) // Waiting :)
break; break;
} }
@ -446,18 +447,19 @@ public class PopupVideoPlayer extends Service {
@Override @Override
public void onRepeatClicked() { public void onRepeatClicked() {
super.onRepeatClicked(); super.onRepeatClicked();
switch (getCurrentRepeatMode()) { switch (simpleExoPlayer.getRepeatMode()) {
case REPEAT_DISABLED: case Player.REPEAT_MODE_OFF:
// Drawable didn't work on low API :/ // Drawable didn't work on low API :/
//notRemoteView.setImageViewResource(R.id.notificationRepeat, R.drawable.ic_repeat_disabled_white); //notRemoteView.setImageViewResource(R.id.notificationRepeat, R.drawable.ic_repeat_disabled_white);
// Set the icon to 30% opacity - 255 (max) * .3 // Set the icon to 30% opacity - 255 (max) * .3
notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, 77); notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, 77);
break; break;
case REPEAT_ONE: case Player.REPEAT_MODE_ONE:
notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, 255); // todo change image
notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, 168);
break; break;
case REPEAT_ALL: case Player.REPEAT_MODE_ALL:
// Waiting :) notRemoteView.setInt(R.id.notificationRepeat, setAlphaMethodName, 255);
break; break;
} }
updateNotification(-1); updateNotification(-1);

View File

@ -204,7 +204,6 @@ public abstract class VideoPlayer extends BasePlayer implements SimpleExoPlayer.
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void handleSingleStreamIntent(Intent intent) { public void handleSingleStreamIntent(Intent intent) {
super.handleIntent(intent);
if (DEBUG) Log.d(TAG, "handleIntent() called with: intent = [" + intent + "]"); if (DEBUG) Log.d(TAG, "handleIntent() called with: intent = [" + intent + "]");
if (intent == null) return; if (intent == null) return;
@ -224,6 +223,8 @@ public abstract class VideoPlayer extends BasePlayer implements SimpleExoPlayer.
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void handleIntent(Intent intent) { public void handleIntent(Intent intent) {
super.handleIntent(intent);
if (intent == null) return; if (intent == null) return;
handleExternalPlaylistIntent(intent); handleExternalPlaylistIntent(intent);
@ -254,17 +255,15 @@ public abstract class VideoPlayer extends BasePlayer implements SimpleExoPlayer.
} }
@Override @Override
public void sync(final int windowIndex, final long windowPos, final StreamInfo info) { public void sync(final int windowIndex, final StreamInfo info) {
super.sync(windowIndex, windowPos, info); super.sync(windowIndex, info);
final List<VideoStream> videos = ListHelper.getSortedStreamVideosList(context, info.video_streams, info.video_only_streams, false);
videoStreamsList = new ArrayList<>(videos);
selectedIndexStream = ListHelper.getDefaultResolutionIndex(context, videos);
qualityPopupMenu.getMenu().removeGroup(qualityPopupMenuGroupId); qualityPopupMenu.getMenu().removeGroup(qualityPopupMenuGroupId);
for (int i = 0; i < info.video_streams.size(); i++) { buildQualityMenu(qualityPopupMenu);
VideoStream videoStream = info.video_streams.get(i);
qualityPopupMenu.getMenu().add(qualityPopupMenuGroupId, i, Menu.NONE, MediaFormat.getNameById(videoStream.format) + " " + videoStream.resolution);
}
qualityTextView.setText(info.video_streams.get(selectedIndexStream).resolution);
qualityPopupMenu.setOnMenuItemClickListener(this);
qualityPopupMenu.setOnDismissListener(this);
playbackSpeedPopupMenu.getMenu().removeGroup(playbackSpeedPopupMenuGroupId); playbackSpeedPopupMenu.getMenu().removeGroup(playbackSpeedPopupMenuGroupId);
buildPlaybackSpeedMenu(playbackSpeedPopupMenu); buildPlaybackSpeedMenu(playbackSpeedPopupMenu);
@ -409,11 +408,6 @@ public abstract class VideoPlayer extends BasePlayer implements SimpleExoPlayer.
playbackSeekBar.getThumb().setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN); playbackSeekBar.getThumb().setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN);
animateView(surfaceForeground, true, 100); animateView(surfaceForeground, true, 100);
if (currentRepeatMode == RepeatMode.REPEAT_ONE) {
changeState(STATE_LOADING);
simpleExoPlayer.seekTo(0);
}
} }
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////

View File

@ -3,6 +3,7 @@ package org.schabi.newpipe.playlist;
import android.util.Log; import android.util.Log;
import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.ListExtractor;
import org.schabi.newpipe.extractor.playlist.PlaylistInfo; import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.util.ExtractorHelper; import org.schabi.newpipe.util.ExtractorHelper;
@ -53,15 +54,15 @@ public class ExternalPlayQueue extends PlayQueue {
@Override @Override
public void fetch() { public void fetch() {
ExtractorHelper.getPlaylistInfo(this.serviceId, this.playlistUrl, false) ExtractorHelper.getMorePlaylistItems(this.serviceId, this.playlistUrl)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.retry(RETRY_COUNT) .retry(RETRY_COUNT)
.subscribe(getPlaylistObserver()); .subscribe(getPlaylistObserver());
} }
private SingleObserver<PlaylistInfo> getPlaylistObserver() { private SingleObserver<ListExtractor.NextItemsResult> getPlaylistObserver() {
return new SingleObserver<PlaylistInfo>() { return new SingleObserver<ListExtractor.NextItemsResult>() {
@Override @Override
public void onSubscribe(@NonNull Disposable d) { public void onSubscribe(@NonNull Disposable d) {
if (isComplete || (fetchReactor != null && !fetchReactor.isDisposed())) { if (isComplete || (fetchReactor != null && !fetchReactor.isDisposed())) {
@ -72,11 +73,11 @@ public class ExternalPlayQueue extends PlayQueue {
} }
@Override @Override
public void onSuccess(@NonNull PlaylistInfo playlistInfo) { public void onSuccess(@NonNull ListExtractor.NextItemsResult result) {
if (!playlistInfo.has_more_streams) isComplete = true; if (!result.hasMoreStreams()) isComplete = true;
playlistUrl = playlistInfo.next_streams_url; playlistUrl = result.nextItemsUrl;
append(extractPlaylistItems(playlistInfo.related_streams)); append(extractPlaylistItems(result.nextItemsList));
} }
@Override @Override

View File

@ -87,6 +87,10 @@ public abstract class PlayQueue {
return streams.size(); return streams.size();
} }
public boolean isEmpty() {
return streams.isEmpty();
}
@NonNull @NonNull
public List<PlayQueueItem> getStreams() { public List<PlayQueueItem> getStreams() {
return Collections.unmodifiableList(streams); return Collections.unmodifiableList(streams);