From 1fb3774e0332f39c7ac48ea17b6a82544b29aba7 Mon Sep 17 00:00:00 2001 From: John Zhen Mo Date: Sat, 28 Oct 2017 10:08:01 -0700 Subject: [PATCH] -Changed play queue item building to shrink thumbnail before caching. -Renamed refactor directory in player to helper. -Fixed background player notification update causing lag on older spec models. -Fixed service activity theme not changing after user setting is changed. -Fixed NPE on popup player fling to close. -Fixed audio reactor volume and max volume mixup. -Added correct toast for each player error case. -Fixed button coloring for play queue service activity on landscape. -Changed title and uploader text to marquee for vertical service activity. -Removed cache clearing on every thumbnail load. --- .../newpipe/player/BackgroundPlayer.java | 41 ++-------- .../org/schabi/newpipe/player/BasePlayer.java | 62 +++++++++++---- .../newpipe/player/MainVideoPlayer.java | 37 +-------- .../newpipe/player/PopupVideoPlayer.java | 39 +++------- .../newpipe/player/ServicePlayerActivity.java | 19 ++++- .../schabi/newpipe/player/VideoPlayer.java | 4 +- .../{refactor => helper}/AudioReactor.java | 32 ++++---- .../{refactor => helper}/CacheFactory.java | 2 +- .../{refactor => helper}/LoadController.java | 2 +- .../{refactor => helper}/LockManager.java | 2 +- .../{refactor => helper}/PlayerHelper.java | 5 +- .../newpipe/playlist/PlayQueueAdapter.java | 9 +-- .../playlist/PlayQueueItemBuilder.java | 42 +++++++--- .../activity_player_queue_control.xml | 41 +++++----- .../layout/activity_player_queue_control.xml | 78 +++++++++++-------- app/src/main/res/layout/play_queue_item.xml | 4 +- app/src/main/res/layout/playlist_header.xml | 42 ++++++---- app/src/main/res/values/dimens.xml | 4 + app/src/main/res/values/strings.xml | 6 +- 19 files changed, 248 insertions(+), 223 deletions(-) rename app/src/main/java/org/schabi/newpipe/player/{refactor => helper}/AudioReactor.java (90%) rename app/src/main/java/org/schabi/newpipe/player/{refactor => helper}/CacheFactory.java (98%) rename app/src/main/java/org/schabi/newpipe/player/{refactor => helper}/LoadController.java (98%) rename app/src/main/java/org/schabi/newpipe/player/{refactor => helper}/LockManager.java (97%) rename app/src/main/java/org/schabi/newpipe/player/{refactor => helper}/PlayerHelper.java (96%) diff --git a/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java b/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java index 69b91b970..9a594a2cb 100644 --- a/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java @@ -34,7 +34,6 @@ import android.support.annotation.Nullable; import android.support.v4.app.NotificationCompat; import android.util.Log; import android.widget.RemoteViews; -import android.widget.Toast; import com.google.android.exoplayer2.PlaybackParameters; import com.google.android.exoplayer2.Player; @@ -46,12 +45,12 @@ import org.schabi.newpipe.extractor.MediaFormat; import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.player.event.PlayerEventListener; -import org.schabi.newpipe.player.refactor.LockManager; +import org.schabi.newpipe.player.helper.LockManager; import org.schabi.newpipe.playlist.PlayQueueItem; import org.schabi.newpipe.util.ListHelper; import org.schabi.newpipe.util.ThemeHelper; -import static org.schabi.newpipe.player.refactor.PlayerHelper.getTimeString; +import static org.schabi.newpipe.player.helper.PlayerHelper.getTimeString; /** @@ -163,9 +162,7 @@ public final class BackgroundPlayer extends Service { private void onScreenOnOff(boolean on) { if (DEBUG) Log.d(TAG, "onScreenOnOff() called with: on = [" + on + "]"); shouldUpdateOnProgress = on; - if (on) { - basePlayerImpl.triggerProgressUpdate(); - } + basePlayerImpl.triggerProgressUpdate(); } /*////////////////////////////////////////////////////////////////////////// @@ -207,9 +204,9 @@ public final class BackgroundPlayer extends Service { PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_REPEAT), PendingIntent.FLAG_UPDATE_CURRENT)); remoteViews.setOnClickPendingIntent(R.id.notificationFRewind, - PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_PLAY_NEXT), PendingIntent.FLAG_UPDATE_CURRENT)); - remoteViews.setOnClickPendingIntent(R.id.notificationFForward, PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_PLAY_PREVIOUS), PendingIntent.FLAG_UPDATE_CURRENT)); + remoteViews.setOnClickPendingIntent(R.id.notificationFForward, + PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_PLAY_NEXT), PendingIntent.FLAG_UPDATE_CURRENT)); setRepeatModeIcon(remoteViews, basePlayerImpl.getRepeatMode()); } @@ -299,7 +296,6 @@ public final class BackgroundPlayer extends Service { updateNotification(-1); } - clearThumbnailCache(); } @Override @@ -317,7 +313,9 @@ public final class BackgroundPlayer extends Service { @Override public void onUpdateProgress(int currentProgress, int duration, int bufferPercent) { updateProgress(currentProgress, duration, bufferPercent); + if (!shouldUpdateOnProgress) return; + resetNotification(); if (bigNotRemoteView != null) { bigNotRemoteView.setProgressBar(R.id.notificationProgressBar, duration, currentProgress, false); bigNotRemoteView.setTextViewText(R.id.notificationTime, getTimeString(currentProgress) + " / " + getTimeString(duration)); @@ -325,7 +323,6 @@ public final class BackgroundPlayer extends Service { if (notRemoteView != null) { notRemoteView.setProgressBar(R.id.notificationProgressBar, duration, currentProgress, false); } - updateNotification(-1); } @@ -348,29 +345,6 @@ public final class BackgroundPlayer extends Service { if (bigNotRemoteView != null) bigNotRemoteView.setImageViewBitmap(R.id.notificationCover, null); } - @Override - public void onRecoverableError(Exception exception) { - exception.printStackTrace(); - - if (errorToast == null) { - errorToast = Toast.makeText(context, R.string.player_audio_failure, Toast.LENGTH_SHORT); - errorToast.show(); - } - } - - @Override - public void onUnrecoverableError(Exception exception) { - exception.printStackTrace(); - - if (errorToast != null) { - errorToast.cancel(); - } - errorToast = Toast.makeText(context, R.string.player_unexpected_failure, Toast.LENGTH_SHORT); - errorToast.show(); - - shutdown(); - } - /*////////////////////////////////////////////////////////////////////////// // ExoPlayer Listener //////////////////////////////////////////////////////////////////////////*/ @@ -388,6 +362,7 @@ public final class BackgroundPlayer extends Service { @Override public void onRepeatModeChanged(int i) { + resetNotification(); setRepeatModeIcon(notRemoteView, i); setRepeatModeIcon(bigNotRemoteView, i); updateNotification(-1); 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 2e3fd1303..e9bd60373 100644 --- a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java @@ -65,12 +65,13 @@ import com.google.android.exoplayer2.util.Util; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener; +import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.player.playback.MediaSourceManager; import org.schabi.newpipe.player.playback.PlaybackListener; -import org.schabi.newpipe.player.refactor.AudioReactor; -import org.schabi.newpipe.player.refactor.CacheFactory; -import org.schabi.newpipe.player.refactor.LoadController; +import org.schabi.newpipe.player.helper.AudioReactor; +import org.schabi.newpipe.player.helper.CacheFactory; +import org.schabi.newpipe.player.helper.LoadController; import org.schabi.newpipe.playlist.PlayQueue; import org.schabi.newpipe.playlist.PlayQueueAdapter; import org.schabi.newpipe.playlist.PlayQueueItem; @@ -85,7 +86,7 @@ import io.reactivex.disposables.Disposable; import io.reactivex.functions.Consumer; import io.reactivex.functions.Predicate; -import static org.schabi.newpipe.player.refactor.PlayerHelper.getTimeString; +import static org.schabi.newpipe.player.helper.PlayerHelper.getTimeString; /** * Base for the players, joining the common properties @@ -194,7 +195,7 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen public void initListeners() {} - protected Disposable getProgressReactor() { + private Disposable getProgressReactor() { return Observable.interval(PROGRESS_LOOP_INTERVAL, TimeUnit.MILLISECONDS) .observeOn(AndroidSchedulers.mainThread()) .filter(new Predicate() { @@ -249,7 +250,7 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen playbackManager = new MediaSourceManager(this, playQueue); if (playQueueAdapter != null) playQueueAdapter.dispose(); - playQueueAdapter = new PlayQueueAdapter(playQueue); + playQueueAdapter = new PlayQueueAdapter(context, playQueue); } public void initThumbnail(final String url) { @@ -536,7 +537,7 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen 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.getDuration() > 0 && simpleExoPlayer.getCurrentPosition() >= simpleExoPlayer.getDuration()) { + if (isCurrentWindowValid() && simpleExoPlayer.getCurrentPosition() >= simpleExoPlayer.getDuration()) { changeState(STATE_COMPLETED); isPrepared = false; } @@ -549,10 +550,9 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen * There are multiple types of errors:

