Allow seeking video by swiping or tapping (#132)
* Allow seeking in players by tapping * Allow seeking in players by swiping horizontally * Small cleanup Co-authored-by: Jarne Demeulemeester <jarnedemeulemeester@gmail.com>
This commit is contained in:
parent
4a7f039664
commit
53d1720ad0
2 changed files with 112 additions and 9 deletions
|
@ -34,32 +34,81 @@ class PlayerGestureHelper(
|
|||
|
||||
private var swipeGestureValueTrackerVolume = -1f
|
||||
private var swipeGestureValueTrackerBrightness = -1f
|
||||
private var swipeGestureValueTrackerProgress = -1L
|
||||
|
||||
private var swipeGestureVolumeOpen = false
|
||||
private var swipeGestureBrightnessOpen = false
|
||||
private var swipeGestureProgressOpen = false
|
||||
|
||||
private val tapGestureDetector = GestureDetector(playerView.context, object : GestureDetector.SimpleOnGestureListener() {
|
||||
override fun onSingleTapUp(e: MotionEvent?): Boolean {
|
||||
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
|
||||
playerView.apply {
|
||||
if (!isControllerFullyVisible) showController() else hideController()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onDoubleTap(e: MotionEvent): Boolean {
|
||||
val viewCenterX = playerView.measuredWidth / 2
|
||||
val currentPos = playerView.player?.currentPosition ?: 0
|
||||
|
||||
if (e.x.toInt() > viewCenterX) {
|
||||
playerView.player?.seekTo(currentPos + appPreferences.playerSeekForwardIncrement)
|
||||
}
|
||||
else {
|
||||
playerView.player?.seekTo((currentPos - appPreferences.playerSeekBackIncrement).coerceAtLeast(0))
|
||||
}
|
||||
return true
|
||||
}
|
||||
})
|
||||
|
||||
private val gestureDetector = GestureDetector(playerView.context, object : GestureDetector.SimpleOnGestureListener() {
|
||||
override fun onSingleTapUp(e: MotionEvent): Boolean {
|
||||
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
|
||||
playerView.apply {
|
||||
if (!isControllerFullyVisible) showController() else hideController()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onDoubleTap(e: MotionEvent): Boolean {
|
||||
val viewCenterX = playerView.measuredWidth / 2
|
||||
val currentPos = playerView.player?.currentPosition ?: 0
|
||||
|
||||
if (e.x.toInt() > viewCenterX) {
|
||||
playerView.player?.seekTo(currentPos + appPreferences.playerSeekForwardIncrement)
|
||||
}
|
||||
else {
|
||||
playerView.player?.seekTo((currentPos - appPreferences.playerSeekBackIncrement).coerceAtLeast(0))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onScroll(firstEvent: MotionEvent, currentEvent: MotionEvent, distanceX: Float, distanceY: Float): Boolean {
|
||||
// Check whether swipe was oriented vertically
|
||||
if (abs(distanceY / distanceX) < 2)
|
||||
return false
|
||||
|
||||
if (firstEvent.y < playerView.resources.dip(Constants.GESTURE_EXCLUSION_AREA_TOP))
|
||||
return false
|
||||
|
||||
// Check whether swipe was oriented vertically
|
||||
if (abs(distanceY / distanceX) < 2) {
|
||||
return if ((abs(currentEvent.x - firstEvent.x) > 50 || swipeGestureProgressOpen) &&
|
||||
(!swipeGestureBrightnessOpen && !swipeGestureVolumeOpen)) {
|
||||
val currentPos = playerView.player?.currentPosition ?: 0
|
||||
val vidDuration = playerView.player?.duration ?: 0
|
||||
|
||||
val difference = ((currentEvent.x - firstEvent.x) * 90).toLong()
|
||||
val newPos = (currentPos + difference).coerceIn(0, vidDuration)
|
||||
|
||||
activity.binding.progressScrubberLayout.visibility = View.VISIBLE
|
||||
activity.binding.progressScrubberText.text = "${longToTimestamp(difference)} [${longToTimestamp(newPos, true)}]"
|
||||
swipeGestureValueTrackerProgress = newPos
|
||||
swipeGestureProgressOpen = true
|
||||
true
|
||||
} else false
|
||||
}
|
||||
|
||||
if (swipeGestureValueTrackerProgress > -1 || swipeGestureProgressOpen)
|
||||
return false
|
||||
|
||||
val viewCenterX = playerView.measuredWidth / 2
|
||||
|
||||
|
@ -84,6 +133,8 @@ class PlayerGestureHelper(
|
|||
activity.binding.gestureVolumeProgressBar.max = maxVolume
|
||||
activity.binding.gestureVolumeProgressBar.progress = toSet
|
||||
activity.binding.gestureVolumeText.text = "${(toSet.toFloat()/maxVolume.toFloat()).times(100).toInt()}%"
|
||||
|
||||
swipeGestureVolumeOpen = true
|
||||
} else {
|
||||
// Swiping on the left, change brightness
|
||||
val window = activity.window
|
||||
|
@ -107,6 +158,8 @@ class PlayerGestureHelper(
|
|||
activity.binding.gestureBrightnessProgressBar.max = BRIGHTNESS_OVERRIDE_FULL.times(100).toInt()
|
||||
activity.binding.gestureBrightnessProgressBar.progress = lp.screenBrightness.times(100).toInt()
|
||||
activity.binding.gestureBrightnessText.text = "${(lp.screenBrightness/BRIGHTNESS_OVERRIDE_FULL).times(100).toInt()}%"
|
||||
|
||||
swipeGestureBrightnessOpen = true
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -123,6 +176,10 @@ class PlayerGestureHelper(
|
|||
}
|
||||
}
|
||||
|
||||
private val hideGestureProgressOverlayAction = Runnable {
|
||||
activity.binding.progressScrubberLayout.visibility = View.GONE
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles scale/zoom gesture
|
||||
*/
|
||||
|
@ -151,17 +208,38 @@ class PlayerGestureHelper(
|
|||
if (visibility == View.VISIBLE) {
|
||||
removeCallbacks(hideGestureVolumeIndicatorOverlayAction)
|
||||
postDelayed(hideGestureVolumeIndicatorOverlayAction, 1000)
|
||||
swipeGestureVolumeOpen = false
|
||||
}
|
||||
}
|
||||
activity.binding.gestureBrightnessLayout.apply {
|
||||
if (visibility == View.VISIBLE) {
|
||||
removeCallbacks(hideGestureBrightnessIndicatorOverlayAction)
|
||||
postDelayed(hideGestureBrightnessIndicatorOverlayAction, 1000)
|
||||
swipeGestureBrightnessOpen = false
|
||||
}
|
||||
}
|
||||
activity.binding.progressScrubberLayout.apply {
|
||||
if (visibility == View.VISIBLE) {
|
||||
if (swipeGestureValueTrackerProgress > -1) {
|
||||
playerView.player?.seekTo(swipeGestureValueTrackerProgress)
|
||||
}
|
||||
removeCallbacks(hideGestureProgressOverlayAction)
|
||||
postDelayed(hideGestureProgressOverlayAction, 1000)
|
||||
swipeGestureProgressOpen = false
|
||||
|
||||
swipeGestureValueTrackerProgress = -1L
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun longToTimestamp(duration: Long, noSign: Boolean = false): String {
|
||||
val sign = if (noSign) "" else if (duration < 0) "-" else "+"
|
||||
val seconds = abs(duration).div(1000)
|
||||
|
||||
return String.format("%s%02d:%02d:%02d", sign, seconds / 3600, (seconds / 60) % 60, seconds % 60)
|
||||
}
|
||||
|
||||
init {
|
||||
if (appPreferences.playerBrightnessRemember) {
|
||||
activity.window.attributes.screenBrightness = appPreferences.playerBrightness
|
||||
|
|
|
@ -12,7 +12,30 @@
|
|||
android:layout_height="match_parent"
|
||||
android:background="@color/black"
|
||||
app:animation_enabled="false"
|
||||
app:show_buffering="always" />
|
||||
app:show_buffering="always">
|
||||
|
||||
</com.google.android.exoplayer2.ui.StyledPlayerView>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/progress_scrubber_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/overlay_background"
|
||||
android:clickable="false"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/progress_scrubber_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
android:textColor="@color/white"
|
||||
tools:text="+00:00:10 [00:00:20]" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/gesture_volume_layout"
|
||||
|
@ -33,7 +56,8 @@
|
|||
android:layout_height="24dp"
|
||||
android:layout_marginVertical="16dp"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/white" />
|
||||
android:textColor="@color/white"
|
||||
tools:text="58%" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/gesture_volume_progress_bar"
|
||||
|
@ -71,7 +95,8 @@
|
|||
android:layout_height="24dp"
|
||||
android:layout_marginVertical="16dp"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/white" />
|
||||
android:textColor="@color/white"
|
||||
tools:text="58%" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/gesture_brightness_progress_bar"
|
||||
|
|
Loading…
Reference in a new issue