-Added fling to toss popup view when velocity is below shutdown.
-Added string for unknown content. -Fixed NPE when UI element is touched after player shuts down in service activity. -Fixed shuffle reset caused by position discontinuity offsets index. -Moved some more player shared preferences to PlayerHelper.
This commit is contained in:
parent
01e031e7e7
commit
38b2ffd450
|
@ -590,12 +590,12 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen
|
||||||
if (DEBUG) Log.d(TAG, "onPositionDiscontinuity() called with window index = [" + newWindowIndex + "]");
|
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.
|
// 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.
|
// which can only offset the current track by +1.
|
||||||
if (newWindowIndex != playQueue.getIndex() && playbackManager != null) {
|
if (newWindowIndex == playQueue.getIndex() + 1) {
|
||||||
playQueue.offsetIndex(+1);
|
playQueue.offsetIndex(+1);
|
||||||
playbackManager.load();
|
|
||||||
}
|
}
|
||||||
|
playbackManager.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -612,6 +612,8 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen
|
||||||
if (simpleExoPlayer == null) return;
|
if (simpleExoPlayer == null) return;
|
||||||
if (DEBUG) Log.d(TAG, "Blocking...");
|
if (DEBUG) Log.d(TAG, "Blocking...");
|
||||||
|
|
||||||
|
currentItem = null;
|
||||||
|
currentInfo = null;
|
||||||
simpleExoPlayer.stop();
|
simpleExoPlayer.stop();
|
||||||
isPrepared = false;
|
isPrepared = false;
|
||||||
|
|
||||||
|
@ -642,8 +644,8 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen
|
||||||
// Check if on wrong window
|
// Check if on wrong window
|
||||||
final int currentSourceIndex = playQueue.indexOf(item);
|
final int currentSourceIndex = playQueue.indexOf(item);
|
||||||
if (currentSourceIndex != playQueue.getIndex()) {
|
if (currentSourceIndex != playQueue.getIndex()) {
|
||||||
throw new IllegalStateException("Play Queue may be desynchronized: item index=[" +
|
Log.e(TAG, "Play Queue may be desynchronized: item index=[" + currentSourceIndex +
|
||||||
currentSourceIndex + "], queue index=[" + playQueue.getIndex() + "]");
|
"], queue index=[" + playQueue.getIndex() + "]");
|
||||||
} else if (simpleExoPlayer.getCurrentWindowIndex() != currentSourceIndex) {
|
} else if (simpleExoPlayer.getCurrentWindowIndex() != currentSourceIndex) {
|
||||||
final long startPos = info != null ? info.start_position : 0;
|
final long startPos = info != null ? info.start_position : 0;
|
||||||
if (DEBUG) Log.d(TAG, "Rewinding to correct window: " + currentSourceIndex + " at: " + getTimeString((int)startPos));
|
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() {
|
public String getVideoUrl() {
|
||||||
return currentItem == null ? null : currentItem.getUrl();
|
return currentItem == null ? context.getString(R.string.unknown_content) : currentItem.getUrl();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getVideoTitle() {
|
public String getVideoTitle() {
|
||||||
return currentItem == null ? null : currentItem.getTitle();
|
return currentItem == null ? context.getString(R.string.unknown_content) : currentItem.getTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUploaderName() {
|
public String getUploaderName() {
|
||||||
return currentItem == null ? null : currentItem.getUploader();
|
return currentItem == null ? context.getString(R.string.unknown_content) : currentItem.getUploader();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCompleted() {
|
public boolean isCompleted() {
|
||||||
|
@ -873,8 +875,10 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlaybackParameters getPlaybackParameters() {
|
public PlaybackParameters getPlaybackParameters() {
|
||||||
|
final PlaybackParameters defaultParameters = new PlaybackParameters(1f, 1f);
|
||||||
|
if (simpleExoPlayer == null) return defaultParameters;
|
||||||
final PlaybackParameters parameters = simpleExoPlayer.getPlaybackParameters();
|
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) {
|
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 int queuePos = playQueue.getIndex();
|
||||||
final long windowPos = simpleExoPlayer.getCurrentPosition();
|
final long windowPos = simpleExoPlayer.getCurrentPosition();
|
||||||
|
|
||||||
if (windowPos > 0) {
|
if (windowPos > 0 && windowPos <= simpleExoPlayer.getDuration()) {
|
||||||
setRecovery(queuePos, windowPos);
|
setRecovery(queuePos, windowPos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.StreamInfo;
|
||||||
import org.schabi.newpipe.extractor.stream.VideoStream;
|
import org.schabi.newpipe.extractor.stream.VideoStream;
|
||||||
import org.schabi.newpipe.player.event.PlayerEventListener;
|
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.old.PlayVideoActivity;
|
||||||
import org.schabi.newpipe.player.helper.LockManager;
|
import org.schabi.newpipe.player.helper.LockManager;
|
||||||
import org.schabi.newpipe.playlist.PlayQueueItem;
|
import org.schabi.newpipe.playlist.PlayQueueItem;
|
||||||
|
@ -96,7 +97,6 @@ import static org.schabi.newpipe.util.AnimationUtils.animateView;
|
||||||
public final class PopupVideoPlayer extends Service {
|
public final class PopupVideoPlayer extends Service {
|
||||||
private static final String TAG = ".PopupVideoPlayer";
|
private static final String TAG = ".PopupVideoPlayer";
|
||||||
private static final boolean DEBUG = BasePlayer.DEBUG;
|
private static final boolean DEBUG = BasePlayer.DEBUG;
|
||||||
private static final int SHUTDOWN_FLING_VELOCITY = 10000;
|
|
||||||
|
|
||||||
private static final int NOTIFICATION_ID = 40028922;
|
private static final int NOTIFICATION_ID = 40028922;
|
||||||
public static final String ACTION_CLOSE = "org.schabi.newpipe.player.PopupVideoPlayer.CLOSE";
|
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 WindowManager.LayoutParams windowLayoutParams;
|
||||||
private GestureDetector gestureDetector;
|
private GestureDetector gestureDetector;
|
||||||
|
|
||||||
|
private int shutdownFlingVelocity;
|
||||||
|
private int tossFlingVelocity;
|
||||||
|
|
||||||
private float screenWidth, screenHeight;
|
private float screenWidth, screenHeight;
|
||||||
private float popupWidth, popupHeight;
|
private float popupWidth, popupHeight;
|
||||||
|
|
||||||
|
@ -211,12 +214,14 @@ public final class PopupVideoPlayer extends Service {
|
||||||
View rootView = View.inflate(this, R.layout.player_popup, null);
|
View rootView = View.inflate(this, R.layout.player_popup, null);
|
||||||
playerImpl.setup(rootView);
|
playerImpl.setup(rootView);
|
||||||
|
|
||||||
|
shutdownFlingVelocity = PlayerHelper.getShutdownFlingVelocity(this);
|
||||||
|
tossFlingVelocity = PlayerHelper.getTossFlingVelocity(this);
|
||||||
|
|
||||||
updateScreenSize();
|
updateScreenSize();
|
||||||
|
|
||||||
|
final boolean popupRememberSizeAndPos = PlayerHelper.isRememberingPopupDimensions(this);
|
||||||
|
final float defaultSize = getResources().getDimension(R.dimen.popup_default_width);
|
||||||
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
|
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;
|
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;
|
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
|
@Override
|
||||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
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 (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();
|
onClose();
|
||||||
return true;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -286,6 +286,8 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onMenuItemClick(MenuItem menuItem) {
|
public boolean onMenuItemClick(MenuItem menuItem) {
|
||||||
|
if (player == null) return false;
|
||||||
|
|
||||||
player.setPlaybackSpeed(playbackSpeed);
|
player.setPlaybackSpeed(playbackSpeed);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -304,6 +306,8 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onMenuItemClick(MenuItem menuItem) {
|
public boolean onMenuItemClick(MenuItem menuItem) {
|
||||||
|
if (player == null) return false;
|
||||||
|
|
||||||
player.setPlaybackPitch(playbackPitch);
|
player.setPlaybackPitch(playbackPitch);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -317,6 +321,8 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
remove.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
remove.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onMenuItemClick(MenuItem menuItem) {
|
public boolean onMenuItemClick(MenuItem menuItem) {
|
||||||
|
if (player == null) return false;
|
||||||
|
|
||||||
final int index = player.getPlayQueue().indexOf(item);
|
final int index = player.getPlayQueue().indexOf(item);
|
||||||
if (index != -1) player.getPlayQueue().remove(index);
|
if (index != -1) player.getPlayQueue().remove(index);
|
||||||
return true;
|
return true;
|
||||||
|
@ -349,7 +355,7 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
|
|
||||||
final int sourceIndex = source.getLayoutPosition();
|
final int sourceIndex = source.getLayoutPosition();
|
||||||
final int targetIndex = target.getLayoutPosition();
|
final int targetIndex = target.getLayoutPosition();
|
||||||
player.getPlayQueue().move(sourceIndex, targetIndex);
|
if (player != null) player.getPlayQueue().move(sourceIndex, targetIndex);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,11 +378,13 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
return new PlayQueueItemBuilder.OnSelectedListener() {
|
return new PlayQueueItemBuilder.OnSelectedListener() {
|
||||||
@Override
|
@Override
|
||||||
public void selected(PlayQueueItem item, View view) {
|
public void selected(PlayQueueItem item, View view) {
|
||||||
player.onSelected(item);
|
if (player != null) player.onSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void held(PlayQueueItem item, View view) {
|
public void held(PlayQueueItem item, View view) {
|
||||||
|
if (player == null) return;
|
||||||
|
|
||||||
final int index = player.getPlayQueue().indexOf(item);
|
final int index = player.getPlayQueue().indexOf(item);
|
||||||
if (index != -1) buildItemPopupMenu(item, view);
|
if (index != -1) buildItemPopupMenu(item, view);
|
||||||
}
|
}
|
||||||
|
@ -403,19 +411,19 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
if (view.getId() == repeatButton.getId()) {
|
if (view.getId() == repeatButton.getId()) {
|
||||||
player.onRepeatClicked();
|
if (player != null) player.onRepeatClicked();
|
||||||
|
|
||||||
} else if (view.getId() == backwardButton.getId()) {
|
} else if (view.getId() == backwardButton.getId()) {
|
||||||
player.onPlayPrevious();
|
if (player != null) player.onPlayPrevious();
|
||||||
|
|
||||||
} else if (view.getId() == playPauseButton.getId()) {
|
} else if (view.getId() == playPauseButton.getId()) {
|
||||||
player.onVideoPlayPause();
|
if (player != null) player.onVideoPlayPause();
|
||||||
|
|
||||||
} else if (view.getId() == forwardButton.getId()) {
|
} else if (view.getId() == forwardButton.getId()) {
|
||||||
player.onPlayNext();
|
if (player != null) player.onPlayNext();
|
||||||
|
|
||||||
} else if (view.getId() == shuffleButton.getId()) {
|
} else if (view.getId() == shuffleButton.getId()) {
|
||||||
player.onShuffleClicked();
|
if (player != null) player.onShuffleClicked();
|
||||||
|
|
||||||
} else if (view.getId() == playbackSpeedButton.getId()) {
|
} else if (view.getId() == playbackSpeedButton.getId()) {
|
||||||
playbackSpeedPopupMenu.show();
|
playbackSpeedPopupMenu.show();
|
||||||
|
@ -450,7 +458,7 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||||
player.simpleExoPlayer.seekTo(seekBar.getProgress());
|
if (player != null) player.simpleExoPlayer.seekTo(seekBar.getProgress());
|
||||||
seekDisplay.setVisibility(View.GONE);
|
seekDisplay.setVisibility(View.GONE);
|
||||||
seeking = false;
|
seeking = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ import java.text.NumberFormat;
|
||||||
import java.util.Formatter;
|
import java.util.Formatter;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class PlayerHelper {
|
public class PlayerHelper {
|
||||||
private PlayerHelper() {}
|
private PlayerHelper() {}
|
||||||
|
|
||||||
|
@ -56,6 +58,10 @@ public class PlayerHelper {
|
||||||
return isUsingOldPlayer(context, false);
|
return isUsingOldPlayer(context, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isRememberingPopupDimensions(@Nonnull final Context context) {
|
||||||
|
return isRememberingPopupDimensions(context, true);
|
||||||
|
}
|
||||||
|
|
||||||
public static long getPreferredCacheSize(@NonNull final Context context) {
|
public static long getPreferredCacheSize(@NonNull final Context context) {
|
||||||
return 64 * 1024 * 1024L;
|
return 64 * 1024 * 1024L;
|
||||||
}
|
}
|
||||||
|
@ -83,6 +89,15 @@ public class PlayerHelper {
|
||||||
public static boolean isUsingDSP(@NonNull final Context context) {
|
public static boolean isUsingDSP(@NonNull final Context context) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getShutdownFlingVelocity(@Nonnull final Context context) {
|
||||||
|
return 10000;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getTossFlingVelocity(@Nonnull final Context context) {
|
||||||
|
return 2500;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Private helpers
|
// Private helpers
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -103,4 +118,8 @@ public class PlayerHelper {
|
||||||
private static boolean isUsingOldPlayer(@NonNull final Context context, final boolean b) {
|
private static boolean isUsingOldPlayer(@NonNull final Context context, final boolean b) {
|
||||||
return getPreferences(context).getBoolean(context.getString(R.string.use_old_player_key), 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,6 +122,8 @@
|
||||||
<string name="notification_channel_name">NewPipe Notification</string>
|
<string name="notification_channel_name">NewPipe Notification</string>
|
||||||
<string name="notification_channel_description">Notifications for NewPipe Background and Popup Players</string>
|
<string name="notification_channel_description">Notifications for NewPipe Background and Popup Players</string>
|
||||||
|
|
||||||
|
<string name="unknown_content">[Unknown]</string>
|
||||||
|
|
||||||
<!-- error strings -->
|
<!-- error strings -->
|
||||||
<string name="general_error">Error</string>
|
<string name="general_error">Error</string>
|
||||||
<string name="network_error">Network error</string>
|
<string name="network_error">Network error</string>
|
||||||
|
|
Loading…
Reference in New Issue