-Added skip silence toggle to playback speed control.
-Added step size selector to playback speed control. -Added skip silence flag to player intents. -Moved default preset in playback speed control to neutral dialog button, renamed as reset. -Removed nightcore preset from playback speed control.
This commit is contained in:
parent
7721098551
commit
72d1e5131f
9 changed files with 236 additions and 81 deletions
|
@ -115,6 +115,7 @@ public abstract class BasePlayer implements
|
||||||
public static final String REPEAT_MODE = "repeat_mode";
|
public static final String REPEAT_MODE = "repeat_mode";
|
||||||
public static final String PLAYBACK_PITCH = "playback_pitch";
|
public static final String PLAYBACK_PITCH = "playback_pitch";
|
||||||
public static final String PLAYBACK_SPEED = "playback_speed";
|
public static final String PLAYBACK_SPEED = "playback_speed";
|
||||||
|
public static final String PLAYBACK_SKIP_SILENCE = "playback_skip_silence";
|
||||||
public static final String PLAYBACK_QUALITY = "playback_quality";
|
public static final String PLAYBACK_QUALITY = "playback_quality";
|
||||||
public static final String PLAY_QUEUE_KEY = "play_queue_key";
|
public static final String PLAY_QUEUE_KEY = "play_queue_key";
|
||||||
public static final String APPEND_ONLY = "append_only";
|
public static final String APPEND_ONLY = "append_only";
|
||||||
|
@ -235,20 +236,23 @@ public abstract class BasePlayer implements
|
||||||
final int repeatMode = intent.getIntExtra(REPEAT_MODE, getRepeatMode());
|
final int repeatMode = intent.getIntExtra(REPEAT_MODE, getRepeatMode());
|
||||||
final float playbackSpeed = intent.getFloatExtra(PLAYBACK_SPEED, getPlaybackSpeed());
|
final float playbackSpeed = intent.getFloatExtra(PLAYBACK_SPEED, getPlaybackSpeed());
|
||||||
final float playbackPitch = intent.getFloatExtra(PLAYBACK_PITCH, getPlaybackPitch());
|
final float playbackPitch = intent.getFloatExtra(PLAYBACK_PITCH, getPlaybackPitch());
|
||||||
|
final boolean playbackSkipSilence = intent.getBooleanExtra(PLAYBACK_SKIP_SILENCE, false);
|
||||||
|
|
||||||
// Good to go...
|
// Good to go...
|
||||||
initPlayback(queue, repeatMode, playbackSpeed, playbackPitch, /*playOnInit=*/true);
|
initPlayback(queue, repeatMode, playbackSpeed, playbackPitch, playbackSkipSilence,
|
||||||
|
/*playOnInit=*/true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initPlayback(@NonNull final PlayQueue queue,
|
protected void initPlayback(@NonNull final PlayQueue queue,
|
||||||
@Player.RepeatMode final int repeatMode,
|
@Player.RepeatMode final int repeatMode,
|
||||||
final float playbackSpeed,
|
final float playbackSpeed,
|
||||||
final float playbackPitch,
|
final float playbackPitch,
|
||||||
|
final boolean playbackSkipSilence,
|
||||||
final boolean playOnReady) {
|
final boolean playOnReady) {
|
||||||
destroyPlayer();
|
destroyPlayer();
|
||||||
initPlayer(playOnReady);
|
initPlayer(playOnReady);
|
||||||
setRepeatMode(repeatMode);
|
setRepeatMode(repeatMode);
|
||||||
setPlaybackParameters(playbackSpeed, playbackPitch);
|
setPlaybackParameters(playbackSpeed, playbackPitch, playbackSkipSilence);
|
||||||
|
|
||||||
playQueue = queue;
|
playQueue = queue;
|
||||||
playQueue.init();
|
playQueue.init();
|
||||||
|
@ -1162,19 +1166,22 @@ public abstract class BasePlayer implements
|
||||||
return getPlaybackParameters().pitch;
|
return getPlaybackParameters().pitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getPlaybackSkipSilence() {
|
||||||
|
return getPlaybackParameters().skipSilence;
|
||||||
|
}
|
||||||
|
|
||||||
public void setPlaybackSpeed(float speed) {
|
public void setPlaybackSpeed(float speed) {
|
||||||
setPlaybackParameters(speed, getPlaybackPitch());
|
setPlaybackParameters(speed, getPlaybackPitch(), getPlaybackSkipSilence());
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlaybackParameters getPlaybackParameters() {
|
public PlaybackParameters getPlaybackParameters() {
|
||||||
final PlaybackParameters defaultParameters = new PlaybackParameters(1f, 1f);
|
if (simpleExoPlayer == null) return PlaybackParameters.DEFAULT;
|
||||||
if (simpleExoPlayer == null) return defaultParameters;
|
|
||||||
final PlaybackParameters parameters = simpleExoPlayer.getPlaybackParameters();
|
final PlaybackParameters parameters = simpleExoPlayer.getPlaybackParameters();
|
||||||
return parameters == null ? defaultParameters : parameters;
|
return parameters == null ? PlaybackParameters.DEFAULT : parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPlaybackParameters(float speed, float pitch) {
|
public void setPlaybackParameters(float speed, float pitch, boolean skipSilence) {
|
||||||
simpleExoPlayer.setPlaybackParameters(new PlaybackParameters(speed, pitch));
|
simpleExoPlayer.setPlaybackParameters(new PlaybackParameters(speed, pitch, skipSilence));
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlayQueue getPlayQueue() {
|
public PlayQueue getPlayQueue() {
|
||||||
|
|
|
@ -181,7 +181,7 @@ public final class MainVideoPlayer extends AppCompatActivity
|
||||||
playerImpl.setPlaybackQuality(playerState.getPlaybackQuality());
|
playerImpl.setPlaybackQuality(playerState.getPlaybackQuality());
|
||||||
playerImpl.initPlayback(playerState.getPlayQueue(), playerState.getRepeatMode(),
|
playerImpl.initPlayback(playerState.getPlayQueue(), playerState.getRepeatMode(),
|
||||||
playerState.getPlaybackSpeed(), playerState.getPlaybackPitch(),
|
playerState.getPlaybackSpeed(), playerState.getPlaybackPitch(),
|
||||||
playerState.wasPlaying());
|
playerState.isPlaybackSkipSilence(), playerState.wasPlaying());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,7 +210,8 @@ public final class MainVideoPlayer extends AppCompatActivity
|
||||||
playerImpl.setRecovery();
|
playerImpl.setRecovery();
|
||||||
playerState = new PlayerState(playerImpl.getPlayQueue(), playerImpl.getRepeatMode(),
|
playerState = new PlayerState(playerImpl.getPlayQueue(), playerImpl.getRepeatMode(),
|
||||||
playerImpl.getPlaybackSpeed(), playerImpl.getPlaybackPitch(),
|
playerImpl.getPlaybackSpeed(), playerImpl.getPlaybackPitch(),
|
||||||
playerImpl.getPlaybackQuality(), playerImpl.isPlaying());
|
playerImpl.getPlaybackQuality(), playerImpl.getPlaybackSkipSilence(),
|
||||||
|
playerImpl.isPlaying());
|
||||||
StateSaver.tryToSave(isChangingConfigurations(), null, outState, this);
|
StateSaver.tryToSave(isChangingConfigurations(), null, outState, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,8 +353,11 @@ public final class MainVideoPlayer extends AppCompatActivity
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlaybackParameterChanged(float playbackTempo, float playbackPitch) {
|
public void onPlaybackParameterChanged(float playbackTempo, float playbackPitch,
|
||||||
if (playerImpl != null) playerImpl.setPlaybackParameters(playbackTempo, playbackPitch);
|
boolean playbackSkipSilence) {
|
||||||
|
if (playerImpl != null) {
|
||||||
|
playerImpl.setPlaybackParameters(playbackTempo, playbackPitch, playbackSkipSilence);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -533,6 +537,7 @@ public final class MainVideoPlayer extends AppCompatActivity
|
||||||
this.getRepeatMode(),
|
this.getRepeatMode(),
|
||||||
this.getPlaybackSpeed(),
|
this.getPlaybackSpeed(),
|
||||||
this.getPlaybackPitch(),
|
this.getPlaybackPitch(),
|
||||||
|
this.getPlaybackSkipSilence(),
|
||||||
this.getPlaybackQuality()
|
this.getPlaybackQuality()
|
||||||
);
|
);
|
||||||
context.startService(intent);
|
context.startService(intent);
|
||||||
|
@ -554,6 +559,7 @@ public final class MainVideoPlayer extends AppCompatActivity
|
||||||
this.getRepeatMode(),
|
this.getRepeatMode(),
|
||||||
this.getPlaybackSpeed(),
|
this.getPlaybackSpeed(),
|
||||||
this.getPlaybackPitch(),
|
this.getPlaybackPitch(),
|
||||||
|
this.getPlaybackSkipSilence(),
|
||||||
this.getPlaybackQuality()
|
this.getPlaybackQuality()
|
||||||
);
|
);
|
||||||
context.startService(intent);
|
context.startService(intent);
|
||||||
|
@ -649,7 +655,8 @@ public final class MainVideoPlayer extends AppCompatActivity
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlaybackSpeedClicked() {
|
public void onPlaybackSpeedClicked() {
|
||||||
PlaybackParameterDialog.newInstance(getPlaybackSpeed(), getPlaybackPitch())
|
PlaybackParameterDialog
|
||||||
|
.newInstance(getPlaybackSpeed(), getPlaybackPitch(), getPlaybackSkipSilence())
|
||||||
.show(getSupportFragmentManager(), TAG);
|
.show(getSupportFragmentManager(), TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,21 +14,26 @@ public class PlayerState implements Serializable {
|
||||||
private final float playbackSpeed;
|
private final float playbackSpeed;
|
||||||
private final float playbackPitch;
|
private final float playbackPitch;
|
||||||
@Nullable private final String playbackQuality;
|
@Nullable private final String playbackQuality;
|
||||||
|
private final boolean playbackSkipSilence;
|
||||||
private final boolean wasPlaying;
|
private final boolean wasPlaying;
|
||||||
|
|
||||||
PlayerState(@NonNull final PlayQueue playQueue, final int repeatMode,
|
PlayerState(@NonNull final PlayQueue playQueue, final int repeatMode,
|
||||||
final float playbackSpeed, final float playbackPitch, final boolean wasPlaying) {
|
final float playbackSpeed, final float playbackPitch,
|
||||||
this(playQueue, repeatMode, playbackSpeed, playbackPitch, null, wasPlaying);
|
final boolean playbackSkipSilence, final boolean wasPlaying) {
|
||||||
|
this(playQueue, repeatMode, playbackSpeed, playbackPitch, null,
|
||||||
|
playbackSkipSilence, wasPlaying);
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerState(@NonNull final PlayQueue playQueue, final int repeatMode,
|
PlayerState(@NonNull final PlayQueue playQueue, final int repeatMode,
|
||||||
final float playbackSpeed, final float playbackPitch,
|
final float playbackSpeed, final float playbackPitch,
|
||||||
@Nullable final String playbackQuality, final boolean wasPlaying) {
|
@Nullable final String playbackQuality, final boolean playbackSkipSilence,
|
||||||
|
final boolean wasPlaying) {
|
||||||
this.playQueue = playQueue;
|
this.playQueue = playQueue;
|
||||||
this.repeatMode = repeatMode;
|
this.repeatMode = repeatMode;
|
||||||
this.playbackSpeed = playbackSpeed;
|
this.playbackSpeed = playbackSpeed;
|
||||||
this.playbackPitch = playbackPitch;
|
this.playbackPitch = playbackPitch;
|
||||||
this.playbackQuality = playbackQuality;
|
this.playbackQuality = playbackQuality;
|
||||||
|
this.playbackSkipSilence = playbackSkipSilence;
|
||||||
this.wasPlaying = wasPlaying;
|
this.wasPlaying = wasPlaying;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +67,10 @@ public class PlayerState implements Serializable {
|
||||||
return playbackQuality;
|
return playbackQuality;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isPlaybackSkipSilence() {
|
||||||
|
return playbackSkipSilence;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean wasPlaying() {
|
public boolean wasPlaying() {
|
||||||
return wasPlaying;
|
return wasPlaying;
|
||||||
}
|
}
|
||||||
|
|
|
@ -459,6 +459,7 @@ public final class PopupVideoPlayer extends Service {
|
||||||
this.getRepeatMode(),
|
this.getRepeatMode(),
|
||||||
this.getPlaybackSpeed(),
|
this.getPlaybackSpeed(),
|
||||||
this.getPlaybackPitch(),
|
this.getPlaybackPitch(),
|
||||||
|
this.getPlaybackSkipSilence(),
|
||||||
this.getPlaybackQuality()
|
this.getPlaybackQuality()
|
||||||
);
|
);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
|
|
@ -187,6 +187,7 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
this.player.getRepeatMode(),
|
this.player.getRepeatMode(),
|
||||||
this.player.getPlaybackSpeed(),
|
this.player.getPlaybackSpeed(),
|
||||||
this.player.getPlaybackPitch(),
|
this.player.getPlaybackPitch(),
|
||||||
|
this.player.getPlaybackSkipSilence(),
|
||||||
null
|
null
|
||||||
).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
}
|
}
|
||||||
|
@ -466,13 +467,16 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
|
|
||||||
private void openPlaybackParameterDialog() {
|
private void openPlaybackParameterDialog() {
|
||||||
if (player == null) return;
|
if (player == null) return;
|
||||||
PlaybackParameterDialog.newInstance(player.getPlaybackSpeed(),
|
PlaybackParameterDialog.newInstance(player.getPlaybackSpeed(), player.getPlaybackPitch(),
|
||||||
player.getPlaybackPitch()).show(getSupportFragmentManager(), getTag());
|
player.getPlaybackSkipSilence()).show(getSupportFragmentManager(), getTag());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlaybackParameterChanged(float playbackTempo, float playbackPitch) {
|
public void onPlaybackParameterChanged(float playbackTempo, float playbackPitch,
|
||||||
if (player != null) player.setPlaybackParameters(playbackTempo, playbackPitch);
|
boolean playbackSkipSilence) {
|
||||||
|
if (player != null) {
|
||||||
|
player.setPlaybackParameters(playbackTempo, playbackPitch, playbackSkipSilence);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -21,25 +21,24 @@ import static org.schabi.newpipe.player.BasePlayer.DEBUG;
|
||||||
public class PlaybackParameterDialog extends DialogFragment {
|
public class PlaybackParameterDialog extends DialogFragment {
|
||||||
@NonNull private static final String TAG = "PlaybackParameterDialog";
|
@NonNull private static final String TAG = "PlaybackParameterDialog";
|
||||||
|
|
||||||
public static final double MINIMUM_PLAYBACK_VALUE = 0.25f;
|
// Maximum allowable range in ExoPlayer
|
||||||
|
public static final double MINIMUM_PLAYBACK_VALUE = 0.10f;
|
||||||
public static final double MAXIMUM_PLAYBACK_VALUE = 3.00f;
|
public static final double MAXIMUM_PLAYBACK_VALUE = 3.00f;
|
||||||
|
|
||||||
public static final char STEP_UP_SIGN = '+';
|
public static final char STEP_UP_SIGN = '+';
|
||||||
public static final char STEP_DOWN_SIGN = '-';
|
public static final char STEP_DOWN_SIGN = '-';
|
||||||
public static final double PLAYBACK_STEP_VALUE = 0.05f;
|
public static final double DEFAULT_PLAYBACK_STEP_VALUE = 0.05f;
|
||||||
|
|
||||||
public static final double NIGHTCORE_TEMPO = 1.20f;
|
|
||||||
public static final double NIGHTCORE_PITCH_LOWER = 1.15f;
|
|
||||||
public static final double NIGHTCORE_PITCH_UPPER = 1.25f;
|
|
||||||
|
|
||||||
public static final double DEFAULT_TEMPO = 1.00f;
|
public static final double DEFAULT_TEMPO = 1.00f;
|
||||||
public static final double DEFAULT_PITCH = 1.00f;
|
public static final double DEFAULT_PITCH = 1.00f;
|
||||||
|
public static final boolean DEFAULT_SKIP_SILENCE = false;
|
||||||
|
|
||||||
@NonNull private static final String INITIAL_TEMPO_KEY = "initial_tempo_key";
|
@NonNull private static final String INITIAL_TEMPO_KEY = "initial_tempo_key";
|
||||||
@NonNull private static final String INITIAL_PITCH_KEY = "initial_pitch_key";
|
@NonNull private static final String INITIAL_PITCH_KEY = "initial_pitch_key";
|
||||||
|
|
||||||
public interface Callback {
|
public interface Callback {
|
||||||
void onPlaybackParameterChanged(final float playbackTempo, final float playbackPitch);
|
void onPlaybackParameterChanged(final float playbackTempo, final float playbackPitch,
|
||||||
|
final boolean playbackSkipSilence);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable private Callback callback;
|
@Nullable private Callback callback;
|
||||||
|
@ -50,6 +49,7 @@ public class PlaybackParameterDialog extends DialogFragment {
|
||||||
|
|
||||||
private double initialTempo = DEFAULT_TEMPO;
|
private double initialTempo = DEFAULT_TEMPO;
|
||||||
private double initialPitch = DEFAULT_PITCH;
|
private double initialPitch = DEFAULT_PITCH;
|
||||||
|
private boolean initialSkipSilence = DEFAULT_SKIP_SILENCE;
|
||||||
|
|
||||||
@Nullable private SeekBar tempoSlider;
|
@Nullable private SeekBar tempoSlider;
|
||||||
@Nullable private TextView tempoMinimumText;
|
@Nullable private TextView tempoMinimumText;
|
||||||
|
@ -65,16 +65,22 @@ public class PlaybackParameterDialog extends DialogFragment {
|
||||||
@Nullable private TextView pitchStepDownText;
|
@Nullable private TextView pitchStepDownText;
|
||||||
@Nullable private TextView pitchStepUpText;
|
@Nullable private TextView pitchStepUpText;
|
||||||
|
|
||||||
@Nullable private CheckBox unhookingCheckbox;
|
@Nullable private TextView stepSizeOnePercentText;
|
||||||
|
@Nullable private TextView stepSizeFivePercentText;
|
||||||
|
@Nullable private TextView stepSizeTenPercentText;
|
||||||
|
@Nullable private TextView stepSizeTwentyFivePercentText;
|
||||||
|
@Nullable private TextView stepSizeOneHundredPercentText;
|
||||||
|
|
||||||
@Nullable private TextView nightCorePresetText;
|
@Nullable private CheckBox unhookingCheckbox;
|
||||||
@Nullable private TextView resetPresetText;
|
@Nullable private CheckBox skipSilenceCheckbox;
|
||||||
|
|
||||||
public static PlaybackParameterDialog newInstance(final double playbackTempo,
|
public static PlaybackParameterDialog newInstance(final double playbackTempo,
|
||||||
final double playbackPitch) {
|
final double playbackPitch,
|
||||||
|
final boolean playbackSkipSilence) {
|
||||||
PlaybackParameterDialog dialog = new PlaybackParameterDialog();
|
PlaybackParameterDialog dialog = new PlaybackParameterDialog();
|
||||||
dialog.initialTempo = playbackTempo;
|
dialog.initialTempo = playbackTempo;
|
||||||
dialog.initialPitch = playbackPitch;
|
dialog.initialPitch = playbackPitch;
|
||||||
|
dialog.initialSkipSilence = playbackSkipSilence;
|
||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +129,9 @@ public class PlaybackParameterDialog extends DialogFragment {
|
||||||
.setView(view)
|
.setView(view)
|
||||||
.setCancelable(true)
|
.setCancelable(true)
|
||||||
.setNegativeButton(R.string.cancel, (dialogInterface, i) ->
|
.setNegativeButton(R.string.cancel, (dialogInterface, i) ->
|
||||||
setPlaybackParameters(initialTempo, initialPitch))
|
setPlaybackParameters(initialTempo, initialPitch, initialSkipSilence))
|
||||||
|
.setNeutralButton(R.string.playback_reset, (dialogInterface, i) ->
|
||||||
|
setPlaybackParameters(DEFAULT_TEMPO, DEFAULT_PITCH, DEFAULT_SKIP_SILENCE))
|
||||||
.setPositiveButton(R.string.finish, (dialogInterface, i) ->
|
.setPositiveButton(R.string.finish, (dialogInterface, i) ->
|
||||||
setCurrentPlaybackParameters());
|
setCurrentPlaybackParameters());
|
||||||
|
|
||||||
|
@ -136,9 +144,13 @@ public class PlaybackParameterDialog extends DialogFragment {
|
||||||
|
|
||||||
private void setupControlViews(@NonNull View rootView) {
|
private void setupControlViews(@NonNull View rootView) {
|
||||||
setupHookingControl(rootView);
|
setupHookingControl(rootView);
|
||||||
|
setupSkipSilenceControl(rootView);
|
||||||
|
|
||||||
setupTempoControl(rootView);
|
setupTempoControl(rootView);
|
||||||
setupPitchControl(rootView);
|
setupPitchControl(rootView);
|
||||||
setupPresetControl(rootView);
|
setupStepSize(DEFAULT_PLAYBACK_STEP_VALUE);
|
||||||
|
|
||||||
|
setupStepSizeSelector(rootView);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupTempoControl(@NonNull View rootView) {
|
private void setupTempoControl(@NonNull View rootView) {
|
||||||
|
@ -157,17 +169,17 @@ public class PlaybackParameterDialog extends DialogFragment {
|
||||||
tempoMinimumText.setText(PlayerHelper.formatSpeed(MINIMUM_PLAYBACK_VALUE));
|
tempoMinimumText.setText(PlayerHelper.formatSpeed(MINIMUM_PLAYBACK_VALUE));
|
||||||
|
|
||||||
if (tempoStepUpText != null) {
|
if (tempoStepUpText != null) {
|
||||||
tempoStepUpText.setText(getStepUpPercentString(PLAYBACK_STEP_VALUE));
|
tempoStepUpText.setText(getStepUpPercentString(DEFAULT_PLAYBACK_STEP_VALUE));
|
||||||
tempoStepUpText.setOnClickListener(view -> {
|
tempoStepUpText.setOnClickListener(view -> {
|
||||||
onTempoSliderUpdated(getCurrentTempo() + PLAYBACK_STEP_VALUE);
|
onTempoSliderUpdated(getCurrentTempo() + DEFAULT_PLAYBACK_STEP_VALUE);
|
||||||
setCurrentPlaybackParameters();
|
setCurrentPlaybackParameters();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tempoStepDownText != null) {
|
if (tempoStepDownText != null) {
|
||||||
tempoStepDownText.setText(getStepDownPercentString(PLAYBACK_STEP_VALUE));
|
tempoStepDownText.setText(getStepDownPercentString(DEFAULT_PLAYBACK_STEP_VALUE));
|
||||||
tempoStepDownText.setOnClickListener(view -> {
|
tempoStepDownText.setOnClickListener(view -> {
|
||||||
onTempoSliderUpdated(getCurrentTempo() - PLAYBACK_STEP_VALUE);
|
onTempoSliderUpdated(getCurrentTempo() - DEFAULT_PLAYBACK_STEP_VALUE);
|
||||||
setCurrentPlaybackParameters();
|
setCurrentPlaybackParameters();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -194,22 +206,6 @@ public class PlaybackParameterDialog extends DialogFragment {
|
||||||
if (pitchMinimumText != null)
|
if (pitchMinimumText != null)
|
||||||
pitchMinimumText.setText(PlayerHelper.formatPitch(MINIMUM_PLAYBACK_VALUE));
|
pitchMinimumText.setText(PlayerHelper.formatPitch(MINIMUM_PLAYBACK_VALUE));
|
||||||
|
|
||||||
if (pitchStepUpText != null) {
|
|
||||||
pitchStepUpText.setText(getStepUpPercentString(PLAYBACK_STEP_VALUE));
|
|
||||||
pitchStepUpText.setOnClickListener(view -> {
|
|
||||||
onPitchSliderUpdated(getCurrentPitch() + PLAYBACK_STEP_VALUE);
|
|
||||||
setCurrentPlaybackParameters();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pitchStepDownText != null) {
|
|
||||||
pitchStepDownText.setText(getStepDownPercentString(PLAYBACK_STEP_VALUE));
|
|
||||||
pitchStepDownText.setOnClickListener(view -> {
|
|
||||||
onPitchSliderUpdated(getCurrentPitch() - PLAYBACK_STEP_VALUE);
|
|
||||||
setCurrentPlaybackParameters();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pitchSlider != null) {
|
if (pitchSlider != null) {
|
||||||
pitchSlider.setMax(strategy.progressOf(MAXIMUM_PLAYBACK_VALUE));
|
pitchSlider.setMax(strategy.progressOf(MAXIMUM_PLAYBACK_VALUE));
|
||||||
pitchSlider.setProgress(strategy.progressOf(initialPitch));
|
pitchSlider.setProgress(strategy.progressOf(initialPitch));
|
||||||
|
@ -231,24 +227,84 @@ public class PlaybackParameterDialog extends DialogFragment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupPresetControl(@NonNull View rootView) {
|
private void setupSkipSilenceControl(@NonNull View rootView) {
|
||||||
nightCorePresetText = rootView.findViewById(R.id.presetNightcore);
|
skipSilenceCheckbox = rootView.findViewById(R.id.skipSilenceCheckbox);
|
||||||
if (nightCorePresetText != null) {
|
if (skipSilenceCheckbox != null) {
|
||||||
nightCorePresetText.setOnClickListener(view -> {
|
skipSilenceCheckbox.setChecked(initialSkipSilence);
|
||||||
final double randomPitch = NIGHTCORE_PITCH_LOWER +
|
skipSilenceCheckbox.setOnCheckedChangeListener((compoundButton, isChecked) ->
|
||||||
Math.random() * (NIGHTCORE_PITCH_UPPER - NIGHTCORE_PITCH_LOWER);
|
setCurrentPlaybackParameters());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setTempoSlider(NIGHTCORE_TEMPO);
|
private void setupStepSizeSelector(@NonNull final View rootView) {
|
||||||
setPitchSlider(randomPitch);
|
stepSizeOnePercentText = rootView.findViewById(R.id.stepSizeOnePercent);
|
||||||
|
stepSizeFivePercentText = rootView.findViewById(R.id.stepSizeFivePercent);
|
||||||
|
stepSizeTenPercentText = rootView.findViewById(R.id.stepSizeTenPercent);
|
||||||
|
stepSizeTwentyFivePercentText = rootView.findViewById(R.id.stepSizeTwentyFivePercent);
|
||||||
|
stepSizeOneHundredPercentText = rootView.findViewById(R.id.stepSizeOneHundredPercent);
|
||||||
|
|
||||||
|
if (stepSizeOnePercentText != null) {
|
||||||
|
final double onePercent = 0.01f;
|
||||||
|
stepSizeOnePercentText.setText(getPercentString(onePercent));
|
||||||
|
stepSizeOnePercentText.setOnClickListener(view -> setupStepSize(onePercent));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stepSizeFivePercentText != null) {
|
||||||
|
final double fivePercent = 0.05f;
|
||||||
|
stepSizeFivePercentText.setText(getPercentString(fivePercent));
|
||||||
|
stepSizeFivePercentText.setOnClickListener(view -> setupStepSize(fivePercent));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stepSizeTenPercentText != null) {
|
||||||
|
final double tenPercent = 0.10f;
|
||||||
|
stepSizeTenPercentText.setText(getPercentString(tenPercent));
|
||||||
|
stepSizeTenPercentText.setOnClickListener(view -> setupStepSize(tenPercent));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stepSizeTwentyFivePercentText != null) {
|
||||||
|
final double twentyFivePercent = 0.25f;
|
||||||
|
stepSizeTwentyFivePercentText.setText(getPercentString(twentyFivePercent));
|
||||||
|
stepSizeTwentyFivePercentText.setOnClickListener(view ->
|
||||||
|
setupStepSize(twentyFivePercent));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stepSizeOneHundredPercentText != null) {
|
||||||
|
final double oneHundredPercent = 1.00f;
|
||||||
|
stepSizeOneHundredPercentText.setText(getPercentString(oneHundredPercent));
|
||||||
|
stepSizeOneHundredPercentText.setOnClickListener(view ->
|
||||||
|
setupStepSize(oneHundredPercent));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupStepSize(final double stepSize) {
|
||||||
|
if (tempoStepUpText != null) {
|
||||||
|
tempoStepUpText.setText(getStepUpPercentString(stepSize));
|
||||||
|
tempoStepUpText.setOnClickListener(view -> {
|
||||||
|
onTempoSliderUpdated(getCurrentTempo() + stepSize);
|
||||||
setCurrentPlaybackParameters();
|
setCurrentPlaybackParameters();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
resetPresetText = rootView.findViewById(R.id.presetReset);
|
if (tempoStepDownText != null) {
|
||||||
if (resetPresetText != null) {
|
tempoStepDownText.setText(getStepDownPercentString(stepSize));
|
||||||
resetPresetText.setOnClickListener(view -> {
|
tempoStepDownText.setOnClickListener(view -> {
|
||||||
setTempoSlider(DEFAULT_TEMPO);
|
onTempoSliderUpdated(getCurrentTempo() - stepSize);
|
||||||
setPitchSlider(DEFAULT_PITCH);
|
setCurrentPlaybackParameters();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pitchStepUpText != null) {
|
||||||
|
pitchStepUpText.setText(getStepUpPercentString(stepSize));
|
||||||
|
pitchStepUpText.setOnClickListener(view -> {
|
||||||
|
onPitchSliderUpdated(getCurrentPitch() + stepSize);
|
||||||
|
setCurrentPlaybackParameters();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pitchStepDownText != null) {
|
||||||
|
pitchStepDownText.setText(getStepDownPercentString(stepSize));
|
||||||
|
pitchStepDownText.setOnClickListener(view -> {
|
||||||
|
onPitchSliderUpdated(getCurrentPitch() - stepSize);
|
||||||
setCurrentPlaybackParameters();
|
setCurrentPlaybackParameters();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -342,10 +398,11 @@ public class PlaybackParameterDialog extends DialogFragment {
|
||||||
//////////////////////////////////////////////////////////////////////////*/
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
private void setCurrentPlaybackParameters() {
|
private void setCurrentPlaybackParameters() {
|
||||||
setPlaybackParameters(getCurrentTempo(), getCurrentPitch());
|
setPlaybackParameters(getCurrentTempo(), getCurrentPitch(), getCurrentSkipSilence());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPlaybackParameters(final double tempo, final double pitch) {
|
private void setPlaybackParameters(final double tempo, final double pitch,
|
||||||
|
final boolean skipSilence) {
|
||||||
if (callback != null && tempoCurrentText != null && pitchCurrentText != null) {
|
if (callback != null && tempoCurrentText != null && pitchCurrentText != null) {
|
||||||
if (DEBUG) Log.d(TAG, "Setting playback parameters to " +
|
if (DEBUG) Log.d(TAG, "Setting playback parameters to " +
|
||||||
"tempo=[" + tempo + "], " +
|
"tempo=[" + tempo + "], " +
|
||||||
|
@ -353,7 +410,7 @@ public class PlaybackParameterDialog extends DialogFragment {
|
||||||
|
|
||||||
tempoCurrentText.setText(PlayerHelper.formatSpeed(tempo));
|
tempoCurrentText.setText(PlayerHelper.formatSpeed(tempo));
|
||||||
pitchCurrentText.setText(PlayerHelper.formatPitch(pitch));
|
pitchCurrentText.setText(PlayerHelper.formatPitch(pitch));
|
||||||
callback.onPlaybackParameterChanged((float) tempo, (float) pitch);
|
callback.onPlaybackParameterChanged((float) tempo, (float) pitch, skipSilence);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,13 +424,22 @@ public class PlaybackParameterDialog extends DialogFragment {
|
||||||
pitchSlider.getProgress());
|
pitchSlider.getProgress());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean getCurrentSkipSilence() {
|
||||||
|
return skipSilenceCheckbox != null && skipSilenceCheckbox.isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private static String getStepUpPercentString(final double percent) {
|
private static String getStepUpPercentString(final double percent) {
|
||||||
return STEP_UP_SIGN + PlayerHelper.formatPitch(percent);
|
return STEP_UP_SIGN + getPercentString(percent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private static String getStepDownPercentString(final double percent) {
|
private static String getStepDownPercentString(final double percent) {
|
||||||
return STEP_DOWN_SIGN + PlayerHelper.formatPitch(percent);
|
return STEP_DOWN_SIGN + getPercentString(percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private static String getPercentString(final double percent) {
|
||||||
|
return PlayerHelper.formatPitch(percent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,11 +100,13 @@ public class NavigationHelper {
|
||||||
final int repeatMode,
|
final int repeatMode,
|
||||||
final float playbackSpeed,
|
final float playbackSpeed,
|
||||||
final float playbackPitch,
|
final float playbackPitch,
|
||||||
|
final boolean playbackSkipSilence,
|
||||||
@Nullable final String playbackQuality) {
|
@Nullable final String playbackQuality) {
|
||||||
return getPlayerIntent(context, targetClazz, playQueue, playbackQuality)
|
return getPlayerIntent(context, targetClazz, playQueue, playbackQuality)
|
||||||
.putExtra(BasePlayer.REPEAT_MODE, repeatMode)
|
.putExtra(BasePlayer.REPEAT_MODE, repeatMode)
|
||||||
.putExtra(BasePlayer.PLAYBACK_SPEED, playbackSpeed)
|
.putExtra(BasePlayer.PLAYBACK_SPEED, playbackSpeed)
|
||||||
.putExtra(BasePlayer.PLAYBACK_PITCH, playbackPitch);
|
.putExtra(BasePlayer.PLAYBACK_PITCH, playbackPitch)
|
||||||
|
.putExtra(BasePlayer.PLAYBACK_SKIP_SILENCE, playbackSkipSilence);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void playOnMainPlayer(final Context context, final PlayQueue queue) {
|
public static void playOnMainPlayer(final Context context, final PlayQueue queue) {
|
||||||
|
|
|
@ -279,30 +279,88 @@
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:layout_below="@id/separatorCheckbox"/>
|
android:layout_below="@id/separatorCheckbox"/>
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/skipSilenceCheckbox"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:checked="false"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:text="@string/skip_silence_checkbox"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_below="@id/unhookCheckbox"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/presetSelector"
|
android:id="@+id/stepSizeSelector"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="40dp"
|
android:layout_height="40dp"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:layout_below="@id/unhookCheckbox">
|
android:layout_below="@id/skipSilenceCheckbox">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/presetNightcore"
|
android:id="@+id/stepSizeText"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="@string/playback_nightcore"
|
android:text="@string/playback_step"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:clickable="false"
|
||||||
|
android:textColor="?attr/colorAccent"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/stepSizeOnePercent"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
android:background="?attr/selectableItemBackground"
|
android:background="?attr/selectableItemBackground"
|
||||||
android:textColor="?attr/colorAccent"/>
|
android:textColor="?attr/colorAccent"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/presetReset"
|
android:id="@+id/stepSizeFivePercent"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="@string/playback_default"
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:textColor="?attr/colorAccent"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/stepSizeTenPercent"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:textColor="?attr/colorAccent"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/stepSizeTwentyFivePercent"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:textColor="?attr/colorAccent"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/stepSizeOneHundredPercent"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
android:background="?attr/selectableItemBackground"
|
android:background="?attr/selectableItemBackground"
|
||||||
android:textColor="?attr/colorAccent"/>
|
android:textColor="?attr/colorAccent"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -479,9 +479,10 @@
|
||||||
<string name="playback_speed_control">Playback Speed Controls</string>
|
<string name="playback_speed_control">Playback Speed Controls</string>
|
||||||
<string name="playback_tempo">Tempo</string>
|
<string name="playback_tempo">Tempo</string>
|
||||||
<string name="playback_pitch">Pitch</string>
|
<string name="playback_pitch">Pitch</string>
|
||||||
<string name="unhook_checkbox">Unhook (may cause distortion)</string>
|
<string name="unhook_checkbox">Unlink (may cause distortion)</string>
|
||||||
<string name="playback_nightcore">Nightcore</string>
|
<string name="skip_silence_checkbox">Fast-forward during silence</string>
|
||||||
<string name="playback_default">Default</string>
|
<string name="playback_step">Step</string>
|
||||||
|
<string name="playback_reset">Reset</string>
|
||||||
|
|
||||||
<!-- GDPR dialog -->
|
<!-- GDPR dialog -->
|
||||||
<string name="start_accept_privacy_policy">In order to comply with the European General Data Protection Regulation (GDPR), we herby draw your attention to NewPipe\'s privacy policy. Please read it carefully.\nYou must accept it to send us the bug report.</string>
|
<string name="start_accept_privacy_policy">In order to comply with the European General Data Protection Regulation (GDPR), we herby draw your attention to NewPipe\'s privacy policy. Please read it carefully.\nYou must accept it to send us the bug report.</string>
|
||||||
|
|
Loading…
Reference in a new issue