Add functionality

This commit is contained in:
Bnyro 2022-10-23 13:39:15 +02:00
parent afe25fc67a
commit 41162fafac
8 changed files with 95 additions and 63 deletions

View File

@ -0,0 +1,22 @@
package com.github.libretube.extensions
import com.github.libretube.api.obj.StreamItem
import com.github.libretube.api.obj.Streams
fun Streams?.toStreamItem(videoId: String): StreamItem {
if (this == null) return StreamItem()
return StreamItem(
url = videoId,
title = title,
thumbnail = thumbnailUrl,
uploaderName = uploader,
uploaderUrl = uploaderUrl,
uploaderAvatar = uploaderAvatar,
uploadedDate = uploadDate,
uploaded = null,
duration = duration,
views = views,
uploaderVerified = uploaderVerified,
shortDescription = description
)
}

View File

@ -25,6 +25,7 @@ import com.github.libretube.db.DatabaseHelper
import com.github.libretube.db.DatabaseHolder
import com.github.libretube.extensions.awaitQuery
import com.github.libretube.extensions.toID
import com.github.libretube.extensions.toStreamItem
import com.github.libretube.util.AutoPlayHelper
import com.github.libretube.util.NowPlayingNotification
import com.github.libretube.util.PlayerHelper
@ -146,7 +147,9 @@ class BackgroundMode : Service() {
}
private fun updateWatchPosition() {
player?.currentPosition?.let { DatabaseHelper.saveWatchPosition(videoId, it) }
player?.currentPosition?.let {
DatabaseHelper.saveWatchPosition(videoId, it)
}
handler.postDelayed(this::updateWatchPosition, 500)
}
@ -158,7 +161,7 @@ class BackgroundMode : Service() {
seekToPosition: Long = 0
) {
// append the video to the playing queue
PlayingQueue.add(videoId)
PlayingQueue.add(streams.toStreamItem(videoId))
CoroutineScope(Dispatchers.IO).launch {
try {
streams = RetrofitInstance.api.getStreams(videoId)
@ -166,6 +169,8 @@ class BackgroundMode : Service() {
return@launch
}
PlayingQueue.updateCurrent(streams.toStreamItem(videoId))
handler.post {
playAudio(seekToPosition)
}
@ -175,8 +180,6 @@ class BackgroundMode : Service() {
private fun playAudio(
seekToPosition: Long
) {
PlayingQueue.updateCurrent(videoId)
initializePlayer()
setMediaItem()
@ -280,7 +283,7 @@ class BackgroundMode : Service() {
if (!this::autoPlayHelper.isInitialized) autoPlayHelper = AutoPlayHelper(playlistId!!)
// search for the next videoId in the playlist
CoroutineScope(Dispatchers.IO).launch {
nextStreamId = autoPlayHelper.getNextVideoId(videoId, streams!!.relatedStreams!!)
nextStreamId = autoPlayHelper.getNextVideoId(videoId)
}
}

View File

@ -81,8 +81,6 @@ class HomeFragment : BaseFragment() {
} finally {
binding.homeRefresh.isRefreshing = false
}
// TODO() REMOVE TESTING
PlayingQueue.streams = response
runOnUiThread {
binding.progressBar.visibility = View.GONE

View File

@ -52,6 +52,7 @@ import com.github.libretube.extensions.formatShort
import com.github.libretube.extensions.hideKeyboard
import com.github.libretube.extensions.query
import com.github.libretube.extensions.toID
import com.github.libretube.extensions.toStreamItem
import com.github.libretube.models.PlayerViewModel
import com.github.libretube.models.interfaces.PlayerOptionsInterface
import com.github.libretube.services.BackgroundMode
@ -635,8 +636,6 @@ class PlayerFragment : BaseFragment() {
private fun playVideo() {
lifecycleScope.launchWhenCreated {
PlayingQueue.updateCurrent(videoId!!)
streams = try {
RetrofitInstance.api.getStreams(videoId!!)
} catch (e: IOException) {
@ -650,6 +649,12 @@ class PlayerFragment : BaseFragment() {
return@launchWhenCreated
}
PlayingQueue.updateCurrent(streams.toStreamItem(videoId!!))
if (PlayingQueue.size() <= 1) PlayingQueue.add(
*streams.relatedStreams.orEmpty().toTypedArray()
)
runOnUiThread {
// hide the button to skip SponsorBlock segments manually
binding.sbSkipBtn.visibility = View.GONE
@ -694,7 +699,7 @@ class PlayerFragment : BaseFragment() {
if (!this::autoPlayHelper.isInitialized) autoPlayHelper = AutoPlayHelper(playlistId)
// search for the next videoId in the playlist
lifecycleScope.launchWhenCreated {
nextStreamId = autoPlayHelper.getNextVideoId(videoId!!, streams.relatedStreams)
nextStreamId = autoPlayHelper.getNextVideoId(videoId!!)
}
}

View File

@ -27,7 +27,7 @@ class PlayingQueueSheet : BottomSheetDialogFragment() {
binding.optionsRecycler.layoutManager = LinearLayoutManager(context)
binding.optionsRecycler.adapter = PlayingQueueAdapter(
PlayingQueue.streams
PlayingQueue.getStreams()
)
}
}

View File

@ -3,8 +3,10 @@ package com.github.libretube.ui.sheets
import android.os.Bundle
import android.widget.Toast
import com.github.libretube.R
import com.github.libretube.api.RetrofitInstance
import com.github.libretube.constants.IntentData
import com.github.libretube.constants.ShareObjectType
import com.github.libretube.extensions.toStreamItem
import com.github.libretube.ui.dialogs.AddToPlaylistDialog
import com.github.libretube.ui.dialogs.DownloadDialog
import com.github.libretube.ui.dialogs.ShareDialog
@ -12,6 +14,9 @@ import com.github.libretube.ui.views.BottomSheet
import com.github.libretube.util.BackgroundHelper
import com.github.libretube.util.PlayingQueue
import com.github.libretube.util.PreferenceHelper
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
/**
* Dialog with different options for a selected video.
@ -79,10 +84,28 @@ class VideoOptionsBottomSheet(
shareDialog.show(parentFragmentManager, ShareDialog::class.java.name)
}
context?.getString(R.string.play_next) -> {
PlayingQueue.addAsNext(videoId)
CoroutineScope(Dispatchers.IO).launch {
try {
PlayingQueue.addAsNext(
RetrofitInstance.api.getStreams(videoId)
.toStreamItem(videoId)
)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
context?.getString(R.string.add_to_queue) -> {
PlayingQueue.add(videoId)
CoroutineScope(Dispatchers.IO).launch {
try {
PlayingQueue.add(
RetrofitInstance.api.getStreams(videoId)
.toStreamItem(videoId)
)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
}

View File

@ -16,13 +16,10 @@ class AutoPlayHelper(
* get the id of the next video to be played
*/
suspend fun getNextVideoId(
currentVideoId: String,
relatedStreams: List<com.github.libretube.api.obj.StreamItem>?
currentVideoId: String
): String? {
return if (playlistId == null) {
getNextTrendingVideoId(
relatedStreams
)
null
} else {
getNextPlaylistVideoId(
currentVideoId
@ -30,27 +27,6 @@ class AutoPlayHelper(
}
}
/**
* get the id of the next related video
*/
private fun getNextTrendingVideoId(
relatedStreams: List<com.github.libretube.api.obj.StreamItem>?
): String? {
// don't play a video if it got played before already
if (relatedStreams == null || relatedStreams.isEmpty()) return null
var index = 0
var nextStreamId: String? = null
while (nextStreamId == null || PlayingQueue.containsBeforeCurrent(nextStreamId)) {
nextStreamId = relatedStreams[index].url!!.toID()
if (index + 1 < relatedStreams.size) {
index += 1
} else {
break
}
}
return nextStreamId
}
/**
* get the videoId of the next video in a playlist
*/

View File

@ -1,58 +1,63 @@
package com.github.libretube.util
import com.github.libretube.api.obj.StreamItem
import com.github.libretube.extensions.toID
object PlayingQueue {
private val queue = mutableListOf<String>()
private var currentVideoId: String? = null
var streams: List<StreamItem> = listOf()
private val queue = mutableListOf<StreamItem>()
private var currentStream: StreamItem? = null
fun add(videoId: String) {
if (currentVideoId == videoId) return
if (queue.contains(videoId)) queue.remove(videoId)
queue.add(videoId)
fun add(vararg streamItem: StreamItem) {
streamItem.forEach {
if (currentStream != it) {
if (queue.contains(it)) queue.remove(it)
queue.add(it)
}
}
}
fun addAsNext(videoId: String) {
if (currentVideoId == videoId) return
if (queue.contains(videoId)) queue.remove(videoId)
fun addAsNext(streamItem: StreamItem) {
if (currentStream == streamItem) return
if (queue.contains(streamItem)) queue.remove(streamItem)
queue.add(
queue.indexOf(currentVideoId) + 1,
videoId
currentIndex() + 1,
streamItem
)
}
fun getNext(): String? {
return try {
queue[currentIndex() + 1]
queue[currentIndex() + 1].url?.toID()
} catch (e: Exception) {
null
}
}
fun getPrev(): String? {
val index = queue.indexOf(currentVideoId)
return if (index > 0) queue[index - 1] else null
val index = queue.indexOf(currentStream)
return if (index > 0) queue[index - 1].url?.toID() else null
}
fun hasPrev(): Boolean {
return queue.indexOf(currentVideoId) > 0
return queue.indexOf(currentStream) > 0
}
fun updateCurrent(videoId: String) {
currentVideoId = videoId
queue.add(videoId)
fun updateCurrent(streamItem: StreamItem) {
currentStream = streamItem
queue.add(streamItem)
}
fun isNotEmpty() = queue.isNotEmpty()
fun isEmpty() = queue.isEmpty()
fun clear() = queue.clear()
fun currentIndex() = queue.indexOf(currentVideoId)
fun size() = queue.size
fun contains(videoId: String) = queue.contains(videoId)
private fun currentIndex() = queue.indexOf(currentStream)
fun containsBeforeCurrent(videoId: String): Boolean {
return queue.contains(videoId) && queue.indexOf(videoId) < currentIndex()
}
fun contains(streamItem: StreamItem) = queue.contains(streamItem)
fun getStreams() = queue
}