mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2025-10-22 10:57:38 +00:00
-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.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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<Long>() {
|
||||
@@ -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: <br><br>
|
||||
*
|
||||
* {@link ExoPlaybackException#TYPE_SOURCE TYPE_SOURCE}: <br><br>
|
||||
* 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
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@@ -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<VideoStream> 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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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());
|
||||
@@ -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;
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.schabi.newpipe.player.refactor;
|
||||
package org.schabi.newpipe.player.helper;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
@@ -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;
|
||||
@@ -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
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@@ -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<RecyclerView.ViewHold
|
||||
public View view;
|
||||
}
|
||||
|
||||
public PlayQueueAdapter(final PlayQueue playQueue) {
|
||||
this.playQueueItemBuilder = new PlayQueueItemBuilder();
|
||||
public PlayQueueAdapter(final Context context, final PlayQueue playQueue) {
|
||||
this.playQueueItemBuilder = new PlayQueueItemBuilder(context);
|
||||
this.playQueue = playQueue;
|
||||
|
||||
startReactor();
|
||||
@@ -94,9 +95,7 @@ public class PlayQueueAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||
}
|
||||
};
|
||||
|
||||
playQueue.getBroadcastReceiver()
|
||||
.toObservable()
|
||||
.subscribe(observer);
|
||||
playQueue.getBroadcastReceiver().toObservable().subscribe(observer);
|
||||
}
|
||||
|
||||
private void onPlayQueueChanged(final PlayQueueEvent message) {
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
package org.schabi.newpipe.playlist;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.text.TextUtils;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
|
||||
import com.nostra13.universalimageloader.core.process.BitmapProcessor;
|
||||
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.util.Localization;
|
||||
@@ -15,6 +19,10 @@ public class PlayQueueItemBuilder {
|
||||
|
||||
private static final String TAG = PlayQueueItemBuilder.class.toString();
|
||||
|
||||
private final int thumbnailWidthPx;
|
||||
private final int thumbnailHeightPx;
|
||||
private final DisplayImageOptions imageOptions;
|
||||
|
||||
public interface OnSelectedListener {
|
||||
void selected(PlayQueueItem item, View view);
|
||||
void held(PlayQueueItem item, View view);
|
||||
@@ -23,7 +31,11 @@ public class PlayQueueItemBuilder {
|
||||
|
||||
private OnSelectedListener onItemClickListener;
|
||||
|
||||
public PlayQueueItemBuilder() {}
|
||||
public PlayQueueItemBuilder(final Context context) {
|
||||
thumbnailWidthPx = context.getResources().getDimensionPixelSize(R.dimen.play_queue_thumbnail_width);
|
||||
thumbnailHeightPx = context.getResources().getDimensionPixelSize(R.dimen.play_queue_thumbnail_height);
|
||||
imageOptions = buildImageOptions(thumbnailWidthPx, thumbnailHeightPx);
|
||||
}
|
||||
|
||||
public void setOnSelectedListener(OnSelectedListener listener) {
|
||||
this.onItemClickListener = listener;
|
||||
@@ -39,7 +51,7 @@ public class PlayQueueItemBuilder {
|
||||
holder.itemDurationView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
ImageLoader.getInstance().displayImage(item.getThumbnailUrl(), holder.itemThumbnailView, IMAGE_OPTIONS);
|
||||
ImageLoader.getInstance().displayImage(item.getThumbnailUrl(), holder.itemThumbnailView, imageOptions);
|
||||
|
||||
holder.itemRoot.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
@@ -78,11 +90,23 @@ public class PlayQueueItemBuilder {
|
||||
};
|
||||
}
|
||||
|
||||
private static final DisplayImageOptions IMAGE_OPTIONS =
|
||||
new DisplayImageOptions.Builder()
|
||||
.cacheInMemory(true)
|
||||
.showImageOnFail(R.drawable.dummy_thumbnail)
|
||||
.showImageForEmptyUri(R.drawable.dummy_thumbnail)
|
||||
.showImageOnLoading(R.drawable.dummy_thumbnail)
|
||||
.build();
|
||||
private DisplayImageOptions buildImageOptions(final int widthPx, final int heightPx) {
|
||||
final BitmapProcessor bitmapProcessor = new BitmapProcessor() {
|
||||
@Override
|
||||
public Bitmap process(Bitmap bitmap) {
|
||||
final Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, widthPx, heightPx, false);
|
||||
bitmap.recycle();
|
||||
return resizedBitmap;
|
||||
}
|
||||
};
|
||||
|
||||
return new DisplayImageOptions.Builder()
|
||||
.showImageOnFail(R.drawable.dummy_thumbnail)
|
||||
.showImageForEmptyUri(R.drawable.dummy_thumbnail)
|
||||
.showImageOnLoading(R.drawable.dummy_thumbnail)
|
||||
.bitmapConfig(Bitmap.Config.RGB_565) // Users won't be able to see much anyways
|
||||
.preProcessor(bitmapProcessor)
|
||||
.imageScaleType(ImageScaleType.EXACTLY)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user