* * {@link ExoPlaybackException#TYPE_SOURCE TYPE_SOURCE}:

- * If the current {@link com.google.android.exoplayer2.Timeline.Window window} has - * duration and position greater than 0, then we know the current window is working correctly - * and the error is produced by transitioning into a bad window, therefore we report an error - * to the play queue based on if the current error can be skipped. + * If the current {@link com.google.android.exoplayer2.Timeline.Window window} is valid, + * then we know the error is produced by transitioning into a bad window, therefore we report + * an error to the play queue based on if the current error can be skipped. * * This is done because ExoPlayer reports the source exceptions before window is * transitioned on seamless playback. @@ -579,9 +579,8 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen switch (error.type) { case ExoPlaybackException.TYPE_SOURCE: - final boolean skippable = simpleExoPlayer.getDuration() >= 0 && simpleExoPlayer.getCurrentPosition() >= 0; - playQueue.error(skippable); - onRecoverableError(error); + playQueue.error(isCurrentWindowValid()); + onStreamError(error); break; case ExoPlaybackException.TYPE_UNEXPECTED: onRecoverableError(error); @@ -670,9 +669,35 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen // General Player //////////////////////////////////////////////////////////////////////////*/ - public abstract void onRecoverableError(Exception exception); + public void onStreamError(Exception exception) { + exception.printStackTrace(); - public abstract void onUnrecoverableError(Exception exception); + if (errorToast == null) { + errorToast = Toast.makeText(context, R.string.player_stream_failure, Toast.LENGTH_SHORT); + errorToast.show(); + } + } + + public void onRecoverableError(Exception exception) { + exception.printStackTrace(); + + if (errorToast == null) { + errorToast = Toast.makeText(context, R.string.player_recoverable_failure, Toast.LENGTH_SHORT); + errorToast.show(); + } + } + + public void onUnrecoverableError(Exception exception) { + exception.printStackTrace(); + + if (errorToast != null) { + errorToast.cancel(); + } + errorToast = Toast.makeText(context, R.string.player_unrecoverable_failure, Toast.LENGTH_SHORT); + errorToast.show(); + + shutdown(); + } public void onPrepared(boolean playWhenReady) { if (DEBUG) Log.d(TAG, "onPrepared() called with: playWhenReady = [" + playWhenReady + "]"); @@ -754,6 +779,11 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen simpleExoPlayer.seekTo(progress); } + public boolean isCurrentWindowValid() { + return simpleExoPlayer != null && simpleExoPlayer.getDuration() >= 0 + && simpleExoPlayer.getCurrentPosition() >= 0; + } + /*////////////////////////////////////////////////////////////////////////// // Utils //////////////////////////////////////////////////////////////////////////*/ diff --git a/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java index acdca3d67..f3b05b66a 100644 --- a/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java @@ -23,7 +23,6 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; -import android.graphics.Bitmap; import android.graphics.Color; import android.media.AudioManager; import android.os.Build; @@ -50,7 +49,7 @@ import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.VideoStream; -import org.schabi.newpipe.player.refactor.PlayerHelper; +import org.schabi.newpipe.player.helper.PlayerHelper; import org.schabi.newpipe.playlist.PlayQueueItem; import org.schabi.newpipe.playlist.PlayQueueItemBuilder; import org.schabi.newpipe.playlist.PlayQueueItemHolder; @@ -288,12 +287,6 @@ public final class MainVideoPlayer extends Activity { screenRotationButton.setOnClickListener(this); } - @Override - public void onThumbnailReceived(Bitmap thumbnail) { - super.onThumbnailReceived(thumbnail); - clearThumbnailCache(); - } - /*////////////////////////////////////////////////////////////////////////// // ExoPlayer Video Listener //////////////////////////////////////////////////////////////////////////*/ @@ -439,29 +432,6 @@ public final class MainVideoPlayer extends Activity { if (isPlaying()) hideControls(300, 0); } - @Override - public void onRecoverableError(Exception exception) { - exception.printStackTrace(); - - if (errorToast == null) { - errorToast = Toast.makeText(context, R.string.player_video_failure, Toast.LENGTH_SHORT); - errorToast.show(); - } - } - - @Override - public void onUnrecoverableError(Exception exception) { - exception.printStackTrace(); - - if (errorToast != null) { - errorToast.cancel(); - } - errorToast = Toast.makeText(context, R.string.player_unexpected_failure, Toast.LENGTH_SHORT); - errorToast.show(); - - shutdown(); - } - @Override protected int getDefaultResolutionIndex(final List sortedVideos) { return ListHelper.getDefaultResolutionIndex(context, sortedVideos); @@ -763,11 +733,12 @@ public final class MainVideoPlayer extends Activity { if (e1.getX() > playerImpl.getRootView().getWidth() / 2) { double floor = Math.floor(up ? stepVolume : -stepVolume); - currentVolume = (int) (playerImpl.getAudioReactor().getMaxVolume() + floor); + currentVolume = (int) (playerImpl.getAudioReactor().getVolume() + floor); if (currentVolume >= maxVolume) currentVolume = maxVolume; if (currentVolume <= minVolume) currentVolume = (int) minVolume; - playerImpl.getAudioReactor().setMaxVolume(currentVolume); + playerImpl.getAudioReactor().setVolume(currentVolume); + currentVolume = playerImpl.getAudioReactor().getVolume(); if (DEBUG) Log.d(TAG, "onScroll().volumeControl, currentVolume = " + currentVolume); final String volumeText = volumeUnicode + " " + Math.round((((float) currentVolume) / maxVolume) * 100) + "%"; playerImpl.getVolumeTextView().setText(volumeText); 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 219754ac3..4c13afa82 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java @@ -66,7 +66,7 @@ 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.old.PlayVideoActivity; -import org.schabi.newpipe.player.refactor.LockManager; +import org.schabi.newpipe.player.helper.LockManager; import org.schabi.newpipe.playlist.PlayQueueItem; import org.schabi.newpipe.playlist.SinglePlayQueue; import org.schabi.newpipe.report.ErrorActivity; @@ -85,7 +85,7 @@ import io.reactivex.disposables.Disposable; import io.reactivex.functions.Consumer; import io.reactivex.schedulers.Schedulers; -import static org.schabi.newpipe.player.refactor.PlayerHelper.isUsingOldPlayer; +import static org.schabi.newpipe.player.helper.PlayerHelper.isUsingOldPlayer; import static org.schabi.newpipe.util.AnimationUtils.animateView; /** @@ -366,7 +366,7 @@ public final class PopupVideoPlayer extends Service { } private void updatePopupSize(int width, int height) { - //if (DEBUG) Log.d(TAG, "updatePopupSize() called with: width = [" + width + "], height = [" + height + "]"); + if (DEBUG) Log.d(TAG, "updatePopupSize() called with: width = [" + width + "], height = [" + height + "]"); width = (int) (width > maximumWidth ? maximumWidth : width < minimumWidth ? minimumWidth : width); @@ -440,7 +440,6 @@ public final class PopupVideoPlayer extends Service { updateNotification(-1); } - clearThumbnailCache(); } @Override @@ -481,29 +480,6 @@ public final class PopupVideoPlayer extends Service { if (isPlaying()) hideControls(500, 0); } - @Override - public void onRecoverableError(Exception exception) { - exception.printStackTrace(); - - if (errorToast == null) { - errorToast = Toast.makeText(context, R.string.player_video_failure, Toast.LENGTH_SHORT); - errorToast.show(); - } - } - - @Override - public void onUnrecoverableError(Exception exception) { - exception.printStackTrace(); - - if (errorToast != null) { - errorToast.cancel(); - } - errorToast = Toast.makeText(context, R.string.player_unexpected_failure, Toast.LENGTH_SHORT); - errorToast.show(); - - shutdown(); - } - @Override public void onStopTrackingTouch(SeekBar seekBar) { super.onStopTrackingTouch(seekBar); @@ -737,7 +713,7 @@ public final class PopupVideoPlayer extends Service { public boolean onDoubleTap(MotionEvent e) { if (DEBUG) Log.d(TAG, "onDoubleTap() called with: e = [" + e + "]" + "rawXy = " + e.getRawX() + ", " + e.getRawY() + ", xy = " + e.getX() + ", " + e.getY()); - if (!playerImpl.isPlaying() || !playerImpl.isPlayerReady()) return false; + if (playerImpl == null || !playerImpl.isPlaying() || !playerImpl.isPlayerReady()) return false; if (e.getX() > popupWidth / 2) { playerImpl.onFastForward(); @@ -751,7 +727,7 @@ public final class PopupVideoPlayer extends Service { @Override public boolean onSingleTapConfirmed(MotionEvent e) { if (DEBUG) Log.d(TAG, "onSingleTapConfirmed() called with: e = [" + e + "]"); - if (playerImpl.getPlayer() == null) return false; + if (playerImpl == null || playerImpl.getPlayer() == null) return false; playerImpl.onVideoPlayPause(); return true; } @@ -776,7 +752,7 @@ public final class PopupVideoPlayer extends Service { @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { - if (isResizing) return super.onScroll(e1, e2, distanceX, distanceY); + if (isResizing || playerImpl == null) return super.onScroll(e1, e2, distanceX, distanceY); if (playerImpl.getCurrentState() != BasePlayer.STATE_BUFFERING && (!isMoving || playerImpl.getControlsRoot().getAlpha() != 1f)) playerImpl.showControls(0); @@ -807,6 +783,7 @@ public final class PopupVideoPlayer extends Service { private void onScrollEnd() { if (DEBUG) Log.d(TAG, "onScrollEnd() called"); + if (playerImpl == null) return; if (playerImpl.isControlsVisible() && playerImpl.getCurrentState() == BasePlayer.STATE_PLAYING) { playerImpl.hideControls(300, VideoPlayer.DEFAULT_CONTROLS_HIDE_TIME); } @@ -814,6 +791,7 @@ public final class PopupVideoPlayer extends Service { @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { + if (playerImpl == null) return false; if (Math.abs(velocityX) > SHUTDOWN_FLING_VELOCITY) { if (DEBUG) Log.d(TAG, "Popup close fling velocity= " + velocityX); onClose(); @@ -825,6 +803,7 @@ public final class PopupVideoPlayer extends Service { @Override public boolean onTouch(View v, MotionEvent event) { gestureDetector.onTouchEvent(event); + if (playerImpl == null) return false; if (event.getPointerCount() == 2 && !isResizing) { if (DEBUG) Log.d(TAG, "onTouch() 2 finger pointer detected, enabling resizing."); playerImpl.showAndAnimateControl(-1, true); 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 cc712b1b8..ef77cdda2 100644 --- a/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java +++ b/app/src/main/java/org/schabi/newpipe/player/ServicePlayerActivity.java @@ -36,8 +36,8 @@ import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.ThemeHelper; -import static org.schabi.newpipe.player.refactor.PlayerHelper.formatPitch; -import static org.schabi.newpipe.player.refactor.PlayerHelper.formatSpeed; +import static org.schabi.newpipe.player.helper.PlayerHelper.formatPitch; +import static org.schabi.newpipe.player.helper.PlayerHelper.formatSpeed; public abstract class ServicePlayerActivity extends AppCompatActivity implements PlayerEventListener, SeekBar.OnSeekBarChangeListener, View.OnClickListener { @@ -48,7 +48,7 @@ public abstract class ServicePlayerActivity extends AppCompatActivity protected BasePlayer player; private boolean seeking; - + private boolean redraw; //////////////////////////////////////////////////////////////////////////// // Views //////////////////////////////////////////////////////////////////////////// @@ -119,6 +119,15 @@ public abstract class ServicePlayerActivity extends AppCompatActivity bind(); } + @Override + protected void onResume() { + super.onResume(); + if (redraw) { + recreate(); + redraw = false; + } + } + @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_play_queue, menu); @@ -136,6 +145,7 @@ public abstract class ServicePlayerActivity extends AppCompatActivity return true; case R.id.action_settings: NavigationHelper.openSettings(this); + redraw = true; return true; case R.id.action_system_audio: startActivity(new Intent(Settings.ACTION_SOUND_SETTINGS)); @@ -228,6 +238,8 @@ public abstract class ServicePlayerActivity extends AppCompatActivity metadataArtist = rootView.findViewById(R.id.artist_name); metadata.setOnClickListener(this); + metadataTitle.setSelected(true); + metadataArtist.setSelected(true); } private void buildSeekBar() { @@ -452,7 +464,6 @@ public abstract class ServicePlayerActivity extends AppCompatActivity onStateChanged(state); onPlayModeChanged(repeatMode, shuffled); onPlaybackParameterChanged(parameters); - scrollToSelected(); } @Override diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java index 74c8f6ac8..816c8d0d2 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java @@ -65,8 +65,8 @@ import org.schabi.newpipe.util.ListHelper; import java.util.ArrayList; import java.util.List; -import static org.schabi.newpipe.player.refactor.PlayerHelper.formatSpeed; -import static org.schabi.newpipe.player.refactor.PlayerHelper.getTimeString; +import static org.schabi.newpipe.player.helper.PlayerHelper.formatSpeed; +import static org.schabi.newpipe.player.helper.PlayerHelper.getTimeString; import static org.schabi.newpipe.util.AnimationUtils.animateView; /** diff --git a/app/src/main/java/org/schabi/newpipe/player/refactor/AudioReactor.java b/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java similarity index 90% rename from app/src/main/java/org/schabi/newpipe/player/refactor/AudioReactor.java rename to app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java index ff56503e2..4e031a0dd 100644 --- a/app/src/main/java/org/schabi/newpipe/player/refactor/AudioReactor.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java @@ -1,4 +1,4 @@ -package org.schabi.newpipe.player.refactor; +package org.schabi.newpipe.player.helper; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -17,7 +17,6 @@ import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.audio.AudioRendererEventListener; import com.google.android.exoplayer2.decoder.DecoderCounters; -@SuppressWarnings({"WeakerAccess", "unused"}) public class AudioReactor implements AudioManager.OnAudioFocusChangeListener, AudioRendererEventListener { private static final String TAG = "AudioFocusReactor"; @@ -32,25 +31,22 @@ public class AudioReactor implements AudioManager.OnAudioFocusChangeListener, Au private final Context context; private final AudioManager audioManager; - private AudioFocusRequest request; - - private final boolean isResumeAfterAudioFocusGain; + private final AudioFocusRequest request; public AudioReactor(@NonNull final Context context, @NonNull final SimpleExoPlayer player) { this.player = player; this.context = context; - this.audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); - this.isResumeAfterAudioFocusGain = PlayerHelper.isResumeAfterAudioFocusGain(context); - player.setAudioDebugListener(this); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (shouldBuildFocusRequest()) { request = new AudioFocusRequest.Builder(FOCUS_GAIN_TYPE) .setAcceptsDelayedFocusGain(true) .setWillPauseWhenDucked(true) .setOnAudioFocusChangeListener(this) .build(); + } else { + request = null; } } @@ -59,7 +55,7 @@ public class AudioReactor implements AudioManager.OnAudioFocusChangeListener, Au //////////////////////////////////////////////////////////////////////////*/ public void requestAudioFocus() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (shouldBuildFocusRequest()) { audioManager.requestAudioFocus(request); } else { audioManager.requestAudioFocus(this, STREAM_TYPE, FOCUS_GAIN_TYPE); @@ -67,21 +63,29 @@ public class AudioReactor implements AudioManager.OnAudioFocusChangeListener, Au } public void abandonAudioFocus() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (shouldBuildFocusRequest()) { audioManager.abandonAudioFocusRequest(request); } else { audioManager.abandonAudioFocus(this); } } + public int getVolume() { + return audioManager.getStreamVolume(STREAM_TYPE); + } + public int getMaxVolume() { return audioManager.getStreamMaxVolume(STREAM_TYPE); } - public void setMaxVolume(final int volume) { + public void setVolume(final int volume) { audioManager.setStreamVolume(STREAM_TYPE, volume, 0); } + private boolean shouldBuildFocusRequest() { + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O; + } + /*////////////////////////////////////////////////////////////////////////// // AudioFocus //////////////////////////////////////////////////////////////////////////*/ @@ -108,7 +112,7 @@ public class AudioReactor implements AudioManager.OnAudioFocusChangeListener, Au player.setVolume(DUCK_AUDIO_TO); animateAudio(DUCK_AUDIO_TO, 1f, DUCK_DURATION); - if (isResumeAfterAudioFocusGain) { + if (PlayerHelper.isResumeAfterAudioFocusGain(context)) { player.setPlayWhenReady(true); } } @@ -159,6 +163,8 @@ public class AudioReactor implements AudioManager.OnAudioFocusChangeListener, Au @Override public void onAudioSessionId(int i) { + if (!PlayerHelper.isUsingDSP(context)) return; + final Intent intent = new Intent(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION); intent.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, i); intent.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, context.getPackageName()); diff --git a/app/src/main/java/org/schabi/newpipe/player/refactor/CacheFactory.java b/app/src/main/java/org/schabi/newpipe/player/helper/CacheFactory.java similarity index 98% rename from app/src/main/java/org/schabi/newpipe/player/refactor/CacheFactory.java rename to app/src/main/java/org/schabi/newpipe/player/helper/CacheFactory.java index bd7862f49..dce74ffb5 100644 --- a/app/src/main/java/org/schabi/newpipe/player/refactor/CacheFactory.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/CacheFactory.java @@ -1,4 +1,4 @@ -package org.schabi.newpipe.player.refactor; +package org.schabi.newpipe.player.helper; import android.content.Context; import android.support.annotation.NonNull; diff --git a/app/src/main/java/org/schabi/newpipe/player/refactor/LoadController.java b/app/src/main/java/org/schabi/newpipe/player/helper/LoadController.java similarity index 98% rename from app/src/main/java/org/schabi/newpipe/player/refactor/LoadController.java rename to app/src/main/java/org/schabi/newpipe/player/helper/LoadController.java index 2e8da8207..acc20f5b0 100644 --- a/app/src/main/java/org/schabi/newpipe/player/refactor/LoadController.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/LoadController.java @@ -1,4 +1,4 @@ -package org.schabi.newpipe.player.refactor; +package org.schabi.newpipe.player.helper; import android.content.Context; diff --git a/app/src/main/java/org/schabi/newpipe/player/refactor/LockManager.java b/app/src/main/java/org/schabi/newpipe/player/helper/LockManager.java similarity index 97% rename from app/src/main/java/org/schabi/newpipe/player/refactor/LockManager.java rename to app/src/main/java/org/schabi/newpipe/player/helper/LockManager.java index 9ec841943..1f352159c 100644 --- a/app/src/main/java/org/schabi/newpipe/player/refactor/LockManager.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/LockManager.java @@ -1,4 +1,4 @@ -package org.schabi.newpipe.player.refactor; +package org.schabi.newpipe.player.helper; import android.content.Context; import android.net.wifi.WifiManager; diff --git a/app/src/main/java/org/schabi/newpipe/player/refactor/PlayerHelper.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java similarity index 96% rename from app/src/main/java/org/schabi/newpipe/player/refactor/PlayerHelper.java rename to app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java index 8c4fb340d..558f82b43 100644 --- a/app/src/main/java/org/schabi/newpipe/player/refactor/PlayerHelper.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java @@ -1,4 +1,4 @@ -package org.schabi.newpipe.player.refactor; +package org.schabi.newpipe.player.helper; import android.content.Context; import android.content.SharedPreferences; @@ -80,6 +80,9 @@ public class PlayerHelper { return 5000L; } + public static boolean isUsingDSP(@NonNull final Context context) { + return true; + } //////////////////////////////////////////////////////////////////////////// // Private helpers //////////////////////////////////////////////////////////////////////////// diff --git a/app/src/main/java/org/schabi/newpipe/playlist/PlayQueueAdapter.java b/app/src/main/java/org/schabi/newpipe/playlist/PlayQueueAdapter.java index 72711e4b3..283606074 100644 --- a/app/src/main/java/org/schabi/newpipe/playlist/PlayQueueAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/playlist/PlayQueueAdapter.java @@ -1,5 +1,6 @@ package org.schabi.newpipe.playlist; +import android.content.Context; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.LayoutInflater; @@ -61,8 +62,8 @@ public class PlayQueueAdapter extends RecyclerView.Adapter + android:layout_below="@id/appbar"> @@ -129,17 +129,17 @@ @@ -147,13 +147,14 @@ android:id="@+id/control_progress_bar" style="?android:attr/progressBarStyleLargeInverse" android:layout_width="50dp" - android:layout_height="match_parent" + android:layout_height="50dp" android:layout_centerVertical="true" android:layout_centerHorizontal="true" android:layout_centerInParent="true" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:background="#00000000" + android:tint="?attr/colorAccent" android:padding="2dp" android:clickable="false" android:scaleType="fitCenter" @@ -163,15 +164,15 @@ @@ -189,22 +190,22 @@ android:id="@+id/control_playback_speed" android:layout_width="wrap_content" android:layout_height="35dp" - android:layout_marginLeft="2dp" - android:layout_marginRight="2dp" + android:layout_marginLeft="5dp" + android:layout_marginRight="5dp" android:layout_centerVertical="true" android:layout_toLeftOf="@+id/control_repeat" android:gravity="center" android:minWidth="50dp" android:text="1x" - android:textColor="@android:color/white" + android:textColor="?attr/colorAccent" android:textStyle="bold" android:background="?attr/selectableItemBackground" tools:ignore="HardcodedText,RtlHardcoded"/> @@ -222,8 +224,8 @@ @@ -238,14 +241,14 @@ android:id="@+id/control_playback_pitch" android:layout_width="wrap_content" android:layout_height="35dp" - android:layout_marginLeft="2dp" - android:layout_marginRight="2dp" + android:layout_marginLeft="5dp" + android:layout_marginRight="5dp" android:layout_centerVertical="true" android:layout_toRightOf="@+id/control_shuffle" android:gravity="center" android:minWidth="50dp" android:text="100%" - android:textColor="@android:color/white" + android:textColor="?attr/colorAccent" android:textStyle="bold" android:background="?attr/selectableItemBackground" tools:ignore="HardcodedText,RtlHardcoded"/> diff --git a/app/src/main/res/layout/activity_player_queue_control.xml b/app/src/main/res/layout/activity_player_queue_control.xml index d0bf4b6de..328cedcba 100644 --- a/app/src/main/res/layout/activity_player_queue_control.xml +++ b/app/src/main/res/layout/activity_player_queue_control.xml @@ -41,11 +41,11 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/center" - android:layout_above="@+id/progress_bar"> + android:layout_above="@+id/playback_controls"> @@ -100,11 +106,12 @@ android:id="@+id/progress_bar" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_above="@+id/playback_controls" + android:layout_alignParentBottom="true" android:gravity="center" android:orientation="horizontal" - android:paddingLeft="16dp" - android:paddingRight="16dp"> + android:paddingLeft="12dp" + android:paddingRight="12dp" + android:background="@drawable/player_controls_bg"> @@ -143,72 +152,71 @@ @@ -216,45 +224,49 @@ android:id="@+id/control_progress_bar" style="?android:attr/progressBarStyleLargeInverse" android:layout_width="50dp" - android:layout_height="match_parent" + android:layout_height="50dp" android:layout_centerVertical="true" android:layout_centerHorizontal="true" android:layout_centerInParent="true" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:background="#00000000" + android:tint="?attr/colorAccent" android:padding="2dp" android:clickable="false" android:scaleType="fitCenter" android:indeterminate="true" - android:visibility="invisible"/> + android:visibility="invisible" + tools:visibility="visible"/> @@ -262,14 +274,14 @@ android:id="@+id/control_playback_pitch" android:layout_width="wrap_content" android:layout_height="35dp" - android:layout_marginLeft="2dp" - android:layout_marginRight="2dp" + android:layout_marginLeft="5dp" + android:layout_marginRight="5dp" android:layout_centerVertical="true" android:layout_toRightOf="@+id/control_shuffle" android:gravity="center" android:minWidth="50dp" android:text="100%" - android:textColor="@android:color/white" + android:textColor="?attr/colorAccent" android:textStyle="bold" android:background="?attr/selectableItemBackground" tools:ignore="HardcodedText,RtlHardcoded"/> diff --git a/app/src/main/res/layout/play_queue_item.xml b/app/src/main/res/layout/play_queue_item.xml index 8ae7c4ff3..f4a5f7022 100644 --- a/app/src/main/res/layout/play_queue_item.xml +++ b/app/src/main/res/layout/play_queue_item.xml @@ -12,8 +12,8 @@ + tools:text="Mix musics #23 title Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blanditLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsum" /> -