diff --git a/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt index 908073fa7..42cf5c619 100644 --- a/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/fragments/PlayerFragment.kt @@ -164,6 +164,7 @@ class PlayerFragment : BaseFragment() { private var defaultSubtitleCode = "" private var sponsorBlockEnabled = true private var sponsorBlockNotifications = true + private var skipButtonsEnabled = false /** * for autoplay @@ -176,6 +177,11 @@ class PlayerFragment : BaseFragment() { */ private lateinit var nowPlayingNotification: NowPlayingNotification + /** + * history of played videos in the current lifecycle + */ + val videoIds = mutableListOf() + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) arguments?.let { @@ -204,7 +210,7 @@ class PlayerFragment : BaseFragment() { setUserPrefs() - if (autoplayEnabled == true) playerBinding.autoplayIV.setImageResource(R.drawable.ic_toggle_on) + if (autoplayEnabled) playerBinding.autoplayIV.setImageResource(R.drawable.ic_toggle_on) val mainActivity = activity as MainActivity if (autoRotationEnabled) { @@ -314,6 +320,11 @@ class PlayerFragment : BaseFragment() { if (defaultSubtitleCode.contains("-")) { defaultSubtitleCode = defaultSubtitleCode.split("-")[0] } + + skipButtonsEnabled = PreferenceHelper.getBoolean( + PreferenceKeys.SKIP_BUTTONS, + false + ) } private fun initializeTransitionLayout() { @@ -566,8 +577,6 @@ class PlayerFragment : BaseFragment() { playerBinding.fullscreen.setImageResource(R.drawable.ic_fullscreen_exit) playerBinding.exoTitle.visibility = View.VISIBLE - scaleControls(1.3F) - val mainActivity = activity as MainActivity if (!autoRotationEnabled) { // different orientations of the video are only available when auto rotation is disabled @@ -602,8 +611,6 @@ class PlayerFragment : BaseFragment() { playerBinding.fullscreen.setImageResource(R.drawable.ic_fullscreen) playerBinding.exoTitle.visibility = View.INVISIBLE - scaleControls(1F) - if (!autoRotationEnabled) { // switch back to portrait mode if auto rotation disabled val mainActivity = activity as MainActivity @@ -613,11 +620,6 @@ class PlayerFragment : BaseFragment() { Globals.IS_FULL_SCREEN = false } - private fun scaleControls(scaleFactor: Float) { - playerBinding.exoPlayPause.scaleX = scaleFactor - playerBinding.exoPlayPause.scaleY = scaleFactor - } - private fun toggleDescription() { if (binding.descLinLayout.isVisible) { // hide the description and chapters @@ -746,6 +748,7 @@ class PlayerFragment : BaseFragment() { } } } + videoIds += videoId!! } run() } @@ -754,7 +757,18 @@ class PlayerFragment : BaseFragment() { * set the videoId of the next stream for autoplay */ private fun setNextStream() { - nextStreamId = streams.relatedStreams!![0].url.toID() + // don't play a video if it got played before already + var index = 0 + while (nextStreamId == null || nextStreamId == videoId!! || + ( + videoIds.contains(nextStreamId) && + videoIds.indexOf(videoId) > videoIds.indexOf(nextStreamId) + ) + ) { + nextStreamId = streams.relatedStreams!![index].url.toID() + if (index + 1 < streams.relatedStreams!!.size) index += 1 + else break + } if (playlistId == null) return if (!this::autoPlayHelper.isInitialized) autoPlayHelper = AutoPlayHelper(playlistId!!) // search for the next videoId in the playlist @@ -823,17 +837,16 @@ class PlayerFragment : BaseFragment() { // used for autoplay and skipping to next video private fun playNextVideo() { + if (nextStreamId == null) return // check whether there is a new video in the queue // by making sure that the next and the current video aren't the same saveWatchPosition() // forces the comments to reload for the new video commentsLoaded = false binding.commentsRecView.adapter = null - if (videoId != nextStreamId) { - // save the id of the next stream as videoId and load the next video - videoId = nextStreamId - playVideo() - } + // save the id of the next stream as videoId and load the next video + videoId = nextStreamId + playVideo() } private fun prepareExoPlayerView() { @@ -882,7 +895,7 @@ class PlayerFragment : BaseFragment() { } // duration that's not greater than 0 indicates that the video is live - if (!(response.duration!! > 0)) { + if (response.duration!! <= 0) { isLive = true handleLiveVideo() } @@ -1052,6 +1065,22 @@ class PlayerFragment : BaseFragment() { Toast.makeText(context, R.string.login_first, Toast.LENGTH_SHORT).show() } } + + // next and previous buttons + playerBinding.skipPrev.visibility = if ( + skipButtonsEnabled && videoIds.indexOf(videoId!!) != 0 + ) View.VISIBLE else View.INVISIBLE + playerBinding.skipNext.visibility = if (skipButtonsEnabled) View.VISIBLE else View.INVISIBLE + + playerBinding.skipPrev.setOnClickListener { + val index = videoIds.indexOf(videoId!!) - 1 + videoId = videoIds[index] + playVideo() + } + + playerBinding.skipNext.setOnClickListener { + playNextVideo() + } } private fun enableDoubleTapToSeek() { diff --git a/app/src/main/java/com/github/libretube/preferences/PreferenceKeys.kt b/app/src/main/java/com/github/libretube/preferences/PreferenceKeys.kt index 47e89cb2d..1c0b8af8f 100644 --- a/app/src/main/java/com/github/libretube/preferences/PreferenceKeys.kt +++ b/app/src/main/java/com/github/libretube/preferences/PreferenceKeys.kt @@ -58,6 +58,7 @@ object PreferenceKeys { const val PLAYER_AUDIO_FORMAT = "player_audio_format" const val PLAYER_AUDIO_QUALITY = "player_audio_quality" const val DEFAULT_SUBTITLE = "default_subtitle" + const val SKIP_BUTTONS = "skip_buttons" /** * Download diff --git a/app/src/main/res/drawable/ic_next.xml b/app/src/main/res/drawable/ic_next.xml new file mode 100644 index 000000000..79972afe5 --- /dev/null +++ b/app/src/main/res/drawable/ic_next.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_prev.xml b/app/src/main/res/drawable/ic_prev.xml new file mode 100644 index 000000000..00db3759c --- /dev/null +++ b/app/src/main/res/drawable/ic_prev.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/double_tap_overlay.xml b/app/src/main/res/layout/double_tap_overlay.xml index e15dc5a15..717b05544 100644 --- a/app/src/main/res/layout/double_tap_overlay.xml +++ b/app/src/main/res/layout/double_tap_overlay.xml @@ -19,7 +19,6 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" - android:layout_marginStart="30dp" android:visibility="invisible"> + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f89599e88..9ffccc20d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -292,4 +292,6 @@ Download succeeded Share with start time Export Subscriptions + Skip buttons + Show buttons to skip to the next or previous video. diff --git a/app/src/main/res/values/style.xml b/app/src/main/res/values/style.xml index 986b322ef..d7d85f1d4 100644 --- a/app/src/main/res/values/style.xml +++ b/app/src/main/res/values/style.xml @@ -107,6 +107,14 @@ + +