diff --git a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java
index 748ef00c5..c24a46049 100644
--- a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java
+++ b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java
@@ -590,12 +590,12 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen
if (DEBUG) Log.d(TAG, "onPositionDiscontinuity() called with window index = [" + newWindowIndex + "]");
// If the user selects a new track, then the discontinuity occurs after the index is changed.
- // Therefore, the only source that causes a discrepancy would be autoplay,
+ // Therefore, the only source that causes a discrepancy would be gapless transition,
// which can only offset the current track by +1.
- if (newWindowIndex != playQueue.getIndex() && playbackManager != null) {
+ if (newWindowIndex == playQueue.getIndex() + 1) {
playQueue.offsetIndex(+1);
- playbackManager.load();
}
+ playbackManager.load();
}
@Override
@@ -612,6 +612,8 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen
if (simpleExoPlayer == null) return;
if (DEBUG) Log.d(TAG, "Blocking...");
+ currentItem = null;
+ currentInfo = null;
simpleExoPlayer.stop();
isPrepared = false;
@@ -642,8 +644,8 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen
// Check if on wrong window
final int currentSourceIndex = playQueue.indexOf(item);
if (currentSourceIndex != playQueue.getIndex()) {
- throw new IllegalStateException("Play Queue may be desynchronized: item index=[" +
- currentSourceIndex + "], queue index=[" + playQueue.getIndex() + "]");
+ Log.e(TAG, "Play Queue may be desynchronized: item index=[" + currentSourceIndex +
+ "], queue index=[" + playQueue.getIndex() + "]");
} else if (simpleExoPlayer.getCurrentWindowIndex() != currentSourceIndex) {
final long startPos = info != null ? info.start_position : 0;
if (DEBUG) Log.d(TAG, "Rewinding to correct window: " + currentSourceIndex + " at: " + getTimeString((int)startPos));
@@ -829,15 +831,15 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen
}
public String getVideoUrl() {
- return currentItem == null ? null : currentItem.getUrl();
+ return currentItem == null ? context.getString(R.string.unknown_content) : currentItem.getUrl();
}
public String getVideoTitle() {
- return currentItem == null ? null : currentItem.getTitle();
+ return currentItem == null ? context.getString(R.string.unknown_content) : currentItem.getTitle();
}
public String getUploaderName() {
- return currentItem == null ? null : currentItem.getUploader();
+ return currentItem == null ? context.getString(R.string.unknown_content) : currentItem.getUploader();
}
public boolean isCompleted() {
@@ -873,8 +875,10 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen
}
public PlaybackParameters getPlaybackParameters() {
+ final PlaybackParameters defaultParameters = new PlaybackParameters(1f, 1f);
+ if (simpleExoPlayer == null) return defaultParameters;
final PlaybackParameters parameters = simpleExoPlayer.getPlaybackParameters();
- return parameters == null ? new PlaybackParameters(1f, 1f) : parameters;
+ return parameters == null ? defaultParameters : parameters;
}
public void setPlaybackParameters(float speed, float pitch) {
@@ -903,7 +907,7 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen
final int queuePos = playQueue.getIndex();
final long windowPos = simpleExoPlayer.getCurrentPosition();
- if (windowPos > 0) {
+ if (windowPos > 0 && windowPos <= simpleExoPlayer.getDuration()) {
setRecovery(queuePos, windowPos);
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java
index 89d58141d..71068dbea 100644
--- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java
+++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java
@@ -65,6 +65,7 @@ import org.schabi.newpipe.extractor.services.youtube.YoutubeStreamExtractor;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.VideoStream;
import org.schabi.newpipe.player.event.PlayerEventListener;
+import org.schabi.newpipe.player.helper.PlayerHelper;
import org.schabi.newpipe.player.old.PlayVideoActivity;
import org.schabi.newpipe.player.helper.LockManager;
import org.schabi.newpipe.playlist.PlayQueueItem;
@@ -96,7 +97,6 @@ import static org.schabi.newpipe.util.AnimationUtils.animateView;
public final class PopupVideoPlayer extends Service {
private static final String TAG = ".PopupVideoPlayer";
private static final boolean DEBUG = BasePlayer.DEBUG;
- private static final int SHUTDOWN_FLING_VELOCITY = 10000;
private static final int NOTIFICATION_ID = 40028922;
public static final String ACTION_CLOSE = "org.schabi.newpipe.player.PopupVideoPlayer.CLOSE";
@@ -112,6 +112,9 @@ public final class PopupVideoPlayer extends Service {
private WindowManager.LayoutParams windowLayoutParams;
private GestureDetector gestureDetector;
+ private int shutdownFlingVelocity;
+ private int tossFlingVelocity;
+
private float screenWidth, screenHeight;
private float popupWidth, popupHeight;
@@ -211,12 +214,14 @@ public final class PopupVideoPlayer extends Service {
View rootView = View.inflate(this, R.layout.player_popup, null);
playerImpl.setup(rootView);
+ shutdownFlingVelocity = PlayerHelper.getShutdownFlingVelocity(this);
+ tossFlingVelocity = PlayerHelper.getTossFlingVelocity(this);
+
updateScreenSize();
+ final boolean popupRememberSizeAndPos = PlayerHelper.isRememberingPopupDimensions(this);
+ final float defaultSize = getResources().getDimension(R.dimen.popup_default_width);
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
- boolean popupRememberSizeAndPos = sharedPreferences.getBoolean(getString(R.string.popup_remember_size_pos_key), true);
-
- float defaultSize = getResources().getDimension(R.dimen.popup_default_width);
popupWidth = popupRememberSizeAndPos ? sharedPreferences.getFloat(POPUP_SAVED_WIDTH, defaultSize) : defaultSize;
final int layoutParamType = Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O ? WindowManager.LayoutParams.TYPE_PHONE : WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -791,11 +796,20 @@ public final class PopupVideoPlayer extends Service {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
+ if (DEBUG) Log.d(TAG, "Fling velocity: dX=[" + velocityX + "], dY=[" + velocityY + "]");
if (playerImpl == null) return false;
- if (Math.abs(velocityX) > SHUTDOWN_FLING_VELOCITY) {
- if (DEBUG) Log.d(TAG, "Popup close fling velocity= " + velocityX);
+
+ final float absVelocityX = Math.abs(velocityX);
+ final float absVelocityY = Math.abs(velocityY);
+ if (absVelocityX > shutdownFlingVelocity) {
onClose();
return true;
+ } else if (Math.max(absVelocityX, absVelocityY) > tossFlingVelocity) {
+ if (absVelocityX > tossFlingVelocity) windowLayoutParams.x = (int) velocityX;
+ if (absVelocityY > tossFlingVelocity) windowLayoutParams.y = (int) velocityY;
+ checkPositionBounds();
+ windowManager.updateViewLayout(playerImpl.getRootView(), windowLayoutParams);
+ return true;
}
return false;
}
diff --git a/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java b/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java
index ef77cdda2..4fe228dfc 100644
--- a/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java
@@ -286,6 +286,8 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
+ if (player == null) return false;
+
player.setPlaybackSpeed(playbackSpeed);
return true;
}
@@ -304,6 +306,8 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
+ if (player == null) return false;
+
player.setPlaybackPitch(playbackPitch);
return true;
}
@@ -317,6 +321,8 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
remove.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
+ if (player == null) return false;
+
final int index = player.getPlayQueue().indexOf(item);
if (index != -1) player.getPlayQueue().remove(index);
return true;
@@ -349,7 +355,7 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
final int sourceIndex = source.getLayoutPosition();
final int targetIndex = target.getLayoutPosition();
- player.getPlayQueue().move(sourceIndex, targetIndex);
+ if (player != null) player.getPlayQueue().move(sourceIndex, targetIndex);
return true;
}
@@ -372,11 +378,13 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
return new PlayQueueItemBuilder.OnSelectedListener() {
@Override
public void selected(PlayQueueItem item, View view) {
- player.onSelected(item);
+ if (player != null) player.onSelected(item);
}
@Override
public void held(PlayQueueItem item, View view) {
+ if (player == null) return;
+
final int index = player.getPlayQueue().indexOf(item);
if (index != -1) buildItemPopupMenu(item, view);
}
@@ -403,19 +411,19 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
@Override
public void onClick(View view) {
if (view.getId() == repeatButton.getId()) {
- player.onRepeatClicked();
+ if (player != null) player.onRepeatClicked();
} else if (view.getId() == backwardButton.getId()) {
- player.onPlayPrevious();
+ if (player != null) player.onPlayPrevious();
} else if (view.getId() == playPauseButton.getId()) {
- player.onVideoPlayPause();
+ if (player != null) player.onVideoPlayPause();
} else if (view.getId() == forwardButton.getId()) {
- player.onPlayNext();
+ if (player != null) player.onPlayNext();
} else if (view.getId() == shuffleButton.getId()) {
- player.onShuffleClicked();
+ if (player != null) player.onShuffleClicked();
} else if (view.getId() == playbackSpeedButton.getId()) {
playbackSpeedPopupMenu.show();
@@ -450,7 +458,7 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
- player.simpleExoPlayer.seekTo(seekBar.getProgress());
+ if (player != null) player.simpleExoPlayer.seekTo(seekBar.getProgress());
seekDisplay.setVisibility(View.GONE);
seeking = false;
}
diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java
index 558f82b43..40063ba40 100644
--- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java
@@ -12,6 +12,8 @@ import java.text.NumberFormat;
import java.util.Formatter;
import java.util.Locale;
+import javax.annotation.Nonnull;
+
public class PlayerHelper {
private PlayerHelper() {}
@@ -56,6 +58,10 @@ public class PlayerHelper {
return isUsingOldPlayer(context, false);
}
+ public static boolean isRememberingPopupDimensions(@Nonnull final Context context) {
+ return isRememberingPopupDimensions(context, true);
+ }
+
public static long getPreferredCacheSize(@NonNull final Context context) {
return 64 * 1024 * 1024L;
}
@@ -83,6 +89,15 @@ public class PlayerHelper {
public static boolean isUsingDSP(@NonNull final Context context) {
return true;
}
+
+ public static int getShutdownFlingVelocity(@Nonnull final Context context) {
+ return 10000;
+ }
+
+ public static int getTossFlingVelocity(@Nonnull final Context context) {
+ return 2500;
+ }
+
////////////////////////////////////////////////////////////////////////////
// Private helpers
////////////////////////////////////////////////////////////////////////////
@@ -103,4 +118,8 @@ public class PlayerHelper {
private static boolean isUsingOldPlayer(@NonNull final Context context, final boolean b) {
return getPreferences(context).getBoolean(context.getString(R.string.use_old_player_key), b);
}
+
+ private static boolean isRememberingPopupDimensions(@Nonnull final Context context, final boolean b) {
+ return getPreferences(context).getBoolean(context.getString(R.string.popup_remember_size_pos_key), b);
+ }
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index ad69915b9..7092feaf5 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -122,6 +122,8 @@
NewPipe Notification
Notifications for NewPipe Background and Popup Players
+ [Unknown]
+
Error
Network error