mirror of
https://github.com/libre-tube/LibreTube.git
synced 2024-12-13 13:50:30 +05:30
basic playlist autoplay implementation
This commit is contained in:
parent
ad509e3b4e
commit
e534c966bf
@ -60,6 +60,7 @@ class PlaylistAdapter(
|
|||||||
holder.v.setOnClickListener {
|
holder.v.setOnClickListener {
|
||||||
var bundle = Bundle()
|
var bundle = Bundle()
|
||||||
bundle.putString("videoId", streamItem.url!!.replace("/watch?v=", ""))
|
bundle.putString("videoId", streamItem.url!!.replace("/watch?v=", ""))
|
||||||
|
bundle.putString("playlistId", playlistId)
|
||||||
var frag = PlayerFragment()
|
var frag = PlayerFragment()
|
||||||
frag.arguments = bundle
|
frag.arguments = bundle
|
||||||
val activity = holder.v.context as AppCompatActivity
|
val activity = holder.v.context as AppCompatActivity
|
||||||
|
@ -49,6 +49,7 @@ import com.github.libretube.dialogs.ShareDialog
|
|||||||
import com.github.libretube.hideKeyboard
|
import com.github.libretube.hideKeyboard
|
||||||
import com.github.libretube.obj.ChapterSegment
|
import com.github.libretube.obj.ChapterSegment
|
||||||
import com.github.libretube.obj.PipedStream
|
import com.github.libretube.obj.PipedStream
|
||||||
|
import com.github.libretube.obj.Playlist
|
||||||
import com.github.libretube.obj.Segment
|
import com.github.libretube.obj.Segment
|
||||||
import com.github.libretube.obj.Segments
|
import com.github.libretube.obj.Segments
|
||||||
import com.github.libretube.obj.SponsorBlockPrefs
|
import com.github.libretube.obj.SponsorBlockPrefs
|
||||||
@ -86,6 +87,9 @@ import com.google.android.material.button.MaterialButton
|
|||||||
import com.google.android.material.card.MaterialCardView
|
import com.google.android.material.card.MaterialCardView
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.squareup.picasso.Picasso
|
import com.squareup.picasso.Picasso
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import org.chromium.net.CronetEngine
|
import org.chromium.net.CronetEngine
|
||||||
import retrofit2.HttpException
|
import retrofit2.HttpException
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
@ -99,6 +103,7 @@ class PlayerFragment : Fragment() {
|
|||||||
|
|
||||||
private val TAG = "PlayerFragment"
|
private val TAG = "PlayerFragment"
|
||||||
private var videoId: String? = null
|
private var videoId: String? = null
|
||||||
|
private var playlistId: String? = null
|
||||||
private var sId: Int = 0
|
private var sId: Int = 0
|
||||||
private var eId: Int = 0
|
private var eId: Int = 0
|
||||||
private var paused = false
|
private var paused = false
|
||||||
@ -119,8 +124,10 @@ class PlayerFragment : Fragment() {
|
|||||||
private lateinit var motionLayout: MotionLayout
|
private lateinit var motionLayout: MotionLayout
|
||||||
private lateinit var exoPlayer: ExoPlayer
|
private lateinit var exoPlayer: ExoPlayer
|
||||||
private lateinit var segmentData: Segments
|
private lateinit var segmentData: Segments
|
||||||
private var relatedStreams: List<StreamItem>? = arrayListOf()
|
|
||||||
private var relatedStreamsEnabled = true
|
private var relatedStreamsEnabled = true
|
||||||
|
private var relatedStreams: List<StreamItem>? = arrayListOf()
|
||||||
|
private var nextStreamId: String? = null
|
||||||
|
private var playlistStreamIds: MutableList<String> = arrayListOf()
|
||||||
private var isPlayerLocked: Boolean = false
|
private var isPlayerLocked: Boolean = false
|
||||||
|
|
||||||
private lateinit var relDownloadVideo: LinearLayout
|
private lateinit var relDownloadVideo: LinearLayout
|
||||||
@ -138,6 +145,7 @@ class PlayerFragment : Fragment() {
|
|||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
arguments?.let {
|
arguments?.let {
|
||||||
videoId = it.getString("videoId")
|
videoId = it.getString("videoId")
|
||||||
|
playlistId = it.getString("playlistId")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,12 +445,13 @@ class PlayerFragment : Fragment() {
|
|||||||
uploader = response.uploader!!
|
uploader = response.uploader!!
|
||||||
thumbnailUrl = response.thumbnailUrl!!
|
thumbnailUrl = response.thumbnailUrl!!
|
||||||
|
|
||||||
// check whether related streams and autoplay are enabled
|
// save whether related streams and autoplay are enabled
|
||||||
autoplay = PreferenceHelper.getBoolean(requireContext(), "autoplay", false)
|
autoplay = PreferenceHelper.getBoolean(requireContext(), "autoplay", false)
|
||||||
relatedStreamsEnabled =
|
relatedStreamsEnabled =
|
||||||
PreferenceHelper.getBoolean(requireContext(), "related_streams_toggle", true)
|
PreferenceHelper.getBoolean(requireContext(), "related_streams_toggle", true)
|
||||||
// save related streams for autoplay
|
// save related streams for autoplay
|
||||||
relatedStreams = response.relatedStreams
|
relatedStreams = response.relatedStreams
|
||||||
|
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
createExoPlayer(view)
|
createExoPlayer(view)
|
||||||
if (response.chapters != null) initializeChapters(response.chapters)
|
if (response.chapters != null) initializeChapters(response.chapters)
|
||||||
@ -462,6 +471,61 @@ class PlayerFragment : Fragment() {
|
|||||||
fetchSponsorBlockSegments()
|
fetchSponsorBlockSegments()
|
||||||
// show comments if related streams disabled
|
// show comments if related streams disabled
|
||||||
if (!relatedStreamsEnabled) toggleComments()
|
if (!relatedStreamsEnabled) toggleComments()
|
||||||
|
// prepare for autoplay
|
||||||
|
initAutoPlay()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
run()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initAutoPlay() {
|
||||||
|
// save related streams for autoplay
|
||||||
|
if (autoplay) {
|
||||||
|
// save related streams for autoplay
|
||||||
|
if (playlistId != null) {
|
||||||
|
if (playlistStreamIds.isEmpty()) {
|
||||||
|
lateinit var playlist: Playlist
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
// fetch the playlists videos
|
||||||
|
playlist = RetrofitInstance.api.getPlaylist(playlistId!!)
|
||||||
|
playlist.relatedStreams?.forEach { video ->
|
||||||
|
playlistStreamIds += video.url?.replace("/watch?v=", "")!!
|
||||||
|
}
|
||||||
|
// if the playlists contain the video, then save the next video as next stream
|
||||||
|
if (playlistStreamIds.contains(videoId)) {
|
||||||
|
val index = playlistStreamIds.indexOf(videoId)
|
||||||
|
if (index + 1 <= playlistStreamIds.size) {
|
||||||
|
nextStreamId = playlistStreamIds[index + 1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (relatedStreams != null && relatedStreams!!.isNotEmpty()) {
|
||||||
|
// save next video from related streams for autoplay
|
||||||
|
nextStreamId = relatedStreams!![0].url!!.replace("/watch?v=", "")!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun playNextVideo() {
|
||||||
|
// save the id of the next stream as videoId and load the next video
|
||||||
|
videoId = nextStreamId
|
||||||
|
fetchJsonAndInitPlayer(view!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fetchNextPage() {
|
||||||
|
fun run() {
|
||||||
|
lifecycleScope.launchWhenCreated {
|
||||||
|
val response = try {
|
||||||
|
RetrofitInstance.api.getPlaylistNextPage(playlistId!!, nextPage!!)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
println(e)
|
||||||
|
Log.e(TAG, "IOException, you might not have internet connection")
|
||||||
|
return@launchWhenCreated
|
||||||
|
} catch (e: HttpException) {
|
||||||
|
Log.e(TAG, "HttpException, unexpected response," + e.response())
|
||||||
|
return@launchWhenCreated
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -599,14 +663,13 @@ class PlayerFragment : Fragment() {
|
|||||||
// check if video has ended, next video is available and autoplay is enabled.
|
// check if video has ended, next video is available and autoplay is enabled.
|
||||||
if (
|
if (
|
||||||
playbackState == Player.STATE_ENDED &&
|
playbackState == Player.STATE_ENDED &&
|
||||||
relatedStreams != null &&
|
nextStreamId != null &&
|
||||||
relatedStreams!!.isNotEmpty() &&
|
|
||||||
!transitioning &&
|
!transitioning &&
|
||||||
autoplay
|
autoplay
|
||||||
) {
|
) {
|
||||||
transitioning = true
|
transitioning = true
|
||||||
videoId = relatedStreams!![0].url!!.replace("/watch?v=", "")
|
// check whether autoplay is enabled
|
||||||
fetchJsonAndInitPlayer(view)
|
if (autoplay) playNextVideo()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playWhenReady && playbackState == Player.STATE_READY) {
|
if (playWhenReady && playbackState == Player.STATE_READY) {
|
||||||
|
Loading…
Reference in New Issue
Block a user