diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt index 49ad5522cf726cd85a7091fc9eac779a26ec4041..10b49582930ed36ee23db2925bfd0bd4c822a1a2 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt @@ -468,8 +468,8 @@ class VideoDetailView : ConstraintLayout { nextVideo(); }; _player.onDatasourceError.subscribe(::onDataSourceError); - _player.onNext.subscribe { nextVideo(true) }; - _player.onPrevious.subscribe { previousVideo(true) }; + _player.onNext.subscribe { nextVideo(true, true) }; + _player.onPrevious.subscribe { prevVideo(true) }; _minimize_controls_play.setOnClickListener { handlePlay(); }; _minimize_controls_pause.setOnClickListener { handlePause(); }; @@ -547,7 +547,7 @@ class VideoDetailView : ConstraintLayout { MediaControlReceiver.onPlayReceived.subscribe(this) { handlePlay() }; MediaControlReceiver.onPauseReceived.subscribe(this) { handlePause() }; MediaControlReceiver.onNextReceived.subscribe(this) { nextVideo(true) }; - MediaControlReceiver.onPreviousReceived.subscribe(this) { previousVideo(true) }; + MediaControlReceiver.onPreviousReceived.subscribe(this) { prevVideo(true) }; MediaControlReceiver.onCloseReceived.subscribe(this) { Logger.i(TAG, "MediaControlReceiver.onCloseReceived") onClose.emit() @@ -1542,63 +1542,26 @@ class VideoDetailView : ConstraintLayout { _slideUpOverlay = _overlay_quality_selector; } - private fun getPreviousVideo(withoutRemoval: Boolean, forceLoop: Boolean = false): IPlatformVideo? { - if (!StatePlayer.instance.hasQueue) { - if (forceLoop) { - return StatePlayer.instance.currentVideo - } else { - return null - } - } - - val shouldNotRemove = _player.duration < 100 || (_player.position.toFloat() / _player.duration) < 0.9 - var previous = StatePlayer.instance.prevQueueItem(withoutRemoval || shouldNotRemove); - if(previous == null && forceLoop) - previous = StatePlayer.instance.getQueue().last(); - return previous; - } - private fun getNextVideo(withoutRemoval: Boolean, forceLoop: Boolean = false): IPlatformVideo? { - if (!StatePlayer.instance.hasQueue) { - if (forceLoop) { - return StatePlayer.instance.currentVideo - } else { - return null - } - } - - val shouldNotRemove = _player.duration < 100 || (_player.position.toFloat() / _player.duration) < 0.9 - var next = StatePlayer.instance.nextQueueItem(withoutRemoval || shouldNotRemove); - if(next == null && forceLoop) - next = StatePlayer.instance.restartQueue(); - return next; - } - - fun previousVideo(forceLoop: Boolean = false): Boolean { - Logger.i(TAG, "previousVideo") - - val previous = getPreviousVideo(false, forceLoop); - if(previous != null) { - setVideoOverview(previous); - return true; - } else { - StatePlayer.instance.setCurrentlyPlaying(null); + fun prevVideo(withoutRemoval: Boolean = false) { + Logger.i(TAG, "prevVideo") + val next = StatePlayer.instance.prevQueueItem(withoutRemoval || _player.duration < 100 || (_player.position.toFloat() / _player.duration) < 0.9); + if(next != null) { + setVideoOverview(next); } - - return false; } - fun nextVideo(forceLoop: Boolean = false): Boolean { + fun nextVideo(forceLoop: Boolean = false, withoutRemoval: Boolean = false): Boolean { Logger.i(TAG, "nextVideo") - - val next = getNextVideo(false, forceLoop); + var next = StatePlayer.instance.nextQueueItem(withoutRemoval || _player.duration < 100 || (_player.position.toFloat() / _player.duration) < 0.9); + if(next == null && forceLoop) + next = StatePlayer.instance.restartQueue(); if(next != null) { setVideoOverview(next); return true; - } else { - StatePlayer.instance.setCurrentlyPlaying(null); } - + else + StatePlayer.instance.setCurrentlyPlaying(null); return false; } diff --git a/app/src/main/java/com/futo/platformplayer/states/StatePlayer.kt b/app/src/main/java/com/futo/platformplayer/states/StatePlayer.kt index 84dc31504bdd43a6995635a8ad160db92a4e56c3..717bf4df26c8aca80eaa9aa472a54d8aeeefdcda 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StatePlayer.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StatePlayer.kt @@ -373,7 +373,28 @@ class StatePlayer { return null; } - fun getNextQueueItem() : IPlatformVideo? { + fun getPrevQueueItem(forceLoop: Boolean = false) : IPlatformVideo? { + synchronized(_queue) { + val shuffledQueue = _queueShuffled; + val queue = if (queueShuffle && shuffledQueue != null) { + shuffledQueue; + } else { + _queue; + } + + //Init Behavior + if(_queuePosition == -1 && queue.isNotEmpty()) + return queue[0]; + //Standard Behavior + if(_queuePosition - 1 > 0) + return queue[_queuePosition - 1]; + //Repeat Behavior (End of queue) + if(_queuePosition - 1 < 0 && queue.isNotEmpty() && (forceLoop || queueRepeat)) + return queue[_queue.size - 1]; + } + return null; + } + fun getNextQueueItem(forceLoop: Boolean = false) : IPlatformVideo? { if(loopVideo) return currentVideo; synchronized(_queue) { @@ -391,7 +412,7 @@ class StatePlayer { if(_queuePosition + 1 < queue.size) return queue[_queuePosition + 1]; //Repeat Behavior (End of queue) - if(_queuePosition + 1 == queue.size && queue.isNotEmpty() && queueRepeat) + if(_queuePosition + 1 == queue.size && queue.isNotEmpty() && (forceLoop || queueRepeat)) return queue[0]; } return null; diff --git a/app/src/main/java/com/futo/platformplayer/views/video/FutoVideoPlayer.kt b/app/src/main/java/com/futo/platformplayer/views/video/FutoVideoPlayer.kt index 64533459bdedd1d45a681851437d3ce19bfde014..f724f637bd962d374232887bb68b6a684bb4ef4f 100644 --- a/app/src/main/java/com/futo/platformplayer/views/video/FutoVideoPlayer.kt +++ b/app/src/main/java/com/futo/platformplayer/views/video/FutoVideoPlayer.kt @@ -35,7 +35,10 @@ import com.google.android.exoplayer2.ui.PlayerControlView import com.google.android.exoplayer2.ui.StyledPlayerView import com.google.android.exoplayer2.ui.TimeBar import com.google.android.exoplayer2.video.VideoSize +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import java.util.concurrent.Executors import java.util.concurrent.TimeUnit @@ -300,6 +303,17 @@ class FutoVideoPlayer : FutoVideoPlayerBase { } } + StatePlayer.instance.onQueueChanged.subscribe(this) { + CoroutineScope(Dispatchers.Main).launch(Dispatchers.Main) { + updateNextPrevious(); + } + } + StatePlayer.instance.onVideoChanging.subscribe(this) { + CoroutineScope(Dispatchers.Main).launch(Dispatchers.Main) { + updateNextPrevious(); + } + } + updateLoopVideoUI(); if(!isInEditMode) { @@ -307,10 +321,12 @@ class FutoVideoPlayer : FutoVideoPlayerBase { } } - /*fun updateNextPrevious(hasNext: Boolean, hasPrevious: Boolean) { - _buttonNext.visibility = if (hasNext) View.VISIBLE else View.GONE - _buttonPrevious.visibility = if (hasPrevious) View.VISIBLE else View.GONE - }*/ + fun updateNextPrevious() { + val vidPrev = StatePlayer.instance.getPrevQueueItem(true); + val vidNext = StatePlayer.instance.getNextQueueItem(true); + _buttonNext.visibility = if (vidNext != null) View.VISIBLE else View.GONE + _buttonPrevious.visibility = if (vidPrev != null) View.VISIBLE else View.GONE + } private val _currentChapterUpdateInterval: Long = 1000L / Settings.instance.playback.getChapterUpdateFrames(); private var _currentChapterUpdateLastPos = 0L;