forked from recloudstream/cloudstream
gestures controls for player
This commit is contained in:
parent
3ef1c28fbb
commit
c328a315b9
2 changed files with 346 additions and 8 deletions
|
@ -2,11 +2,13 @@ package com.lagradost.cloudstream3.ui.player
|
||||||
|
|
||||||
import android.animation.Animator
|
import android.animation.Animator
|
||||||
import android.animation.AnimatorListenerAdapter
|
import android.animation.AnimatorListenerAdapter
|
||||||
|
import android.animation.ObjectAnimator
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context.AUDIO_SERVICE
|
import android.content.Context.AUDIO_SERVICE
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.content.pm.ActivityInfo
|
import android.content.pm.ActivityInfo
|
||||||
|
import android.content.res.Resources
|
||||||
import android.database.ContentObserver
|
import android.database.ContentObserver
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
|
@ -14,13 +16,13 @@ import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
|
import android.os.SystemClock
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.View.*
|
import android.view.View.*
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.animation.AlphaAnimation
|
import android.view.animation.*
|
||||||
import android.view.animation.Animation
|
|
||||||
import android.view.animation.AnimationUtils
|
|
||||||
import android.widget.ProgressBar
|
import android.widget.ProgressBar
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import android.widget.Toast.LENGTH_LONG
|
import android.widget.Toast.LENGTH_LONG
|
||||||
|
@ -28,6 +30,9 @@ import androidx.core.content.ContextCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
|
import androidx.transition.Fade
|
||||||
|
import androidx.transition.Transition
|
||||||
|
import androidx.transition.TransitionManager
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||||
import com.fasterxml.jackson.databind.json.JsonMapper
|
import com.fasterxml.jackson.databind.json.JsonMapper
|
||||||
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
||||||
|
@ -41,6 +46,7 @@ import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory
|
||||||
import com.google.android.exoplayer2.util.MimeTypes
|
import com.google.android.exoplayer2.util.MimeTypes
|
||||||
import com.lagradost.cloudstream3.LoadResponse
|
import com.lagradost.cloudstream3.LoadResponse
|
||||||
import com.lagradost.cloudstream3.R
|
import com.lagradost.cloudstream3.R
|
||||||
|
import com.lagradost.cloudstream3.UIHelper.toPx
|
||||||
import com.lagradost.cloudstream3.USER_AGENT
|
import com.lagradost.cloudstream3.USER_AGENT
|
||||||
import com.lagradost.cloudstream3.mvvm.Resource
|
import com.lagradost.cloudstream3.mvvm.Resource
|
||||||
import com.lagradost.cloudstream3.mvvm.observe
|
import com.lagradost.cloudstream3.mvvm.observe
|
||||||
|
@ -50,11 +56,14 @@ import com.lagradost.cloudstream3.utils.DataStore.getKey
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import kotlinx.android.synthetic.main.fragment_player.*
|
import kotlinx.android.synthetic.main.fragment_player.*
|
||||||
import kotlinx.android.synthetic.main.player_custom_layout.*
|
import kotlinx.android.synthetic.main.player_custom_layout.*
|
||||||
|
import kotlinx.coroutines.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.net.ssl.HttpsURLConnection
|
import javax.net.ssl.HttpsURLConnection
|
||||||
import javax.net.ssl.SSLContext
|
import javax.net.ssl.SSLContext
|
||||||
import javax.net.ssl.SSLSession
|
import javax.net.ssl.SSLSession
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
|
import kotlin.math.abs
|
||||||
|
import kotlin.math.ceil
|
||||||
|
|
||||||
|
|
||||||
//http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4
|
//http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4
|
||||||
|
@ -99,15 +108,300 @@ class PlayerFragment : Fragment() {
|
||||||
|
|
||||||
private var isFullscreen = false
|
private var isFullscreen = false
|
||||||
private var isPlayerPlaying = true
|
private var isPlayerPlaying = true
|
||||||
|
private var doubleTapEnabled = false
|
||||||
private lateinit var viewModel: ResultViewModel
|
private lateinit var viewModel: ResultViewModel
|
||||||
private lateinit var playerData: PlayerData
|
private lateinit var playerData: PlayerData
|
||||||
private var isLoading = true
|
private var isLoading = true
|
||||||
|
private var isShowing = true
|
||||||
private lateinit var exoPlayer: SimpleExoPlayer
|
private lateinit var exoPlayer: SimpleExoPlayer
|
||||||
|
|
||||||
|
private var width = Resources.getSystem().displayMetrics.heightPixels
|
||||||
|
private var height = Resources.getSystem().displayMetrics.widthPixels
|
||||||
|
|
||||||
private var isLocked = false
|
private var isLocked = false
|
||||||
|
|
||||||
private lateinit var settingsManager: SharedPreferences
|
private lateinit var settingsManager: SharedPreferences
|
||||||
|
|
||||||
|
abstract class DoubleClickListener(private val ctx: PlayerFragment) : OnTouchListener {
|
||||||
|
// The time in which the second tap should be done in order to qualify as
|
||||||
|
// a double click
|
||||||
|
|
||||||
|
private var doubleClickQualificationSpanInMillis: Long = 300L
|
||||||
|
private var singleClickQualificationSpanInMillis: Long = 300L
|
||||||
|
private var timestampLastClick: Long = 0
|
||||||
|
private var timestampLastSingleClick: Long = 0
|
||||||
|
private var clicksLeft = 0
|
||||||
|
private var clicksRight = 0
|
||||||
|
private var fingerLeftScreen = true
|
||||||
|
abstract fun onDoubleClickRight(clicks: Int)
|
||||||
|
abstract fun onDoubleClickLeft(clicks: Int)
|
||||||
|
abstract fun onSingleClick()
|
||||||
|
abstract fun onMotionEvent(event: MotionEvent)
|
||||||
|
|
||||||
|
override fun onTouch(v: View, event: MotionEvent): Boolean {
|
||||||
|
onMotionEvent(event)
|
||||||
|
if (event.action == MotionEvent.ACTION_UP) {
|
||||||
|
fingerLeftScreen = true
|
||||||
|
}
|
||||||
|
if (event.action == MotionEvent.ACTION_DOWN) {
|
||||||
|
fingerLeftScreen = false
|
||||||
|
|
||||||
|
if ((SystemClock.elapsedRealtime() - timestampLastClick) < doubleClickQualificationSpanInMillis) {
|
||||||
|
if (event.rawX >= ctx.width / 2) {
|
||||||
|
clicksRight++
|
||||||
|
if (!ctx.isLocked && ctx.doubleTapEnabled) onDoubleClickRight(clicksRight)
|
||||||
|
if (!ctx.isShowing) onSingleClick()
|
||||||
|
} else {
|
||||||
|
clicksLeft++
|
||||||
|
if (!ctx.isLocked && ctx.doubleTapEnabled) onDoubleClickLeft(clicksLeft)
|
||||||
|
if (!ctx.isShowing) onSingleClick()
|
||||||
|
}
|
||||||
|
} else if (clicksLeft == 0 && clicksRight == 0 && fingerLeftScreen) {
|
||||||
|
// onSingleClick()
|
||||||
|
// timestampLastSingleClick = SystemClock.elapsedRealtime()
|
||||||
|
} else {
|
||||||
|
clicksLeft = 0
|
||||||
|
clicksRight = 0
|
||||||
|
val job = Job()
|
||||||
|
val uiScope = CoroutineScope(Dispatchers.Main + job)
|
||||||
|
|
||||||
|
fun check() {
|
||||||
|
if ((SystemClock.elapsedRealtime() - timestampLastSingleClick) > singleClickQualificationSpanInMillis && (SystemClock.elapsedRealtime() - timestampLastClick) > doubleClickQualificationSpanInMillis) {
|
||||||
|
timestampLastSingleClick = SystemClock.elapsedRealtime()
|
||||||
|
onSingleClick()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.isShowing && !ctx.isLocked && ctx.doubleTapEnabled) {
|
||||||
|
uiScope.launch {
|
||||||
|
delay(doubleClickQualificationSpanInMillis)
|
||||||
|
check()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
check()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
timestampLastClick = SystemClock.elapsedRealtime()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onClickChange() {
|
||||||
|
isShowing = !isShowing
|
||||||
|
|
||||||
|
click_overlay?.visibility = if (isShowing) GONE else VISIBLE
|
||||||
|
|
||||||
|
val titleMove = if (isShowing) 0f else -50.toPx.toFloat()
|
||||||
|
ObjectAnimator.ofFloat(video_title, "translationY", titleMove).apply {
|
||||||
|
duration = 200
|
||||||
|
start()
|
||||||
|
}
|
||||||
|
|
||||||
|
val playerBarMove = if (isShowing) 0f else 50.toPx.toFloat()
|
||||||
|
ObjectAnimator.ofFloat(bottom_player_bar, "translationY", playerBarMove).apply {
|
||||||
|
duration = 200
|
||||||
|
start()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val fadeTo = if (isShowing) 1f else 0f
|
||||||
|
val fadeAnimation = AlphaAnimation(1f - fadeTo, fadeTo)
|
||||||
|
|
||||||
|
fadeAnimation.duration = 100
|
||||||
|
fadeAnimation.fillAfter = true
|
||||||
|
|
||||||
|
if (!isLocked) {
|
||||||
|
shadow_overlay?.startAnimation(fadeAnimation)
|
||||||
|
}
|
||||||
|
video_holder?.startAnimation(fadeAnimation)
|
||||||
|
//video_lock_holder?.startAnimation(fadeAnimation)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun forceLetters(inp: Int, letters: Int = 2): String {
|
||||||
|
val added: Int = letters - inp.toString().length
|
||||||
|
return if (added > 0) {
|
||||||
|
"0".repeat(added) + inp.toString()
|
||||||
|
} else {
|
||||||
|
inp.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun convertTimeToString(time: Double): String {
|
||||||
|
val sec = time.toInt()
|
||||||
|
val rsec = sec % 60
|
||||||
|
val min = ceil((sec - rsec) / 60.0).toInt()
|
||||||
|
val rmin = min % 60
|
||||||
|
val h = ceil((min - rmin) / 60.0).toInt()
|
||||||
|
//int rh = h;// h % 24;
|
||||||
|
return (if (h > 0) forceLetters(h) + ":" else "") + (if (rmin >= 0 || h >= 0) forceLetters(rmin) + ":" else "") + forceLetters(
|
||||||
|
rsec
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun skipOP() {
|
||||||
|
seekTime(85000L)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var skipTime = 0L
|
||||||
|
private var prevDiffX = 0.0
|
||||||
|
private var preventHorizontalSwipe = false
|
||||||
|
private var hasPassedVerticalSwipeThreshold = false
|
||||||
|
private var hasPassedSkipLimit = false
|
||||||
|
private val swipeEnabled = true //<settingsManager!!.getBoolean("swipe_enabled", true)
|
||||||
|
private val swipeVerticalEnabled = true//settingsManager.getBoolean("swipe_vertical_enabled", true)
|
||||||
|
private var isMovingStartTime = 0L
|
||||||
|
private var currentX = 0F
|
||||||
|
private var currentY = 0F
|
||||||
|
private var cachedVolume = 0f
|
||||||
|
|
||||||
|
fun handleMotionEvent(motionEvent: MotionEvent) {
|
||||||
|
// TIME_UNSET == -9223372036854775807L
|
||||||
|
// No swiping on unloaded
|
||||||
|
// https://exoplayer.dev/doc/reference/constant-values.html
|
||||||
|
if (isLocked || exoPlayer.duration == -9223372036854775807L || (!swipeEnabled && !swipeVerticalEnabled)) return
|
||||||
|
val audioManager = activity?.getSystemService(AUDIO_SERVICE) as? AudioManager
|
||||||
|
|
||||||
|
when (motionEvent.action) {
|
||||||
|
MotionEvent.ACTION_DOWN -> {
|
||||||
|
currentX = motionEvent.rawX
|
||||||
|
currentY = motionEvent.rawY
|
||||||
|
//println("DOWN: " + currentX)
|
||||||
|
isMovingStartTime = exoPlayer.currentPosition
|
||||||
|
}
|
||||||
|
MotionEvent.ACTION_MOVE -> {
|
||||||
|
if (swipeVerticalEnabled) {
|
||||||
|
val distanceMultiplierY = 2F
|
||||||
|
val distanceY = (motionEvent.rawY - currentY) * distanceMultiplierY
|
||||||
|
val diffY = distanceY * 2.0 / height
|
||||||
|
|
||||||
|
// Forces 'smooth' moving preventing a bug where you
|
||||||
|
// can make it think it moved half a screen in a frame
|
||||||
|
|
||||||
|
if (abs(diffY) >= 0.2 && !hasPassedSkipLimit) {
|
||||||
|
hasPassedVerticalSwipeThreshold = true
|
||||||
|
preventHorizontalSwipe = true
|
||||||
|
}
|
||||||
|
if (hasPassedVerticalSwipeThreshold) {
|
||||||
|
if (currentX > width * 0.5) {
|
||||||
|
if (audioManager != null && progressBarLeftHolder != null) {
|
||||||
|
val currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
|
||||||
|
val maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
|
||||||
|
|
||||||
|
if (progressBarLeftHolder.alpha <= 0f) {
|
||||||
|
cachedVolume = currentVolume.toFloat() / maxVolume.toFloat()
|
||||||
|
}
|
||||||
|
|
||||||
|
progressBarLeftHolder?.alpha = 1f
|
||||||
|
val vol = minOf(1f,
|
||||||
|
cachedVolume - diffY.toFloat() * 0.5f) // 0.05f *if (diffY > 0) 1 else -1
|
||||||
|
cachedVolume = vol
|
||||||
|
//progressBarRight?.progress = ((1f - alpha) * 100).toInt()
|
||||||
|
|
||||||
|
progressBarLeft?.max = 100 * 100
|
||||||
|
progressBarLeft?.progress = ((vol) * 100 * 100).toInt()
|
||||||
|
|
||||||
|
if (audioManager.isVolumeFixed) {
|
||||||
|
// Lmao might earrape, we'll see in bug reports
|
||||||
|
exoPlayer.volume = minOf(1f, maxOf(vol, 0f))
|
||||||
|
} else {
|
||||||
|
// audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, vol*, 0)
|
||||||
|
val desiredVol = (vol * maxVolume).toInt()
|
||||||
|
if (desiredVol != currentVolume) {
|
||||||
|
val newVolumeAdjusted =
|
||||||
|
if (desiredVol < currentVolume) AudioManager.ADJUST_LOWER else AudioManager.ADJUST_RAISE
|
||||||
|
|
||||||
|
audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, newVolumeAdjusted, 0)
|
||||||
|
}
|
||||||
|
//audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, newVolume, 0)
|
||||||
|
}
|
||||||
|
currentY = motionEvent.rawY
|
||||||
|
}
|
||||||
|
} else if (progressBarRightHolder != null) {
|
||||||
|
progressBarRightHolder?.alpha = 1f
|
||||||
|
val alpha = minOf(0.95f,
|
||||||
|
brightness_overlay.alpha + diffY.toFloat() * 0.5f) // 0.05f *if (diffY > 0) 1 else -1
|
||||||
|
brightness_overlay?.alpha = alpha
|
||||||
|
//progressBarRight?.progress = ((1f - alpha) * 100).toInt()
|
||||||
|
|
||||||
|
progressBarRight?.max = 100 * 100
|
||||||
|
progressBarRight?.progress = ((1f - alpha) * 100 * 100).toInt()
|
||||||
|
/* val animation: ObjectAnimator = ObjectAnimator.ofInt(progressBarRight,
|
||||||
|
"progress",
|
||||||
|
progressBarRight.progress,
|
||||||
|
.toInt())
|
||||||
|
animation.duration = 100
|
||||||
|
animation.setAutoCancel(true)
|
||||||
|
animation.interpolator = DecelerateInterpolator()
|
||||||
|
animation.start()*/
|
||||||
|
|
||||||
|
currentY = motionEvent.rawY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (swipeEnabled) {
|
||||||
|
val distanceMultiplierX = 2F
|
||||||
|
val distanceX = (motionEvent.rawX - currentX) * distanceMultiplierX
|
||||||
|
val diffX = distanceX * 2.0 / width
|
||||||
|
if (abs(diffX - prevDiffX) > 0.5) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
prevDiffX = diffX
|
||||||
|
|
||||||
|
skipTime = ((exoPlayer.duration * (diffX * diffX) / 10) * (if (diffX < 0) -1 else 1)).toLong()
|
||||||
|
if (isMovingStartTime + skipTime < 0) {
|
||||||
|
skipTime = -isMovingStartTime
|
||||||
|
} else if (isMovingStartTime + skipTime > exoPlayer.duration) {
|
||||||
|
skipTime = exoPlayer.duration - isMovingStartTime
|
||||||
|
}
|
||||||
|
if ((abs(skipTime) > 3000 || hasPassedSkipLimit) && !preventHorizontalSwipe) {
|
||||||
|
hasPassedSkipLimit = true
|
||||||
|
val timeString =
|
||||||
|
"${convertTimeToString((isMovingStartTime + skipTime) / 1000.0)} [${(if (abs(skipTime) < 1000) "" else (if (skipTime > 0) "+" else "-"))}${
|
||||||
|
convertTimeToString(abs(skipTime / 1000.0))
|
||||||
|
}]"
|
||||||
|
timeText.alpha = 1f
|
||||||
|
timeText.text = timeString
|
||||||
|
} else {
|
||||||
|
timeText.alpha = 0f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MotionEvent.ACTION_UP -> {
|
||||||
|
val transition: Transition = Fade()
|
||||||
|
transition.duration = 1000
|
||||||
|
|
||||||
|
TransitionManager.beginDelayedTransition(player_holder, transition)
|
||||||
|
|
||||||
|
if (abs(skipTime) > 7000 && !preventHorizontalSwipe && swipeEnabled) {
|
||||||
|
exoPlayer.seekTo(maxOf(minOf(skipTime + isMovingStartTime, exoPlayer.duration), 0))
|
||||||
|
}
|
||||||
|
hasPassedSkipLimit = false
|
||||||
|
hasPassedVerticalSwipeThreshold = false
|
||||||
|
preventHorizontalSwipe = false
|
||||||
|
prevDiffX = 0.0
|
||||||
|
skipTime = 0
|
||||||
|
|
||||||
|
timeText.animate().alpha(0f).setDuration(200)
|
||||||
|
.setInterpolator(AccelerateInterpolator()).start()
|
||||||
|
progressBarRightHolder.animate().alpha(0f).setDuration(200)
|
||||||
|
.setInterpolator(AccelerateInterpolator()).start()
|
||||||
|
progressBarLeftHolder.animate().alpha(0f).setDuration(200)
|
||||||
|
.setInterpolator(AccelerateInterpolator()).start()
|
||||||
|
//val fadeAnimation = AlphaAnimation(1f, 0f)
|
||||||
|
//fadeAnimation.duration = 100
|
||||||
|
//fadeAnimation.fillAfter = true
|
||||||
|
//progressBarLeftHolder.startAnimation(fadeAnimation)
|
||||||
|
//progressBarRightHolder.startAnimation(fadeAnimation)
|
||||||
|
//timeText.startAnimation(fadeAnimation)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun seekTime(time: Long) {
|
private fun seekTime(time: Long) {
|
||||||
exoPlayer.seekTo(maxOf(minOf(exoPlayer.currentPosition + time, exoPlayer.duration), 0))
|
exoPlayer.seekTo(maxOf(minOf(exoPlayer.currentPosition + time, exoPlayer.duration), 0))
|
||||||
}
|
}
|
||||||
|
@ -188,6 +482,7 @@ class PlayerFragment : Fragment() {
|
||||||
skip_op.isClickable = isClick
|
skip_op.isClickable = isClick
|
||||||
resize_player.isClickable = isClick
|
resize_player.isClickable = isClick
|
||||||
exo_progress.isEnabled = isClick
|
exo_progress.isEnabled = isClick
|
||||||
|
//video_go_back_holder2.isEnabled = isClick
|
||||||
|
|
||||||
// Clickable doesn't seem to work on com.google.android.exoplayer2.ui.DefaultTimeBar
|
// Clickable doesn't seem to work on com.google.android.exoplayer2.ui.DefaultTimeBar
|
||||||
//exo_progress.visibility = if (isLocked) INVISIBLE else VISIBLE
|
//exo_progress.visibility = if (isLocked) INVISIBLE else VISIBLE
|
||||||
|
@ -273,7 +568,7 @@ class PlayerFragment : Fragment() {
|
||||||
val fastForwardTime = settingsManager.getInt("fast_forward_button_time", 10)
|
val fastForwardTime = settingsManager.getInt("fast_forward_button_time", 10)
|
||||||
exo_rew_text.text = fastForwardTime.toString()
|
exo_rew_text.text = fastForwardTime.toString()
|
||||||
exo_ffwd_text.text = fastForwardTime.toString()
|
exo_ffwd_text.text = fastForwardTime.toString()
|
||||||
exo_rew.setOnClickListener {
|
fun rewnd() {
|
||||||
val rotateLeft = AnimationUtils.loadAnimation(context, R.anim.rotate_left)
|
val rotateLeft = AnimationUtils.loadAnimation(context, R.anim.rotate_left)
|
||||||
exo_rew.startAnimation(rotateLeft)
|
exo_rew.startAnimation(rotateLeft)
|
||||||
|
|
||||||
|
@ -293,9 +588,13 @@ class PlayerFragment : Fragment() {
|
||||||
exo_rew_text.startAnimation(goLeft)
|
exo_rew_text.startAnimation(goLeft)
|
||||||
exo_rew_text.text = "-$fastForwardTime"
|
exo_rew_text.text = "-$fastForwardTime"
|
||||||
seekTime(fastForwardTime * -1000L)
|
seekTime(fastForwardTime * -1000L)
|
||||||
|
|
||||||
}
|
}
|
||||||
exo_ffwd.setOnClickListener {
|
|
||||||
|
exo_rew.setOnClickListener {
|
||||||
|
rewnd()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ffwrd() {
|
||||||
val rotateRight = AnimationUtils.loadAnimation(context, R.anim.rotate_right)
|
val rotateRight = AnimationUtils.loadAnimation(context, R.anim.rotate_right)
|
||||||
exo_ffwd.startAnimation(rotateRight)
|
exo_ffwd.startAnimation(rotateRight)
|
||||||
|
|
||||||
|
@ -317,6 +616,10 @@ class PlayerFragment : Fragment() {
|
||||||
seekTime(fastForwardTime * 1000L)
|
seekTime(fastForwardTime * 1000L)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exo_ffwd.setOnClickListener {
|
||||||
|
ffwrd()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
lock_player.setOnClickListener {
|
lock_player.setOnClickListener {
|
||||||
isLocked = !isLocked
|
isLocked = !isLocked
|
||||||
|
@ -336,9 +639,43 @@ class PlayerFragment : Fragment() {
|
||||||
playback_speed_btt.startAnimation(fadeAnimation)
|
playback_speed_btt.startAnimation(fadeAnimation)
|
||||||
sources_btt.startAnimation(fadeAnimation)
|
sources_btt.startAnimation(fadeAnimation)
|
||||||
skip_op.startAnimation(fadeAnimation)
|
skip_op.startAnimation(fadeAnimation)
|
||||||
|
video_go_back_holder2.startAnimation(fadeAnimation)
|
||||||
|
|
||||||
updateLock()
|
updateLock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Listener : DoubleClickListener(this) {
|
||||||
|
// Declaring a seekAnimation here will cause a bug
|
||||||
|
|
||||||
|
override fun onDoubleClickRight(clicks: Int) {
|
||||||
|
if (!isLocked) {
|
||||||
|
ffwrd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDoubleClickLeft(clicks: Int) {
|
||||||
|
if (!isLocked) {
|
||||||
|
rewnd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSingleClick() {
|
||||||
|
onClickChange()
|
||||||
|
// activity?.hideSystemUI()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMotionEvent(event: MotionEvent) {
|
||||||
|
handleMotionEvent(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
player_holder.setOnTouchListener(
|
||||||
|
Listener()
|
||||||
|
)
|
||||||
|
|
||||||
|
click_overlay?.setOnTouchListener(
|
||||||
|
Listener()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCurrentUrl(): ExtractorLink {
|
fun getCurrentUrl(): ExtractorLink {
|
||||||
|
|
|
@ -164,6 +164,7 @@
|
||||||
</androidx.cardview.widget.CardView>
|
</androidx.cardview.widget.CardView>
|
||||||
</LinearLayout>-->
|
</LinearLayout>-->
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
|
android:id="@+id/video_go_back_holder2"
|
||||||
android:layout_margin="5dp"
|
android:layout_margin="5dp"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
@ -686,7 +687,7 @@
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:layout_width="4dp"
|
android:layout_width="4dp"
|
||||||
android:layout_height="180dp"
|
android:layout_height="150dp"
|
||||||
android:id="@+id/progressBarLeft"
|
android:id="@+id/progressBarLeft"
|
||||||
android:indeterminate="false"
|
android:indeterminate="false"
|
||||||
style="@android:style/Widget.Material.ProgressBar.Horizontal"
|
style="@android:style/Widget.Material.ProgressBar.Horizontal"
|
||||||
|
@ -729,7 +730,7 @@
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:layout_width="4dp"
|
android:layout_width="4dp"
|
||||||
android:layout_height="180dp"
|
android:layout_height="150dp"
|
||||||
android:id="@+id/progressBarRight"
|
android:id="@+id/progressBarRight"
|
||||||
android:indeterminate="false"
|
android:indeterminate="false"
|
||||||
style="@android:style/Widget.Material.ProgressBar.Horizontal"
|
style="@android:style/Widget.Material.ProgressBar.Horizontal"
|
||||||
|
|
Loading…
Reference in a new issue