1
0
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:
John Zhen Mo
2017-10-28 10:08:01 -07:00
parent f284a799ef
commit 1fb3774e03
19 changed files with 248 additions and 223 deletions

View File

@@ -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);

View File

@@ -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
//////////////////////////////////////////////////////////////////////////*/

View File

@@ -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);

View File

@@ -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);

View File

@@ -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

View File

@@ -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;
/**

View File

@@ -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());

View File

@@ -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;

View File

@@ -1,4 +1,4 @@
package org.schabi.newpipe.player.refactor;
package org.schabi.newpipe.player.helper;
import android.content.Context;

View File

@@ -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;

View File

@@ -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
////////////////////////////////////////////////////////////////////////////

View File

@@ -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) {

View File

@@ -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();
}
}