Skip to content

Commit

Permalink
-Baked recovery records into play queue items.
Browse files Browse the repository at this point in the history
-Added previous and next button on main video player.
-Reverted double tap to seek for popup and main video players.
-Improved shuffling to use recovery record.
-Changed shuffling to place current playing stream to top of queue.
-Fixed exception when removing last item on queue.
-Changed fast forward and rewind button to previous and next on background notification.
-Changed background notification to not update when screen is off and update immediately when screen is turned back on.
-Removed unused intent strings.
-Changed "Append" to "Enqueue" for append text.
  • Loading branch information
karyogamy committed Oct 31, 2017
1 parent 21d42c9 commit 4553850
Show file tree
Hide file tree
Showing 14 changed files with 192 additions and 275 deletions.
24 changes: 10 additions & 14 deletions app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ BasePlayerImpl getBackgroundPlayerInstance() {
/*//////////////////////////////////////////////////////////////////////////
// Notification
//////////////////////////////////////////////////////////////////////////*/

private static final int NOTIFICATION_ID = 123789;
private NotificationManager notificationManager;
private NotificationCompat.Builder notBuilder;
Expand All @@ -101,6 +102,8 @@ BasePlayerImpl getBackgroundPlayerInstance() {
private final String setAlphaMethodName = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) ? "setImageAlpha" : "setAlpha";
private final String setImageResourceMethodName = "setImageResource";

private boolean shouldUpdateOnProgress;

/*//////////////////////////////////////////////////////////////////////////
// Service's LifeCycle
//////////////////////////////////////////////////////////////////////////*/
Expand All @@ -117,6 +120,7 @@ public void onCreate() {
basePlayerImpl.setup();

mBinder = new LocalBinder();
shouldUpdateOnProgress = true;
}

@Override
Expand Down Expand Up @@ -166,12 +170,9 @@ private void onClose() {

private void onScreenOnOff(boolean on) {
if (DEBUG) Log.d(TAG, "onScreenOnOff() called with: on = [" + on + "]");
shouldUpdateOnProgress = on;
if (on) {
if (basePlayerImpl.isPlaying() && !basePlayerImpl.isProgressLoopRunning()) {
basePlayerImpl.startProgressLoop();
}
} else {
basePlayerImpl.stopProgressLoop();
basePlayerImpl.triggerProgressUpdate();
}
}

Expand Down Expand Up @@ -324,14 +325,6 @@ public void onThumbnailReceived(Bitmap thumbnail) {
@Override
public void onPrepared(boolean playWhenReady) {
super.onPrepared(playWhenReady);
if (simpleExoPlayer.getDuration() < 15000) {
FAST_FORWARD_REWIND_AMOUNT = 2000;
} else if (simpleExoPlayer.getDuration() > 60 * 60 * 1000) {
FAST_FORWARD_REWIND_AMOUNT = 60000;
} else {
FAST_FORWARD_REWIND_AMOUNT = 10000;
}
PROGRESS_LOOP_INTERVAL = 1000;
simpleExoPlayer.setVolume(1f);
}

Expand All @@ -343,6 +336,10 @@ public void onShuffleClicked() {

@Override
public void onUpdateProgress(int currentProgress, int duration, int bufferPercent) {
updateProgress(currentProgress, duration, bufferPercent);

if (!shouldUpdateOnProgress) return;

resetNotification();
if (bigNotRemoteView != null) {
if (currentItem != null) {
Expand All @@ -361,7 +358,6 @@ public void onUpdateProgress(int currentProgress, int duration, int bufferPercen
}

updateNotification(-1);
updateProgress(currentProgress, duration, bufferPercent);
}

@Override
Expand Down
123 changes: 35 additions & 88 deletions app/src/main/java/org/schabi/newpipe/player/BasePlayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -122,21 +122,8 @@ public abstract class BasePlayer implements Player.EventListener,
// Intent
//////////////////////////////////////////////////////////////////////////*/

public static final String INTENT_TYPE = "intent_type";
public static final String SINGLE_STREAM = "single";
public static final String EXTERNAL_PLAYLIST = "external";
public static final String INTERNAL_PLAYLIST = "internal";

public static final String VIDEO_URL = "video_url";
public static final String VIDEO_TITLE = "video_title";
public static final String VIDEO_THUMBNAIL_URL = "video_thumbnail_url";
public static final String START_POSITION = "start_position";
public static final String CHANNEL_NAME = "channel_name";
public static final String PLAYBACK_SPEED = "playback_speed";

public static final String PLAY_QUEUE = "play_queue";
public static final String RESTORE_QUEUE_INDEX = "restore_queue_index";
public static final String RESTORE_WINDOW_POS = "restore_window_pos";
public static final String APPEND_ONLY = "append_only";

/*//////////////////////////////////////////////////////////////////////////
Expand All @@ -149,20 +136,17 @@ public abstract class BasePlayer implements Player.EventListener,
protected MediaSourceManager playbackManager;
protected PlayQueue playQueue;

private boolean isRecovery = false;
private int queuePos = 0;
private long videoPos = -1;

protected StreamInfo currentInfo;
protected PlayQueueItem currentItem;

/*//////////////////////////////////////////////////////////////////////////
// Player
//////////////////////////////////////////////////////////////////////////*/

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 final static int FAST_FORWARD_REWIND_AMOUNT = 10000; // 10 Seconds
protected final static int PLAY_PREV_ACTIVATION_LIMIT = 5000; // 5 seconds
protected final static int PROGRESS_LOOP_INTERVAL = 500;
protected final static String CACHE_FOLDER_NAME = "exoplayer";

protected SimpleExoPlayer simpleExoPlayer;
protected boolean isPrepared = false;
Expand All @@ -172,7 +156,6 @@ public abstract class BasePlayer implements Player.EventListener,
protected final DefaultExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
protected final DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();

protected int PROGRESS_LOOP_INTERVAL = 500;
protected Disposable progressUpdateReactor;

//////////////////////////////////////////////////////////////////////////*/
Expand Down Expand Up @@ -269,13 +252,6 @@ public void handleIntent(Intent intent) {
return;
}

// Resolve playback details
if (intent.hasExtra(RESTORE_QUEUE_INDEX) && intent.hasExtra(START_POSITION)) {
setRecovery(
intent.getIntExtra(RESTORE_QUEUE_INDEX, 0),
intent.getLongExtra(START_POSITION, 0)
);
}
setPlaybackSpeed(intent.getFloatExtra(PLAYBACK_SPEED, getPlaybackSpeed()));

// Re-initialization
Expand Down Expand Up @@ -579,6 +555,7 @@ public void onShuffleClicked() {

if (playQueue == null) return;

setRecovery();
if (playQueue.isShuffled()) {
playQueue.unshuffle();
} else {
Expand All @@ -590,26 +567,31 @@ public void onShuffleClicked() {
// ExoPlayer Listener
//////////////////////////////////////////////////////////////////////////*/

@Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
if (DEBUG) Log.d(TAG, "onTimelineChanged(), timeline size = " + timeline.getWindowCount());

private void recover() {
final int currentSourceIndex = playQueue.getIndex();
final PlayQueueItem currentSourceItem = playQueue.getItem();

// Check if already playing correct window
final boolean isCurrentWindowCorrect = simpleExoPlayer.getCurrentWindowIndex() == currentSourceIndex;

// Check if recovering
if (isCurrentWindowCorrect && isRecovery && queuePos == playQueue.getIndex()) {
if (isCurrentWindowCorrect && currentSourceItem != null &&
currentSourceItem.getRecoveryPosition() != PlayQueueItem.RECOVERY_UNSET) {

// todo: figure out exactly why this is the case
/* Rounding time to nearest second as certain media cannot guarantee a sub-second seek
will complete and the player might get stuck in buffering state forever */
final long roundedPos = (videoPos / 1000) * 1000;
final long roundedPos = (currentSourceItem.getRecoveryPosition() / 1000) * 1000;

if (DEBUG) Log.d(TAG, "Rewinding to recovery window: " + currentSourceIndex + " at: " + getTimeString((int)roundedPos));
simpleExoPlayer.seekTo(roundedPos);
isRecovery = false;
simpleExoPlayer.seekTo(currentSourceItem.getRecoveryPosition());
currentSourceItem.resetRecoveryPosition();
}
}

@Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
if (DEBUG) Log.d(TAG, "onTimelineChanged(), timeline size = " + timeline.getWindowCount());

if (playbackManager != null) {
playbackManager.load();
Expand Down Expand Up @@ -653,6 +635,8 @@ public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
}
break;
case Player.STATE_READY: //3
recover();

if (!isPrepared) {
isPrepared = true;
onPrepared(playWhenReady);
Expand All @@ -664,8 +648,7 @@ public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
case Player.STATE_ENDED: // 4
// Ensure the current window has actually ended
// since single windows that are still loading may produce an ended state
if (simpleExoPlayer.isCurrentWindowSeekable() &&
simpleExoPlayer.getCurrentPosition() >= simpleExoPlayer.getDuration()) {
if (simpleExoPlayer.getDuration() > 0 && simpleExoPlayer.getCurrentPosition() >= simpleExoPlayer.getDuration()) {
changeState(STATE_COMPLETED);
isPrepared = false;
}
Expand Down Expand Up @@ -812,11 +795,8 @@ public void onVideoPlayPause() {
else audioManager.abandonAudioFocus(this);

if (getCurrentState() == STATE_COMPLETED) {
if (playQueue.getIndex() == 0) {
simpleExoPlayer.seekToDefaultPosition();
} else {
playQueue.setIndex(0);
}
playQueue.setIndex(0);
simpleExoPlayer.seekToDefaultPosition();
}

simpleExoPlayer.setPlayWhenReady(!isPlaying());
Expand Down Expand Up @@ -877,10 +857,6 @@ public void seekBy(int milliSeconds) {
simpleExoPlayer.seekTo(progress);
}

public boolean isPlaying() {
return simpleExoPlayer.getPlaybackState() == Player.STATE_READY && simpleExoPlayer.getPlayWhenReady();
}

/*//////////////////////////////////////////////////////////////////////////
// Utils
//////////////////////////////////////////////////////////////////////////*/
Expand Down Expand Up @@ -921,24 +897,6 @@ protected void stopProgressLoop() {
progressUpdateReactor = null;
}

protected void tryDeleteCacheFiles(Context context) {
File cacheDir = new File(context.getExternalCacheDir(), CACHE_FOLDER_NAME);

if (cacheDir.exists()) {
try {
if (cacheDir.isDirectory()) {
for (File file : cacheDir.listFiles()) {
try {
if (DEBUG) Log.d(TAG, "tryDeleteCacheFiles: " + file.getAbsolutePath() + " deleted = " + file.delete());
} catch (Exception ignored) {
}
}
}
} catch (Exception ignored) {
}
}
}

public void triggerProgressUpdate() {
onUpdateProgress(
(int) simpleExoPlayer.getCurrentPosition(),
Expand Down Expand Up @@ -992,10 +950,6 @@ public int getCurrentState() {
return currentState;
}

public long getVideoPos() {
return videoPos;
}

public String getVideoUrl() {
return currentItem == null ? null : currentItem.getUrl();
}
Expand All @@ -1012,12 +966,8 @@ public boolean isCompleted() {
return simpleExoPlayer != null && simpleExoPlayer.getPlaybackState() == Player.STATE_ENDED;
}

public boolean isPrepared() {
return isPrepared;
}

public void setPrepared(boolean prepared) {
isPrepared = prepared;
public boolean isPlaying() {
return simpleExoPlayer.getPlaybackState() == Player.STATE_READY && simpleExoPlayer.getPlayWhenReady();
}

public float getPlaybackSpeed() {
Expand Down Expand Up @@ -1045,18 +995,10 @@ public void setPlaybackParameters(float speed, float pitch) {
simpleExoPlayer.setPlaybackParameters(new PlaybackParameters(speed, pitch));
}

public int getCurrentQueueIndex() {
return playQueue != null ? playQueue.getIndex() : -1;
}

public int getCurrentResolutionTarget() {
return trackSelector != null ? trackSelector.getParameters().maxVideoHeight : Integer.MAX_VALUE;
}

public long getPlayerCurrentPosition() {
return simpleExoPlayer != null ? simpleExoPlayer.getCurrentPosition() : 0L;
}

public PlayQueue getPlayQueue() {
return playQueue;
}
Expand All @@ -1069,14 +1011,19 @@ public boolean isProgressLoopRunning() {
return progressUpdateReactor != null && !progressUpdateReactor.isDisposed();
}

public boolean getRecovery() {
return isRecovery;
public void setRecovery() {
if (playQueue == null || simpleExoPlayer == null) return;

final int queuePos = playQueue.getIndex();
final long windowPos = simpleExoPlayer.getCurrentPosition();

setRecovery(queuePos, windowPos);
}

public void setRecovery(final int queuePos, final long windowPos) {
if (playQueue.size() <= queuePos) return;

if (DEBUG) Log.d(TAG, "Setting recovery, queue: " + queuePos + ", pos: " + windowPos);
this.isRecovery = true;
this.queuePos = queuePos;
this.videoPos = windowPos;
playQueue.getItem(queuePos).setRecoveryPosition(windowPos);
}
}
Loading

0 comments on commit 4553850

Please sign in to comment.