add rwd/ffwd double tap indicator & pause/play on long press

This commit is contained in:
Jannik 2020-11-20 11:20:11 +01:00
parent 3880b3ab75
commit 256c32aa3c
Signed by: Seil0
GPG Key ID: E8459F3723C52C24
4 changed files with 148 additions and 67 deletions

View File

@ -11,7 +11,6 @@ import android.view.*
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GestureDetectorCompat
import androidx.core.view.isVisible
import androidx.core.view.postDelayed
import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.Player
@ -23,7 +22,10 @@ import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory
import com.google.android.exoplayer2.util.Util
import kotlinx.android.synthetic.main.activity_player.*
import kotlinx.android.synthetic.main.player_controls.*
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.preferences.Preferences
import org.mosad.teapod.ui.fragments.MediaFragment
@ -34,7 +36,6 @@ import java.util.*
import java.util.concurrent.TimeUnit
import kotlin.concurrent.scheduleAtFixedRate
class PlayerActivity : AppCompatActivity() {
private lateinit var player: SimpleExoPlayer
@ -257,12 +258,52 @@ class PlayerActivity : AppCompatActivity() {
Log.d(javaClass.name, "Released player")
}
/**
* TODO set position of rewind/fast forward indicators programmatically
*/
private fun rewind() {
player.seekTo(player.currentPosition - rwdTime)
// hide/show needed components
exo_double_tap_indicator.visibility = View.VISIBLE
ffwd_10_indicator.visibility = View.INVISIBLE
ffwd_10.visibility = View.INVISIBLE
rwd_10_indicator.onAnimationEndCallback = {
exo_double_tap_indicator.visibility = View.GONE
ffwd_10_indicator.visibility = View.VISIBLE
ffwd_10.visibility = View.VISIBLE
}
// run animation
rwd_10_indicator.runOnClickAnimation()
}
private fun forward() {
player.seekTo(player.currentPosition + fwdTime)
// hide/show needed components
exo_double_tap_indicator.visibility = View.VISIBLE
rwd_10_indicator.visibility = View.INVISIBLE
ffwd_10.visibility = View.INVISIBLE
ffwd_10_indicator.onAnimationEndCallback = {
exo_double_tap_indicator.visibility = View.GONE
rwd_10_indicator.visibility = View.VISIBLE
ffwd_10.visibility = View.VISIBLE
}
// run animation
ffwd_10_indicator.runOnClickAnimation()
}
private fun togglePausePlay() {
if (player.isPlaying) {
player.pause()
} else {
player.play()
}
}
private fun playNextEpisode() {
@ -282,7 +323,7 @@ class PlayerActivity : AppCompatActivity() {
// watchedCallback for next ep
currentEpisode = nextEp // set current ep to next ep
episodeId = nextEp.id
MediaFragment.instance.updateWatchedState(nextEp) // TODO i don't like this
MediaFragment.instance.updateWatchedState(nextEp)
nextEpisode = selectNextEpisode()
}
@ -362,15 +403,14 @@ class PlayerActivity : AppCompatActivity() {
button_next_ep.animate()
.alpha(0.0f)
.setListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) {
super.onAnimationEnd(animation)
button_next_ep.visibility = View.GONE
}
})
override fun onAnimationEnd(animation: Animator?) {
super.onAnimationEnd(animation)
button_next_ep.visibility = View.GONE
}
})
}
inner class PlayerGestureListener : GestureDetector.SimpleOnGestureListener() {
/**
@ -386,22 +426,7 @@ class PlayerActivity : AppCompatActivity() {
*/
override fun onDoubleTap(e: MotionEvent?): Boolean {
val eventPosX = e?.x?.toInt() ?: 0
val eventPosY = e?.y?.toInt() ?: 0
val viewCenterX = video_view.measuredWidth / 2
val viewCenterY = video_view.measuredHeight / 2
// Show ripple effect (Jellyfin Android App) TODO replace this with a netflix player like animation?
video_view.foreground?.apply {
val left = if (eventPosX < viewCenterX) 0 else viewCenterX
val right = if (eventPosX < viewCenterX) viewCenterX else video_view.measuredWidth
setBounds(left, viewCenterY - viewCenterX / 2, right, viewCenterY + viewCenterX / 2)
setHotspot(eventPosX.toFloat(), eventPosY.toFloat())
state = intArrayOf(android.R.attr.state_enabled, android.R.attr.state_pressed)
video_view.postDelayed(100) {
state = IntArray(0)
}
}
// if the event position is on the left side rewind, if it's on the right forward
if (eventPosX < viewCenterX) {
@ -420,6 +445,10 @@ class PlayerActivity : AppCompatActivity() {
return true
}
override fun onLongPress(e: MotionEvent?) {
togglePausePlay()
}
}
}

View File

@ -10,24 +10,18 @@ import android.widget.FrameLayout
import kotlinx.android.synthetic.main.button_fast_forward.view.*
import org.mosad.teapod.R
class FastForwardButton(context: Context, attrs: AttributeSet): FrameLayout(context, attrs) {
class FastForwardButton(context: Context, attrs: AttributeSet?): FrameLayout(context, attrs) {
private val animationDuration: Long = 800
private val buttonAnimation: ObjectAnimator
private val labelAnimation: ObjectAnimator
var onAnimationEndCallback: (() -> Unit)? = null
init {
inflate(context, R.layout.button_fast_forward, this)
}
fun setOnButtonClickListener(func: FastForwardButton.() -> Unit) {
imageButton.setOnClickListener {
func()
runOnClickAnimation()
}
}
fun runOnClickAnimation() {
// run button animation
ObjectAnimator.ofFloat(imageButton, View.ROTATION, 0f, 50f).apply {
buttonAnimation = ObjectAnimator.ofFloat(imageButton, View.ROTATION, 0f, 50f).apply {
duration = animationDuration / 4
repeatCount = 1
repeatMode = ObjectAnimator.REVERSE
@ -36,29 +30,39 @@ class FastForwardButton(context: Context, attrs: AttributeSet): FrameLayout(cont
imageButton.isEnabled = false // disable button
imageButton.setBackgroundResource(R.drawable.ic_baseline_forward_24)
}
override fun onAnimationEnd(animation: Animator?) {
imageButton.isEnabled = true // enable button
}
})
start()
}
// run lbl animation
textView.visibility = View.VISIBLE
ObjectAnimator.ofFloat(textView, View.TRANSLATION_X, 35f).apply {
labelAnimation = ObjectAnimator.ofFloat(textView, View.TRANSLATION_X, 35f).apply {
duration = animationDuration
addListener(object : AnimatorListenerAdapter() {
// the label animation takes longer then the button animation, reset stuff in here
override fun onAnimationEnd(animation: Animator?) {
imageButton.isEnabled = true // enable button
imageButton.setBackgroundResource(R.drawable.ic_baseline_forward_10_24)
textView.visibility = View.GONE
textView.animate().translationX(0f)
onAnimationEndCallback?.invoke()
}
})
start()
}
}
fun setOnButtonClickListener(func: FastForwardButton.() -> Unit) {
imageButton.setOnClickListener {
func()
}
}
fun runOnClickAnimation() {
// run button animation
buttonAnimation.start()
// run lbl animation
textView.visibility = View.VISIBLE
labelAnimation.start()
}
}

View File

@ -13,21 +13,15 @@ import org.mosad.teapod.R
class RewindButton(context: Context, attrs: AttributeSet): FrameLayout(context, attrs) {
private val animationDuration: Long = 800
private val buttonAnimation: ObjectAnimator
private val labelAnimation: ObjectAnimator
var onAnimationEndCallback: (() -> Unit)? = null
init {
inflate(context, R.layout.button_rewind, this)
}
fun setOnButtonClickListener(func: RewindButton.() -> Unit) {
imageButton.setOnClickListener {
func()
runOnClickAnimation()
}
}
fun runOnClickAnimation() {
// run button animation
ObjectAnimator.ofFloat(imageButton, View.ROTATION, 0f, -50f).apply {
buttonAnimation = ObjectAnimator.ofFloat(imageButton, View.ROTATION, 0f, -50f).apply {
duration = animationDuration / 4
repeatCount = 1
repeatMode = ObjectAnimator.REVERSE
@ -36,16 +30,10 @@ class RewindButton(context: Context, attrs: AttributeSet): FrameLayout(context,
imageButton.isEnabled = false // disable button
imageButton.setBackgroundResource(R.drawable.ic_baseline_rewind_24)
}
override fun onAnimationEnd(animation: Animator?) {
imageButton.isEnabled = true // enable button
}
})
start()
}
// run lbl animation
textView.visibility = View.VISIBLE
ObjectAnimator.ofFloat(textView, View.TRANSLATION_X, -35f).apply {
labelAnimation = ObjectAnimator.ofFloat(textView, View.TRANSLATION_X, -35f).apply {
duration = animationDuration
addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) {
@ -54,11 +42,26 @@ class RewindButton(context: Context, attrs: AttributeSet): FrameLayout(context,
textView.visibility = View.GONE
textView.animate().translationX(0f)
onAnimationEndCallback?.invoke()
}
})
start()
}
}
fun setOnButtonClickListener(func: RewindButton.() -> Unit) {
imageButton.setOnClickListener {
func()
}
}
fun runOnClickAnimation() {
// run button animation
buttonAnimation.start()
// run lbl animation
textView.visibility = View.VISIBLE
labelAnimation.start()
}
}

