feat: don't seek after scrubbing when stopping gesture above timebar

This commit is contained in:
Bnyro 2024-03-05 20:31:04 +01:00
parent f8915f3c2c
commit 17615b3eab
5 changed files with 73 additions and 16 deletions

View File

@ -85,7 +85,7 @@ class OfflinePlayerActivity : BaseActivity() {
super.onPlaybackStateChanged(playbackState) super.onPlaybackStateChanged(playbackState)
// setup seekbar preview // setup seekbar preview
if (playbackState == Player.STATE_READY) { if (playbackState == Player.STATE_READY) {
binding.player.binding.exoProgress.addListener( binding.player.binding.exoProgress.addSeekBarListener(
SeekbarPreviewListener( SeekbarPreviewListener(
timeFrameReceiver ?: return, timeFrameReceiver ?: return,
binding.player.binding, binding.player.binding,

View File

@ -948,8 +948,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
player = exoPlayer player = exoPlayer
} }
playerBinding.exoProgress.setPlayer(exoPlayer)
initializePlayerView() initializePlayerView()
// don't continue playback when the fragment is re-created after Android killed it // don't continue playback when the fragment is re-created after Android killed it
@ -1095,7 +1093,7 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
playerBinding.seekbarPreview.isGone = true playerBinding.seekbarPreview.isGone = true
seekBarPreviewListener?.let { playerBinding.exoProgress.removeListener(it) } seekBarPreviewListener?.let { playerBinding.exoProgress.removeListener(it) }
seekBarPreviewListener = createSeekbarPreviewListener().also { seekBarPreviewListener = createSeekbarPreviewListener().also {
playerBinding.exoProgress.addListener(it) playerBinding.exoProgress.addSeekBarListener(it)
} }
} }

View File

@ -182,8 +182,9 @@ open class CustomExoPlayerView(
} }
}) })
player?.let { binding.exoProgress.setPlayer(it) }
// prevent the controls from disappearing while scrubbing the time bar // prevent the controls from disappearing while scrubbing the time bar
binding.exoProgress.addListener(object : TimeBar.OnScrubListener { binding.exoProgress.addSeekBarListener(object : TimeBar.OnScrubListener {
override fun onScrubStart(timeBar: TimeBar, position: Long) { override fun onScrubStart(timeBar: TimeBar, position: Long) {
cancelHideControllerTask() cancelHideControllerTask()
} }

View File

@ -0,0 +1,66 @@
package com.github.libretube.ui.views
import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import androidx.media3.ui.DefaultTimeBar
import androidx.media3.ui.PlayerControlView
import androidx.media3.ui.TimeBar
import androidx.media3.ui.TimeBar.OnScrubListener
import com.github.libretube.extensions.dpToPx
@UnstableApi
open class DismissableTimeBar(
context: Context,
attributeSet: AttributeSet? = null
): DefaultTimeBar(context, attributeSet) {
private var shouldAddListener = false
var exoPlayer: Player? = null
private var lastYPosition = 0f
init {
addSeekBarListener(object : OnScrubListener {
override fun onScrubStart(timeBar: TimeBar, position: Long) = Unit
override fun onScrubMove(timeBar: TimeBar, position: Long) = Unit
override fun onScrubStop(timeBar: TimeBar, position: Long, canceled: Boolean) {
if (lastYPosition > MINIMUM_ACCEPTED_HEIGHT.dpToPx()) exoPlayer?.seekTo(position)
}
})
}
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent): Boolean {
lastYPosition = event.y
return super.onTouchEvent(event)
}
/**
* DO NOT CALL THIS METHOD DIRECTLY. Use [addSeekBarListener] instead!
*/
override fun addListener(listener: OnScrubListener) {
if (shouldAddListener) super.addListener(listener)
}
/**
* Wrapper to circumvent adding the listener created by [PlayerControlView]
*/
fun addSeekBarListener(listener: OnScrubListener) {
shouldAddListener = true
addListener(listener)
shouldAddListener = false
}
fun setPlayer(player: Player) {
this.exoPlayer = player
}
companion object {
private const val MINIMUM_ACCEPTED_HEIGHT = -70f
}
}

View File

@ -7,9 +7,7 @@ import android.graphics.Rect
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View import android.view.View
import androidx.core.view.marginLeft import androidx.core.view.marginLeft
import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi import androidx.media3.common.util.UnstableApi
import androidx.media3.ui.DefaultTimeBar
import com.github.libretube.api.obj.Segment import com.github.libretube.api.obj.Segment
import com.github.libretube.extensions.dpToPx import com.github.libretube.extensions.dpToPx
import com.github.libretube.helpers.PreferenceHelper import com.github.libretube.helpers.PreferenceHelper
@ -23,10 +21,8 @@ import com.google.android.material.R
class MarkableTimeBar( class MarkableTimeBar(
context: Context, context: Context,
attributeSet: AttributeSet? = null attributeSet: AttributeSet? = null
) : DefaultTimeBar(context, attributeSet) { ) : DismissableTimeBar(context, attributeSet) {
private var segments = listOf<Segment>() private var segments = listOf<Segment>()
private var player: Player? = null
private var length: Int = 0 private var length: Int = 0
private val progressBarHeight = 2f.dpToPx() private val progressBarHeight = 2f.dpToPx()
@ -37,7 +33,7 @@ class MarkableTimeBar(
} }
private fun drawSegments(canvas: Canvas) { private fun drawSegments(canvas: Canvas) {
if (player == null) return if (exoPlayer == null) return
canvas.save() canvas.save()
val horizontalOffset = (parent as View).marginLeft val horizontalOffset = (parent as View).marginLeft
@ -68,7 +64,7 @@ class MarkableTimeBar(
} }
private fun Float.toLength(): Int { private fun Float.toLength(): Int {
return (this * 1000 / player!!.duration * length).toInt() return (this * 1000 / exoPlayer!!.duration * length).toInt()
} }
fun setSegments(segments: List<Segment>) { fun setSegments(segments: List<Segment>) {
@ -78,8 +74,4 @@ class MarkableTimeBar(
fun clearSegments() { fun clearSegments() {
segments = listOf() segments = listOf()
} }
fun setPlayer(player: Player) {
this.player = player
}
} }