Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import android.view.View
import androidx.core.os.postDelayed
import org.schabi.newpipe.databinding.PlayerBinding
import org.schabi.newpipe.player.Player
import org.schabi.newpipe.player.helper.PlayerHelper
import org.schabi.newpipe.player.ui.VideoPlayerUi

/**
Expand All @@ -24,11 +25,87 @@ abstract class BasePlayerGestureListener(
protected val player: Player = playerUi.player
protected val binding: PlayerBinding = playerUi.binding

// ///////////////////////////////////////////////////////////////////
// Hold to fast forward (2x speed)
// ///////////////////////////////////////////////////////////////////

private var isHoldingForFastForward = false
private var originalPlaybackSpeed = 1.0f
private val fastForwardSpeed = 2.0f

override fun onTouch(v: View, event: MotionEvent): Boolean {
playerUi.gestureDetector.onTouchEvent(event)

// Handle touch up to restore original speed when hold-to-fast-forward is active
if (event.action == MotionEvent.ACTION_UP || event.action == MotionEvent.ACTION_CANCEL) {
if (isHoldingForFastForward) {
stopHoldToFastForward()
}
}

return false
}

override fun onLongPress(e: MotionEvent) {
if (DEBUG) {
Log.d(TAG, "onLongPress called with e = [$e]")
}

// Check if hold-to-fast-forward is enabled in settings
if (!PlayerHelper.isHoldToFastForwardEnabled(player.context)) {
return
}

// Only activate if player is playing and not in a popup menu
if (player.currentState != Player.STATE_PLAYING || playerUi.isSomePopupMenuVisible) {
return
}

// Don't activate during double tap mode
if (isDoubleTapping) {
return
}

startHoldToFastForward()
}

private fun startHoldToFastForward() {
if (isHoldingForFastForward) {
return
}

if (DEBUG) {
Log.d(TAG, "startHoldToFastForward: activating 2x speed")
}

isHoldingForFastForward = true
originalPlaybackSpeed = player.playbackSpeed

// Set playback speed to 2x
player.setPlaybackSpeed(fastForwardSpeed)

// Show visual feedback
playerUi.onHoldToFastForwardStart()
}

private fun stopHoldToFastForward() {
if (!isHoldingForFastForward) {
return
}

if (DEBUG) {
Log.d(TAG, "stopHoldToFastForward: restoring original speed $originalPlaybackSpeed")
}

isHoldingForFastForward = false

// Restore original playback speed
player.setPlaybackSpeed(originalPlaybackSpeed)

// Hide visual feedback
playerUi.onHoldToFastForwardEnd()
}

private fun onDoubleTap(
event: MotionEvent,
portion: DisplayPortion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,11 @@ public static boolean isAutoQueueEnabled(@NonNull final Context context) {
.getBoolean(context.getString(R.string.auto_queue_key), false);
}

public static boolean isHoldToFastForwardEnabled(@NonNull final Context context) {
return getPreferences(context)
.getBoolean(context.getString(R.string.hold_to_fast_forward_key), true);
}

public static boolean isClearingQueueConfirmationRequired(@NonNull final Context context) {
return getPreferences(context)
.getBoolean(context.getString(R.string.clear_queue_confirmation_key), false);
Expand Down
27 changes: 27 additions & 0 deletions app/src/main/java/org/schabi/newpipe/player/ui/VideoPlayerUi.java
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,33 @@ protected void setupElementsSize(final int buttonsMinWidth,
//endregion


/*//////////////////////////////////////////////////////////////////////////
// Hold to fast forward
//////////////////////////////////////////////////////////////////////////*/
//region Hold to fast forward

/**
* Called when hold-to-fast-forward is activated (long press detected).
* Shows the visual indicator overlay.
*/
public void onHoldToFastForwardStart() {
animate(binding.holdToFastForwardOverlay, true, DEFAULT_CONTROLS_DURATION);
// Hide controls while fast forwarding
if (isControlsVisible()) {
hideControls(DEFAULT_CONTROLS_DURATION, 0);
}
}

/**
* Called when hold-to-fast-forward is deactivated (finger released).
* Hides the visual indicator overlay.
*/
public void onHoldToFastForwardEnd() {
animate(binding.holdToFastForwardOverlay, false, DEFAULT_CONTROLS_DURATION);
}
//endregion


/*//////////////////////////////////////////////////////////////////////////
// Broadcast receiver
//////////////////////////////////////////////////////////////////////////*/
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/res/drawable/ic_fast_forward.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="@color/defaultIconTint"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:pathData="M4,18l8.5,-6L4,6v12zM13,6v12l8.5,-6L13,6z" />
</vector>
36 changes: 36 additions & 0 deletions app/src/main/res/layout/player.xml
Original file line number Diff line number Diff line change
Expand Up @@ -791,4 +791,40 @@
android:alpha="0"
android:visibility="invisible" /> <!-- Required for the first appearance fading correctly -->

<!-- Hold to fast forward indicator -->
<LinearLayout
android:id="@+id/holdToFastForwardOverlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="80dp"
android:background="@drawable/background_oval_black_transparent"
android:gravity="center"
android:orientation="horizontal"
android:paddingStart="20dp"
android:paddingTop="12dp"
android:paddingEnd="20dp"
android:paddingBottom="12dp"
android:visibility="gone"
tools:visibility="visible">

<androidx.appcompat.widget.AppCompatImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="8dp"
android:src="@drawable/ic_fast_forward"
app:tint="@color/white"
tools:ignore="ContentDescription" />

<org.schabi.newpipe.views.NewPipeTextView
android:id="@+id/holdToFastForwardText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hold_to_fast_forward_indicator"
android:textColor="@android:color/white"
android:textSize="16sp"
android:textStyle="bold" />

</LinearLayout>

</RelativeLayout>
2 changes: 2 additions & 0 deletions app/src/main/res/values/settings_keys.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
<string name="clear_queue_confirmation_key">clear_queue_confirmation_key</string>
<string name="ignore_hardware_media_buttons_key">ignore_hardware_media_buttons_key</string>

<string name="hold_to_fast_forward_key">hold_to_fast_forward_key</string>

<string name="popup_saved_width_key">popup_saved_width</string>
<string name="popup_saved_x_key">popup_saved_x</string>
<string name="popup_saved_y_key">popup_saved_y</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@
<string name="clear_queue_confirmation_description">The active player queue will be replaced</string>
<string name="ignore_hardware_media_buttons_title">Ignore hardware media button events</string>
<string name="ignore_hardware_media_buttons_summary">Useful, for instance, if you are using a headset with broken physical buttons</string>
<string name="hold_to_fast_forward_title">Hold to fast forward</string>
<string name="hold_to_fast_forward_summary">Tap and hold on the video to play at 2x speed while held</string>
<string name="hold_to_fast_forward_indicator">2x Speed</string>
<string name="show_comments_title">Show comments</string>
<string name="show_comments_summary">Turn off to hide comments</string>
<string name="show_next_and_similar_title">Show \'Next\' and \'Similar\' videos</string>
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/res/xml/video_audio_settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -249,5 +249,13 @@
android:title="@string/ignore_hardware_media_buttons_title"
app:singleLineTitle="false"
app:iconSpaceReserved="false" />

<SwitchPreferenceCompat
android:defaultValue="true"
android:key="@string/hold_to_fast_forward_key"
android:summary="@string/hold_to_fast_forward_summary"
android:title="@string/hold_to_fast_forward_title"
app:singleLineTitle="false"
app:iconSpaceReserved="false" />
</PreferenceCategory>
</PreferenceScreen>