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)
// setup seekbar preview
if (playbackState == Player.STATE_READY) {
binding.player.binding.exoProgress.addListener(
binding.player.binding.exoProgress.addSeekBarListener(
SeekbarPreviewListener(
timeFrameReceiver ?: return,
binding.player.binding,

View File

@ -948,8 +948,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
player = exoPlayer
}
playerBinding.exoProgress.setPlayer(exoPlayer)
initializePlayerView()
// 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
seekBarPreviewListener?.let { playerBinding.exoProgress.removeListener(it) }
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
binding.exoProgress.addListener(object : TimeBar.OnScrubListener {
binding.exoProgress.addSeekBarListener(object : TimeBar.OnScrubListener {
override fun onScrubStart(timeBar: TimeBar, position: Long) {
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.view.View
import androidx.core.view.marginLeft
import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import androidx.media3.ui.DefaultTimeBar
import com.github.libretube.api.obj.Segment
import com.github.libretube.extensions.dpToPx
import com.github.libretube.helpers.PreferenceHelper
@ -23,10 +21,8 @@ import com.google.android.material.R
class MarkableTimeBar(
context: Context,
attributeSet: AttributeSet? = null
) : DefaultTimeBar(context, attributeSet) {
) : DismissableTimeBar(context, attributeSet) {
private var segments = listOf<Segment>()
private var player: Player? = null
private var length: Int = 0
private val progressBarHeight = 2f.dpToPx()
@ -37,7 +33,7 @@ class MarkableTimeBar(
}
private fun drawSegments(canvas: Canvas) {
if (player == null) return
if (exoPlayer == null) return
canvas.save()
val horizontalOffset = (parent as View).marginLeft
@ -68,7 +64,7 @@ class MarkableTimeBar(
}
private fun Float.toLength(): Int {
return (this * 1000 / player!!.duration * length).toInt()
return (this * 1000 / exoPlayer!!.duration * length).toInt()
}
fun setSegments(segments: List<Segment>) {
@ -78,8 +74,4 @@ class MarkableTimeBar(
fun clearSegments() {
segments = listOf()
}
fun setPlayer(player: Player) {
this.player = player
}
}