diff --git a/src/main/assets/changelog-alpha.txt b/src/main/assets/changelog-alpha.txt index 27c02f985..7035cbd91 100644 --- a/src/main/assets/changelog-alpha.txt +++ b/src/main/assets/changelog-alpha.txt @@ -1,3 +1,6 @@ +/Alpha 360 (2025-04-21) +Added video frame step controls (thanks to ecawthorne and japanesephundroid) + /Alpha 359 (2025-04-20) Added support for emotes in comment flairs (thanks to bharatknv) Added "Mark as Read/Unread" fling action, and optional context menu item (thanks to JoshAusHessen and codeofdusk) diff --git a/src/main/assets/changelog.txt b/src/main/assets/changelog.txt index 64ecaf899..a78eb4513 100644 --- a/src/main/assets/changelog.txt +++ b/src/main/assets/changelog.txt @@ -1,5 +1,6 @@ 114/1.25 Added video playback speed control (thanks to folkemat) +Added video frame step controls (thanks to ecawthorne and japanesephundroid) Added support for emotes in comment flairs (thanks to bharatknv) Show label on crossposts, and add "Go to Crosspost Origin" to post menu (thanks to folkemat) Added "Mark as Read/Unread" fling action, and optional post menu item (thanks to JoshAusHessen and codeofdusk) diff --git a/src/main/java/org/quantumbadger/redreader/common/PrefsUtility.java b/src/main/java/org/quantumbadger/redreader/common/PrefsUtility.java index 7fed56a1b..c47ce987d 100644 --- a/src/main/java/org/quantumbadger/redreader/common/PrefsUtility.java +++ b/src/main/java/org/quantumbadger/redreader/common/PrefsUtility.java @@ -802,6 +802,11 @@ public static boolean pref_behaviour_video_playback_controls() { true); } + public static boolean pref_behaviour_video_frame_step() { + return getBoolean(R.string.pref_behaviour_video_frame_step_key, + false); + } + public static boolean pref_behaviour_video_mute_default() { return getBoolean( R.string.pref_behaviour_video_mute_default_key, diff --git a/src/main/java/org/quantumbadger/redreader/views/video/ExoPlayerWrapperView.java b/src/main/java/org/quantumbadger/redreader/views/video/ExoPlayerWrapperView.java index 0bc6d8c31..d745bd21f 100644 --- a/src/main/java/org/quantumbadger/redreader/views/video/ExoPlayerWrapperView.java +++ b/src/main/java/org/quantumbadger/redreader/views/video/ExoPlayerWrapperView.java @@ -146,7 +146,7 @@ public ExoPlayerWrapperView( addButton(createButton( context, mControlView, - R.drawable.icon_previous, + R.drawable.icon_restart, R.string.video_restart, view -> { mVideoPlayer.seekTo(0); @@ -178,7 +178,68 @@ public ExoPlayerWrapperView( updateProgress(); }); - addButton(mPlayButton, buttons); + if (PrefsUtility.pref_behaviour_video_frame_step()) { + final long frameDuration = (long)(1000f / (mVideoPlayer.getVideoFormat() != null + ? mVideoPlayer.getVideoFormat().frameRate + : 30)); + + final ImageButton stepBackButton = createButton( + context, + mControlView, + R.drawable.icon_step_back, + R.string.video_step_back, + view -> { + mVideoPlayer.seekTo(mVideoPlayer.getCurrentPosition() - frameDuration); + updateProgress(); + } + ); + + final ImageButton stepForwardButton = createButton( + context, + mControlView, + R.drawable.icon_step_forward, + R.string.video_step_forward, + view -> { + mVideoPlayer.seekTo(mVideoPlayer.getCurrentPosition() + frameDuration); + updateProgress(); + } + ); + + mVideoPlayer.addListener(new Player.Listener() { + @Override + public void onIsPlayingChanged(final boolean isPlaying) { + if (isPlaying) { + stepBackButton.setImageAlpha(0x3F); + stepBackButton.setContentDescription( + context.getString(R.string.video_step_back_disabled)); + stepBackButton.setEnabled(false); + + stepForwardButton.setImageAlpha(0x3F); + stepForwardButton.setContentDescription( + context.getString(R.string.video_step_forward_disabled)); + stepForwardButton.setEnabled(false); + + } else { + stepBackButton.setImageAlpha(0xFF); + stepBackButton.setContentDescription( + context.getString(R.string.video_step_back)); + stepBackButton.setEnabled(true); + + stepForwardButton.setImageAlpha(0xFF); + stepForwardButton.setContentDescription( + context.getString(R.string.video_step_forward)); + stepForwardButton.setEnabled(true); + } + } + }); + + addButton(stepBackButton, buttons); + addButton(mPlayButton, buttons); + addButton(stepForwardButton, buttons); + + } else { + addButton(mPlayButton, buttons); + } addButton(createButton( context, diff --git a/src/main/res/drawable/icon_restart.xml b/src/main/res/drawable/icon_restart.xml new file mode 100644 index 000000000..7ebe4bc66 --- /dev/null +++ b/src/main/res/drawable/icon_restart.xml @@ -0,0 +1,26 @@ + + + + + + + diff --git a/src/main/res/drawable/icon_previous.xml b/src/main/res/drawable/icon_step_back.xml similarity index 72% rename from src/main/res/drawable/icon_previous.xml rename to src/main/res/drawable/icon_step_back.xml index 9564a2a35..1397eb87d 100644 --- a/src/main/res/drawable/icon_previous.xml +++ b/src/main/res/drawable/icon_step_back.xml @@ -1,4 +1,4 @@ - + + android:height="32dp" + android:viewportHeight="24.0" + android:viewportWidth="24.0"> - + + + diff --git a/src/main/res/drawable/icon_step_forward.xml b/src/main/res/drawable/icon_step_forward.xml new file mode 100644 index 000000000..2ced92191 --- /dev/null +++ b/src/main/res/drawable/icon_step_forward.xml @@ -0,0 +1,26 @@ + + + + + + + diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 120ec4efd..eba05baca 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -1482,9 +1482,13 @@ Unmute Restart video Rewind + Step back + Step back disabled Play Pause Fast forward + Step forward + Step forward disabled Zoom in Zoom out @@ -1910,4 +1914,8 @@ Crosspost tag Crosspost. Go to Crosspost Origin + + Enable stepping frame by frame + pref_behaviour_video_frame_step + diff --git a/src/main/res/xml/prefs_images_video.xml b/src/main/res/xml/prefs_images_video.xml index 7126cba0d..248931758 100644 --- a/src/main/res/xml/prefs_images_video.xml +++ b/src/main/res/xml/prefs_images_video.xml @@ -43,6 +43,10 @@ android:key="@string/pref_behaviour_video_playback_controls_key" android:defaultValue="true"/> + +