From 8faf1bde89686d2b219d10bb0b5ccf6f7908c2ce Mon Sep 17 00:00:00 2001 From: Bnyro Date: Sun, 20 Aug 2023 18:26:41 +0200 Subject: [PATCH] feat: infinite playing queue when auto-insert related streams enabled --- .../libretube/services/OnlinePlayerService.kt | 25 ++++++++----------- .../libretube/ui/fragments/PlayerFragment.kt | 21 ++++++---------- .../com/github/libretube/util/PlayingQueue.kt | 19 +++++++++++--- 3 files changed, 35 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt b/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt index 5ca2d456a..c24e02c20 100644 --- a/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt +++ b/app/src/main/java/com/github/libretube/services/OnlinePlayerService.kt @@ -169,7 +169,13 @@ class OnlinePlayerService : LifecycleService() { // clear the queue if it shouldn't be kept explicitly if (!keepQueue) PlayingQueue.clear() - if (PlayingQueue.isEmpty()) updateQueue() + if (PlayingQueue.isEmpty()) { + PlayingQueue.updateQueue(streams!!.toStreamItem(videoId), playlistId, channelId) + insertRelatedStreamsToQueue() + } + else if (PlayingQueue.isLast() && playlistId == null && channelId == null) { + insertRelatedStreamsToQueue() + } // save the current stream to the queue streams?.toStreamItem(videoId)?.let { @@ -347,19 +353,10 @@ class OnlinePlayerService : LifecycleService() { player?.checkForSegments(this, segments, sponsorBlockConfig) } - private fun updateQueue() { - if (playlistId != null) { - streams?.toStreamItem(videoId)?.let { - PlayingQueue.insertPlaylist(playlistId!!, it) - } - } else if (channelId != null) { - streams?.toStreamItem(videoId)?.let { - PlayingQueue.insertChannel(channelId!!, it) - } - } else { - streams?.relatedStreams?.toTypedArray()?.let { - if (PlayerHelper.autoInsertRelatedVideos) PlayingQueue.add(*it) - } + private fun insertRelatedStreamsToQueue() { + if (!PlayerHelper.autoInsertRelatedVideos) return + streams?.relatedStreams?.toTypedArray()?.let { + PlayingQueue.add(*it, skipExisting = true) } } diff --git a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt index c42a071ce..b1b75396a 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt @@ -711,22 +711,17 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions { return@launch } - if (PlayingQueue.isEmpty()) { - lifecycleScope.launch(Dispatchers.IO) { - if (playlistId != null) { - PlayingQueue.insertPlaylist(playlistId!!, streams.toStreamItem(videoId)) - } else if (channelId != null) { - PlayingQueue.insertChannel(channelId!!, streams.toStreamItem(videoId)) - } else { - PlayingQueue.updateCurrent(streams.toStreamItem(videoId)) - if (PlayerHelper.autoInsertRelatedVideos) { - PlayingQueue.add(*streams.relatedStreams.toTypedArray()) - } - } - } + val isFirstVideo = PlayingQueue.isEmpty() + if (isFirstVideo) { + PlayingQueue.updateQueue(streams.toStreamItem(videoId), playlistId, channelId) } else { PlayingQueue.updateCurrent(streams.toStreamItem(videoId)) } + val isLastVideo = !isFirstVideo && PlayingQueue.isLast() + val isAutoQueue = playlistId == null && channelId == null + if (PlayerHelper.autoInsertRelatedVideos && (isFirstVideo || isLastVideo) && isAutoQueue) { + PlayingQueue.add(*streams.relatedStreams.toTypedArray(), skipExisting = true) + } if (PreferenceHelper.getBoolean(PreferenceKeys.AUTO_FULLSCREEN_SHORTS, false)) { val videoStream = streams.videoStreams.firstOrNull() diff --git a/app/src/main/java/com/github/libretube/util/PlayingQueue.kt b/app/src/main/java/com/github/libretube/util/PlayingQueue.kt index 5088a4841..42a1707d4 100644 --- a/app/src/main/java/com/github/libretube/util/PlayingQueue.kt +++ b/app/src/main/java/com/github/libretube/util/PlayingQueue.kt @@ -24,9 +24,14 @@ object PlayingQueue { fun clear() = queue.clear() - fun add(vararg streamItem: StreamItem) { + /** + * @param skipExisting Whether to skip the [streamItem] if it's already part of the queue + */ + fun add(vararg streamItem: StreamItem, skipExisting: Boolean = false) { for (stream in streamItem) { - if (currentStream?.url?.toID() == stream.url?.toID() || stream.title.isNullOrBlank()) continue + if (skipExisting && contains(stream)) continue + if (currentStream?.url?.toID() == stream.url?.toID() || + stream.title.isNullOrBlank()) continue // remove if already present queue.remove(stream) queue.add(stream) @@ -68,6 +73,8 @@ object PlayingQueue { fun size() = queue.size + fun isLast() = currentIndex() == size() - 1 + fun currentIndex(): Int = queue.indexOfFirst { it.url?.toID() == currentStream?.url?.toID() }.takeIf { it >= 0 } ?: 0 @@ -159,7 +166,7 @@ object PlayingQueue { } } - fun insertChannel(channelId: String, newCurrentStream: StreamItem) { + private fun insertChannel(channelId: String, newCurrentStream: StreamItem) { scope.launch(Dispatchers.IO) { runCatching { val channel = RetrofitInstance.api.getChannel(channelId) @@ -179,6 +186,12 @@ object PlayingQueue { } } + fun updateQueue(streamItem: StreamItem, playlistId: String?, channelId: String?) { + if (playlistId != null) insertPlaylist(playlistId, streamItem) + else if (channelId != null) insertChannel(channelId, streamItem) + else updateCurrent(streamItem) + } + fun onQueueItemSelected(index: Int) { try { val streamItem = queue[index]