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;