Skip to content

Commit

Permalink
Add middle gesture area in main player screen and tempo (and pitch) c…
Browse files Browse the repository at this point in the history
…hanging functionality
  • Loading branch information
klaviartur committed Feb 8, 2025
1 parent bcc355f commit 26c2a45
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 8 deletions.
4 changes: 4 additions & 0 deletions app/src/main/java/org/schabi/newpipe/player/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,10 @@ public float getPlaybackPitch() {
return getPlaybackParameters().pitch;
}

public void setPlaybackPitch(final float pitch) {
setPlaybackParameters(getPlaybackSpeed(), pitch, getPlaybackSkipSilence());
}

public boolean getPlaybackSkipSilence() {
return !exoPlayerIsNull() && simpleExoPlayer.getSkipSilenceEnabled();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ import org.schabi.newpipe.ktx.AnimationType
import org.schabi.newpipe.ktx.animate
import org.schabi.newpipe.player.Player
import org.schabi.newpipe.player.helper.AudioReactor
import org.schabi.newpipe.player.helper.PlaybackParameterDialog
import org.schabi.newpipe.player.helper.PlayerHelper
import org.schabi.newpipe.player.helper.PlayerSemitoneHelper
import org.schabi.newpipe.player.ui.MainPlayerUi
import org.schabi.newpipe.util.ThemeHelper.getAndroidDimenPx
import kotlin.math.abs
import kotlin.math.roundToInt

/**
* GestureListener for the player
Expand Down Expand Up @@ -102,6 +105,7 @@ class MainPlayerGestureListener(
binding.volumeRelativeLayout.animate(true, 200, AnimationType.SCALE_AND_ALPHA)
}
binding.brightnessRelativeLayout.isVisible = false
binding.playbackSpeedRelativeLayout.isVisible = false
}

private fun onScrollBrightness(distanceY: Float) {
Expand Down Expand Up @@ -147,6 +151,50 @@ class MainPlayerGestureListener(
binding.brightnessRelativeLayout.animate(true, 200, AnimationType.SCALE_AND_ALPHA)
}
binding.volumeRelativeLayout.isVisible = false
binding.playbackSpeedRelativeLayout.isVisible = false
}

private fun onScrollPlaybackSpeed(distanceY: Float) {
val bar: ProgressBar = binding.playbackSpeedProgressBar
val maxPlaybackSpeed: Float = PlaybackParameterDialog.getMaxPitchOrSpeed()
val minPlaybackSpeed: Float = PlaybackParameterDialog.getMinPitchOrSpeed()
val playbackSpeedStep: Float = PlaybackParameterDialog.getCurrentStepSize(player.context) / maxPlaybackSpeed

// If we just started sliding, change the progress bar to match the current playback speed
if (!binding.playbackSpeedRelativeLayout.isVisible) {
val playbackSpeedPercent: Float = player.playbackSpeed / maxPlaybackSpeed
bar.progress = (playbackSpeedPercent * bar.max).toInt()
}

// Update progress bar
bar.incrementProgressBy(distanceY.toInt())

// Update playback speed
val currentProgressPercent: Float = (bar.progress / bar.max.toFloat() / playbackSpeedStep).roundToInt() * playbackSpeedStep
val currentPlaybackSpeed: Float = (currentProgressPercent * maxPlaybackSpeed).coerceIn(minPlaybackSpeed, maxPlaybackSpeed)

player.playbackSpeed = currentPlaybackSpeed
if (!PlaybackParameterDialog.getPlaybackUnhooked(player.context)) {
if (!PlaybackParameterDialog.getPitchControlModeSemitone(player.context)) {
player.playbackPitch = currentPlaybackSpeed
} else {
player.playbackPitch = PlayerSemitoneHelper.semitonesToPercent(PlayerSemitoneHelper.percentToSemitones(currentPlaybackSpeed.toDouble())).toFloat()
}
}

if (DEBUG) {
Log.d(TAG, "onScroll().playbackSpeedControl, currentPlaybackSpeed = $currentPlaybackSpeed")
}

// Update player center image
binding.playbackSpeedTextView.text = PlayerHelper.formatSpeed(currentPlaybackSpeed.toDouble())

// Make sure the correct layout is visible
if (!binding.playbackSpeedRelativeLayout.isVisible) {
binding.playbackSpeedRelativeLayout.animate(true, 200, AnimationType.SCALE_AND_ALPHA)
}
binding.brightnessRelativeLayout.isVisible = false
binding.volumeRelativeLayout.isVisible = false
}

override fun onScrollEnd(event: MotionEvent) {
Expand All @@ -157,6 +205,9 @@ class MainPlayerGestureListener(
if (binding.brightnessRelativeLayout.isVisible) {
binding.brightnessRelativeLayout.animate(false, 200, AnimationType.SCALE_AND_ALPHA, 200)
}
if (binding.playbackSpeedRelativeLayout.isVisible) {
binding.playbackSpeedRelativeLayout.animate(false, 200, AnimationType.SCALE_AND_ALPHA, 200)
}
}

override fun onScroll(
Expand Down Expand Up @@ -190,30 +241,42 @@ class MainPlayerGestureListener(

isMoving = true

// -- Brightness and Volume control --
if (getDisplayHalfPortion(initialEvent) == DisplayPortion.RIGHT_HALF) {
// -- Brightness Volume and Tempo control --
if (getDisplayPortion(initialEvent) == DisplayPortion.RIGHT) {
when (PlayerHelper.getActionForRightGestureSide(player.context)) {
player.context.getString(R.string.volume_control_key) ->
onScrollVolume(distanceY)
player.context.getString(R.string.brightness_control_key) ->
onScrollBrightness(distanceY)
player.context.getString(R.string.playback_speed_control_key) ->
onScrollPlaybackSpeed(distanceY)
}
} else {
} else if (getDisplayPortion(initialEvent) == DisplayPortion.LEFT) {
when (PlayerHelper.getActionForLeftGestureSide(player.context)) {
player.context.getString(R.string.volume_control_key) ->
onScrollVolume(distanceY)
player.context.getString(R.string.brightness_control_key) ->
onScrollBrightness(distanceY)
player.context.getString(R.string.playback_speed_control_key) ->
onScrollPlaybackSpeed(distanceY)
}
} else {
when (PlayerHelper.getActionForMiddleGestureSide(player.context)) {
player.context.getString(R.string.volume_control_key) ->
onScrollVolume(distanceY)
player.context.getString(R.string.brightness_control_key) ->
onScrollBrightness(distanceY)
player.context.getString(R.string.playback_speed_control_key) ->
onScrollPlaybackSpeed(distanceY)
}
}

return true
}

override fun getDisplayPortion(e: MotionEvent): DisplayPortion {
return when {
e.x < binding.root.width / 3.0 -> DisplayPortion.LEFT
e.x > binding.root.width * 2.0 / 3.0 -> DisplayPortion.RIGHT
e.x < binding.root.width * 0.3 -> DisplayPortion.LEFT
e.x > binding.root.width * 0.7 -> DisplayPortion.RIGHT
else -> DisplayPortion.MIDDLE
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public class PlaybackParameterDialog extends DialogFragment {
private static final double DEFAULT_PITCH_PERCENT = 1.00f;
private static final double DEFAULT_STEP = STEP_25_PERCENT_VALUE;
private static final boolean DEFAULT_SKIP_SILENCE = false;

private static final boolean DEFAULT_PLAYBACK_UNHOOK = false;
private static final SliderStrategy QUADRATIC_STRATEGY = new SliderStrategy.Quadratic(
MIN_PITCH_OR_SPEED,
MAX_PITCH_OR_SPEED,
Expand Down Expand Up @@ -261,7 +261,7 @@ private void initUI() {
bindCheckboxWithBoolPref(
binding.unhookCheckbox,
R.string.playback_unhook_key,
true,
DEFAULT_PLAYBACK_UNHOOK,
isChecked -> {
if (!isChecked) {
// when unchecked, slide back to the minimum of current tempo or pitch
Expand Down Expand Up @@ -590,6 +590,32 @@ private static String getPercentString(final double percent) {
return PlayerHelper.formatPitch(percent);
}


public static boolean getPlaybackUnhooked(final Context context) {
return PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean(context.getString(R.string.playback_unhook_key),
DEFAULT_PLAYBACK_UNHOOK);
}

public static boolean getPitchControlModeSemitone(final Context context) {
return PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean(context.getString(R.string.playback_adjust_by_semitones_key),
PITCH_CTRL_MODE_PERCENT);
}

public static float getCurrentStepSize(final Context context) {
return PreferenceManager.getDefaultSharedPreferences(context)
.getFloat(context.getString(R.string.adjustment_step_key), (float) DEFAULT_STEP);
}

public static float getMinPitchOrSpeed() {
return (float) MIN_PITCH_OR_SPEED;
}

public static float getMaxPitchOrSpeed() {
return (float) MAX_PITCH_OR_SPEED;
}

public interface Callback {
void onPlaybackParameterChanged(float playbackTempo, float playbackPitch,
boolean playbackSkipSilence);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,12 @@ public static String getActionForRightGestureSide(@NonNull final Context context
context.getString(R.string.default_right_gesture_control_value));
}

public static String getActionForMiddleGestureSide(@NonNull final Context context) {
return getPreferences(context)
.getString(context.getString(R.string.middle_gesture_control_key),
context.getString(R.string.default_middle_gesture_control_value));
}

public static String getActionForLeftGestureSide(@NonNull final Context context) {
return getPreferences(context)
.getString(context.getString(R.string.left_gesture_control_key),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,7 @@ public void onLayoutChange(final View view, final int l, final int t, final int

binding.volumeProgressBar.setMax(maxGestureLength);
binding.brightnessProgressBar.setMax(maxGestureLength);
binding.playbackSpeedProgressBar.setMax(maxGestureLength);

setInitialGestureValues();
binding.itemsListPanel.getLayoutParams().height =
Expand Down
28 changes: 28 additions & 0 deletions app/src/main/res/layout/player.xml
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,34 @@
tools:src="@drawable/ic_brightness_high" />
</RelativeLayout>

<RelativeLayout
android:id="@+id/playbackSpeedRelativeLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@drawable/background_oval_black_transparent"
android:visibility="gone"
tools:visibility="visible">

<ProgressBar
android:id="@+id/playbackSpeedProgressBar"
style="?android:progressBarStyleHorizontal"
android:layout_width="128dp"
android:layout_height="128dp"
android:indeterminate="false"
android:progressDrawable="@drawable/progress_circular_white" />

<TextView
android:id="@+id/playbackSpeedTextView"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_centerInParent="true"
android:gravity="center"
android:textColor="@color/white"
android:textSize="18sp"
tools:ignore="ContentDescription" />
</RelativeLayout>

<RelativeLayout
android:id="@+id/unskipButton"
android:visibility="gone"
Expand Down

0 comments on commit 26c2a45

Please sign in to comment.