View File

@ -2,10 +2,11 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/player_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
android:background="#000000"
android:keepScreenOn="true"
tools:context=".PlayerActivity">
<com.google.android.exoplayer2.ui.StyledPlayerView
@ -15,9 +16,9 @@
android:layout_gravity="center"
android:animateLayoutChanges="true"
android:foreground="@drawable/ripple_background"
app:controller_layout_id="@layout/player_controls"
app:fastforward_increment="10000"
app:rewind_increment="10000"
app:controller_layout_id="@layout/player_controls"/>
app:rewind_increment="10000" />
<com.google.android.material.progressindicator.ProgressIndicator
android:id="@+id/loading"
@ -28,6 +29,50 @@
app:indicatorColor="@color/exo_white"
tools:visibility="visible" />
<LinearLayout
android:id="@+id/exo_double_tap_indicator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="horizontal"
android:visibility="gone">
<Space
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
<org.mosad.teapod.ui.components.RewindButton
android:id="@+id/rwd_10_indicator"
android:layout_width="100dp"
android:layout_height="wrap_content" />
<Space
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
<Space
android:layout_width="60dp"
android:layout_height="1dp" />
<Space
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
<org.mosad.teapod.ui.components.FastForwardButton
android:id="@+id/ffwd_10_indicator"
android:layout_width="100dp"
android:layout_height="wrap_content" />
<Space
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
</LinearLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/button_next_ep"
android:layout_width="wrap_content"