mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-29 00:10:32 +05:30
fix: autoplay countdown continues although other video selected
This commit is contained in:
parent
9458b5597b
commit
40c885316d
@ -7,8 +7,10 @@ import android.os.Looper
|
||||
import android.view.KeyEvent
|
||||
import androidx.annotation.OptIn
|
||||
import androidx.core.app.ServiceCompat
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.core.os.postDelayed
|
||||
import androidx.media3.common.C
|
||||
import androidx.media3.common.MediaMetadata
|
||||
import androidx.media3.common.PlaybackException
|
||||
import androidx.media3.common.Player
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
@ -22,6 +24,7 @@ import androidx.media3.session.SessionCommand
|
||||
import androidx.media3.session.SessionResult
|
||||
import com.github.libretube.R
|
||||
import com.github.libretube.api.obj.Subtitle
|
||||
import com.github.libretube.constants.IntentData
|
||||
import com.github.libretube.enums.PlayerCommand
|
||||
import com.github.libretube.enums.PlayerEvent
|
||||
import com.github.libretube.extensions.parcelable
|
||||
@ -47,6 +50,8 @@ abstract class AbstractPlayerService : MediaLibraryService(), MediaLibrarySessio
|
||||
var trackSelector: DefaultTrackSelector? = null
|
||||
|
||||
lateinit var videoId: String
|
||||
private set
|
||||
|
||||
var isTransitioning = true
|
||||
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
@ -170,7 +175,7 @@ abstract class AbstractPlayerService : MediaLibraryService(), MediaLibrarySessio
|
||||
}
|
||||
|
||||
private fun navigateVideo(videoId: String) {
|
||||
this.videoId = videoId
|
||||
setVideoId(videoId)
|
||||
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
startPlayback()
|
||||
@ -185,6 +190,28 @@ abstract class AbstractPlayerService : MediaLibraryService(), MediaLibrarySessio
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the [videoId] to the new videoId and change the playlist metadata
|
||||
* to reflect that videoId change
|
||||
*/
|
||||
protected fun setVideoId(videoId: String) {
|
||||
this.videoId = videoId
|
||||
|
||||
updatePlaylistMetadata {
|
||||
setExtras(bundleOf(IntentData.videoId to videoId))
|
||||
}
|
||||
}
|
||||
|
||||
protected fun updatePlaylistMetadata(updateAction: MediaMetadata.Builder.() -> Unit) {
|
||||
handler.post {
|
||||
exoPlayer?.playlistMetadata = MediaMetadata.Builder()
|
||||
.apply(updateAction)
|
||||
// send a unique timestamp to notify that the metadata changed, even if playing the same video twice
|
||||
.setTrackNumber(System.currentTimeMillis().mod(Int.MAX_VALUE))
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handlePlayerAction(event: PlayerEvent) {
|
||||
if (PlayerHelper.handlePlayerAction(exoPlayer ?: return, event)) return
|
||||
|
||||
@ -303,7 +330,7 @@ abstract class AbstractPlayerService : MediaLibraryService(), MediaLibrarySessio
|
||||
*/
|
||||
abstract suspend fun startPlayback()
|
||||
|
||||
fun saveWatchPosition() {
|
||||
private fun saveWatchPosition() {
|
||||
if (isTransitioning || !PlayerHelper.watchPositionsVideo) return
|
||||
|
||||
exoPlayer?.let { PlayerHelper.saveWatchPosition(it, videoId) }
|
||||
|
@ -56,13 +56,14 @@ open class OfflinePlayerService : AbstractPlayerService() {
|
||||
shuffle = args.getBoolean(IntentData.shuffle, false)
|
||||
noInternetService = args.getBoolean(IntentData.noInternet, false)
|
||||
|
||||
videoId = if (shuffle) {
|
||||
val videoId = if (shuffle) {
|
||||
runBlocking(Dispatchers.IO) {
|
||||
Database.downloadDao().getRandomVideoIdByFileType(FileType.AUDIO)
|
||||
}
|
||||
} else {
|
||||
args.getString(IntentData.videoId)
|
||||
} ?: return
|
||||
setVideoId(videoId)
|
||||
|
||||
PlayingQueue.clear()
|
||||
|
||||
@ -131,9 +132,7 @@ open class OfflinePlayerService : AbstractPlayerService() {
|
||||
}
|
||||
|
||||
private fun playNextVideo(videoId: String) {
|
||||
saveWatchPosition()
|
||||
|
||||
this.videoId = videoId
|
||||
setVideoId(videoId)
|
||||
|
||||
scope.launch {
|
||||
startPlayback()
|
||||
|
@ -6,7 +6,6 @@ import androidx.core.net.toUri
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.common.MediaItem.SubtitleConfiguration
|
||||
import androidx.media3.common.MediaMetadata
|
||||
import androidx.media3.common.MimeTypes
|
||||
import androidx.media3.common.Player
|
||||
import androidx.media3.datasource.cronet.CronetDataSource
|
||||
@ -106,7 +105,7 @@ open class OnlinePlayerService : AbstractPlayerService() {
|
||||
}
|
||||
|
||||
// get the intent arguments
|
||||
videoId = playerData.videoId
|
||||
setVideoId(playerData.videoId)
|
||||
playlistId = playerData.playlistId
|
||||
channelId = playerData.channelId
|
||||
startTimestamp = playerData.timestamp
|
||||
@ -178,8 +177,6 @@ open class OnlinePlayerService : AbstractPlayerService() {
|
||||
* Plays the next video from the queue
|
||||
*/
|
||||
private fun playNextVideo(nextId: String? = null) {
|
||||
saveWatchPosition()
|
||||
|
||||
if (nextId == null) {
|
||||
if (PlayingQueue.repeatMode == Player.REPEAT_MODE_ONE) {
|
||||
exoPlayer?.seekTo(0)
|
||||
@ -192,7 +189,7 @@ open class OnlinePlayerService : AbstractPlayerService() {
|
||||
val nextVideo = nextId ?: PlayingQueue.getNext() ?: return
|
||||
|
||||
// play new video on background
|
||||
this.videoId = nextVideo
|
||||
setVideoId(nextVideo)
|
||||
this.streams = null
|
||||
this.sponsorBlockSegments = emptyList()
|
||||
|
||||
@ -214,9 +211,9 @@ open class OnlinePlayerService : AbstractPlayerService() {
|
||||
).segments
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
exoPlayer?.playlistMetadata = MediaMetadata.Builder()
|
||||
.setExtras(bundleOf(IntentData.segments to ArrayList(sponsorBlockSegments)))
|
||||
.build()
|
||||
updatePlaylistMetadata {
|
||||
setExtras(bundleOf(IntentData.segments to ArrayList(sponsorBlockSegments)))
|
||||
}
|
||||
|
||||
checkForSegments()
|
||||
}
|
||||
|
@ -305,16 +305,6 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
||||
override fun onMediaMetadataChanged(mediaMetadata: MediaMetadata) {
|
||||
super.onMediaMetadataChanged(mediaMetadata)
|
||||
|
||||
mediaMetadata.extras?.getString(IntentData.videoId)?.let {
|
||||
videoId = it
|
||||
// fix: if the fragment is recreated, play the current video, and not the initial one
|
||||
arguments?.run {
|
||||
val playerData =
|
||||
parcelable<PlayerData>(IntentData.playerData)!!.copy(videoId = videoId)
|
||||
putParcelable(IntentData.playerData, playerData)
|
||||
}
|
||||
}
|
||||
|
||||
val maybeStreams: Streams? = mediaMetadata.extras?.parcelable(IntentData.streams)
|
||||
maybeStreams?.let { streams ->
|
||||
this@PlayerFragment.streams = streams
|
||||
@ -327,6 +317,18 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
||||
override fun onPlaylistMetadataChanged(mediaMetadata: MediaMetadata) {
|
||||
super.onPlaylistMetadataChanged(mediaMetadata)
|
||||
|
||||
mediaMetadata.extras?.getString(IntentData.videoId)?.let {
|
||||
videoId = it
|
||||
_binding?.autoplayCountdown?.cancelAndHideCountdown()
|
||||
|
||||
// fix: if the fragment is recreated, play the current video, and not the initial one
|
||||
arguments?.run {
|
||||
val playerData =
|
||||
parcelable<PlayerData>(IntentData.playerData)!!.copy(videoId = videoId)
|
||||
putParcelable(IntentData.playerData, playerData)
|
||||
}
|
||||
}
|
||||
|
||||
val segments: List<Segment>? = mediaMetadata.extras?.parcelableList(IntentData.segments)
|
||||
viewModel.segments.postValue(segments.orEmpty())
|
||||
}
|
||||
|
@ -34,8 +34,7 @@ class AutoplayCountdownView(
|
||||
|
||||
init {
|
||||
binding.cancel.setOnClickListener {
|
||||
handler.removeCallbacksAndMessages(TIMER_RUNNABLE_TOKEN)
|
||||
hideSelf.invoke()
|
||||
cancelAndHideCountdown()
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,6 +77,11 @@ class AutoplayCountdownView(
|
||||
handler.postDelayed(1000, TIMER_RUNNABLE_TOKEN, this::updateCountdown)
|
||||
}
|
||||
|
||||
fun cancelAndHideCountdown() {
|
||||
handler.removeCallbacksAndMessages(TIMER_RUNNABLE_TOKEN)
|
||||
hideSelf.invoke()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val COUNTDOWN_SECONDS = 5
|
||||
private const val TIMER_RUNNABLE_TOKEN = "timer_runnable"
|
||||
|
Loading…
x
Reference in New Issue
Block a user