Skip to content

Commit 00f76a0

Browse files
Carl MillerCarl Miller
authored andcommitted
Add hold-to-fast-forward feature (2x speed on long press)
- Added long press gesture to increase playback speed to 2x while holding - Added setting toggle in Video & Audio settings to enable/disable the feature - Feature is enabled by default - Updated GitHub Actions workflow to build APK and create releases automatically
1 parent ebe0759 commit 00f76a0

6 files changed

Lines changed: 106 additions & 7 deletions

File tree

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
1-
name: "Build unsigned release APK on master"
1+
name: "Build and Release APK"
22

33
on:
44
workflow_dispatch:
5+
push:
6+
branches:
7+
- master
8+
- main
9+
tags:
10+
- 'v*'
511

612
jobs:
713
release:
814
runs-on: ubuntu-latest
15+
permissions:
16+
contents: write
917
steps:
1018
- uses: actions/checkout@v4
11-
with:
12-
ref: 'master'
1319

1420
- uses: actions/setup-java@v4
1521
with:
@@ -20,19 +26,43 @@ jobs:
2026
- name: "Build release APK"
2127
run: ./gradlew assembleRelease --stacktrace
2228

23-
- name: "Rename APK"
29+
- name: "Get version name"
30+
id: version
2431
run: |
2532
VERSION_NAME="$(jq -r ".elements[0].versionName" "app/build/outputs/apk/release/output-metadata.json")"
33+
echo "version=$VERSION_NAME" >> "$GITHUB_OUTPUT"
2634
echo "Version name: $VERSION_NAME" >> "$GITHUB_STEP_SUMMARY"
2735
echo '```json' >> "$GITHUB_STEP_SUMMARY"
2836
cat "app/build/outputs/apk/release/output-metadata.json" >> "$GITHUB_STEP_SUMMARY"
2937
echo >> "$GITHUB_STEP_SUMMARY"
3038
echo '```' >> "$GITHUB_STEP_SUMMARY"
31-
# assume there is only one APK in that folder
32-
mv app/build/outputs/apk/release/*.apk "app/build/outputs/apk/release/NewPipe_v$VERSION_NAME.apk"
3339
34-
- name: "Upload APK"
40+
- name: "Rename APK"
41+
run: |
42+
mv app/build/outputs/apk/release/*.apk "app/build/outputs/apk/release/NewPipe_v${{ steps.version.outputs.version }}.apk"
43+
44+
- name: "Upload APK as artifact"
3545
uses: actions/upload-artifact@v4
3646
with:
3747
name: app
3848
path: app/build/outputs/apk/release/*.apk
49+
50+
- name: "Create Release"
51+
uses: softprops/action-gh-release@v1
52+
with:
53+
tag_name: v${{ steps.version.outputs.version }}-${{ github.run_number }}
54+
name: Release v${{ steps.version.outputs.version }}
55+
body: |
56+
## NewPipe Release v${{ steps.version.outputs.version }}
57+
58+
### New Features
59+
- **Hold to Fast-Forward**: Hold anywhere on the player to increase playback speed to 2x. Release to return to normal speed.
60+
- New setting in Video & Audio settings to enable/disable this feature.
61+
62+
### Download
63+
Download the APK below and install it on your Android device.
64+
files: app/build/outputs/apk/release/*.apk
65+
draft: false
66+
prerelease: false
67+
env:
68+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

app/src/main/java/org/schabi/newpipe/player/gesture/BasePlayerGestureListener.kt

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import android.view.View
99
import androidx.core.os.postDelayed
1010
import org.schabi.newpipe.databinding.PlayerBinding
1111
import org.schabi.newpipe.player.Player
12+
import org.schabi.newpipe.player.helper.PlayerHelper
1213
import org.schabi.newpipe.player.ui.VideoPlayerUi
1314

1415
/**
@@ -24,8 +25,59 @@ abstract class BasePlayerGestureListener(
2425
protected val player: Player = playerUi.player
2526
protected val binding: PlayerBinding = playerUi.binding
2627

28+
// ///////////////////////////////////////////////////////////////////
29+
// Long press (hold) to fast-forward
30+
// ///////////////////////////////////////////////////////////////////
31+
32+
private var isHoldingForFastForward = false
33+
private var originalPlaybackSpeed = 1.0f
34+
private val longPressHandler: Handler = Handler(Looper.getMainLooper())
35+
private val longPressRunnable = Runnable {
36+
if (PlayerHelper.isHoldToFastForwardEnabled(player.context) &&
37+
player.currentState == Player.STATE_PLAYING &&
38+
!playerUi.isSomePopupMenuVisible
39+
) {
40+
startFastForward()
41+
}
42+
}
43+
44+
private fun startFastForward() {
45+
if (!isHoldingForFastForward) {
46+
if (DEBUG) {
47+
Log.d(TAG, "startFastForward called")
48+
}
49+
isHoldingForFastForward = true
50+
originalPlaybackSpeed = player.playbackSpeed
51+
player.setPlaybackSpeed(2.0f)
52+
}
53+
}
54+
55+
private fun stopFastForward() {
56+
if (isHoldingForFastForward) {
57+
if (DEBUG) {
58+
Log.d(TAG, "stopFastForward called, restoring speed to $originalPlaybackSpeed")
59+
}
60+
isHoldingForFastForward = false
61+
player.setPlaybackSpeed(originalPlaybackSpeed)
62+
}
63+
longPressHandler.removeCallbacks(longPressRunnable)
64+
}
65+
2766
override fun onTouch(v: View, event: MotionEvent): Boolean {
2867
playerUi.gestureDetector.onTouchEvent(event)
68+
69+
// Handle long press for fast-forward
70+
when (event.action) {
71+
MotionEvent.ACTION_DOWN -> {
72+
// Start timer for long press detection
73+
longPressHandler.postDelayed(longPressRunnable, LONG_PRESS_DELAY)
74+
}
75+
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
76+
// Stop fast-forward when finger is lifted
77+
stopFastForward()
78+
}
79+
}
80+
2981
return false
3082
}
3183

@@ -184,5 +236,6 @@ abstract class BasePlayerGestureListener(
184236

185237
private const val DOUBLE_TAP = "doubleTap"
186238
private const val DOUBLE_TAP_DELAY = 550L
239+
private const val LONG_PRESS_DELAY = 500L
187240
}
188241
}

app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,11 @@ public static boolean isStartMainPlayerFullscreenEnabled(@NonNull final Context
226226
.getBoolean(context.getString(R.string.start_main_player_fullscreen_key), false);
227227
}
228228

229+
public static boolean isHoldToFastForwardEnabled(@NonNull final Context context) {
230+
return getPreferences(context)
231+
.getBoolean(context.getString(R.string.hold_to_fast_forward_key), true);
232+
}
233+
229234
public static boolean isAutoQueueEnabled(@NonNull final Context context) {
230235
return getPreferences(context)
231236
.getBoolean(context.getString(R.string.auto_queue_key), false);

app/src/main/res/values/settings_keys.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
<string name="screen_brightness_timestamp_key">screen_brightness_timestamp_key</string>
2525
<string name="clear_queue_confirmation_key">clear_queue_confirmation_key</string>
2626
<string name="ignore_hardware_media_buttons_key">ignore_hardware_media_buttons_key</string>
27+
<string name="hold_to_fast_forward_key">hold_to_fast_forward_key</string>
2728

2829
<string name="popup_saved_width_key">popup_saved_width</string>
2930
<string name="popup_saved_x_key">popup_saved_x</string>

app/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@
9191
<string name="clear_queue_confirmation_description">The active player queue will be replaced</string>
9292
<string name="ignore_hardware_media_buttons_title">Ignore hardware media button events</string>
9393
<string name="ignore_hardware_media_buttons_summary">Useful, for instance, if you are using a headset with broken physical buttons</string>
94+
<string name="hold_to_fast_forward_title">Hold to fast-forward</string>
95+
<string name="hold_to_fast_forward_summary">Hold anywhere on the player to increase playback speed to 2x. Release to return to normal speed</string>
9496
<string name="show_comments_title">Show comments</string>
9597
<string name="show_comments_summary">Turn off to hide comments</string>
9698
<string name="show_next_and_similar_title">Show \'Next\' and \'Similar\' videos</string>

app/src/main/res/xml/video_audio_settings.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,5 +249,13 @@
249249
android:title="@string/ignore_hardware_media_buttons_title"
250250
app:singleLineTitle="false"
251251
app:iconSpaceReserved="false" />
252+
253+
<SwitchPreferenceCompat
254+
android:defaultValue="true"
255+
android:key="@string/hold_to_fast_forward_key"
256+
android:summary="@string/hold_to_fast_forward_summary"
257+
android:title="@string/hold_to_fast_forward_title"
258+
app:singleLineTitle="false"
259+
app:iconSpaceReserved="false" />
252260
</PreferenceCategory>
253261
</PreferenceScreen>

0 commit comments

Comments
 (0)