Skip to content

Commit 4f2d8fa

Browse files
try fix: video track are disabled unexpectedly under certain conditions
1 parent 710a4c5 commit 4f2d8fa

1 file changed

Lines changed: 6 additions & 85 deletions

File tree

android/src/main/kotlin/project/pipepipe/app/service/PlaybackService.kt

Lines changed: 6 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import project.pipepipe.app.platform.getPlaybackStartPosition
2929
import project.pipepipe.app.platform.toMedia3MediaItem
3030
import project.pipepipe.app.platform.toPlatformMediaItem
3131
import project.pipepipe.app.platform.uuid
32+
import project.pipepipe.app.uistate.VideoDetailPageState
3233
import project.pipepipe.shared.infoitem.StreamInfo
3334
import project.pipepipe.shared.job.SupportedJobType
3435
import java.util.concurrent.ExecutorService
@@ -589,6 +590,11 @@ class PlaybackService : MediaLibraryService() {
589590

590591
private fun applyPlaybackMode(mode: PlaybackMode) {
591592
val disableVideo = (mode == PlaybackMode.AUDIO_ONLY)
593+
if (disableVideo && SharedContext.sharedVideoDetailViewModel.uiState.value.pageState == VideoDetailPageState.FULLSCREEN_PLAYER) {
594+
// for unknown reason, sometimes switching from detail page -> fullscreen will cause video track disabled but playback mode still video_audio
595+
// hopefully this check should prevent it.
596+
return
597+
}
592598
val params = player.trackSelectionParameters
593599
.buildUpon()
594600
.setTrackTypeDisabled(C.TRACK_TYPE_VIDEO, disableVideo)
@@ -611,43 +617,6 @@ class PlaybackService : MediaLibraryService() {
611617
)
612618
}
613619

614-
private fun refreshStreamAndRetry() {
615-
val currentIndex = player.currentMediaItemIndex
616-
val savedPosition = player.currentPosition
617-
serviceScope.launch {
618-
try {
619-
// Get service ID from current media item
620-
val currentItem = player.currentMediaItem ?: return@launch
621-
val serviceId = currentItem.mediaMetadata.extras?.getInt("KEY_SERVICE_ID")
622-
val uuid = currentItem.mediaMetadata.extras?.getString("KEY_UUID")
623-
624-
// Fetch fresh stream info
625-
val streamInfo = withContext(Dispatchers.IO) {
626-
executeJobFlow(
627-
SupportedJobType.FETCH_INFO,
628-
currentItem.mediaId,
629-
serviceId
630-
).info as StreamInfo
631-
}
632-
633-
// Create new media item with fresh stream URLs
634-
val newMediaItem = streamInfo.toMedia3MediaItem(uuid)
635-
636-
// Replace the media item at the current position
637-
withContext(Dispatchers.Main) {
638-
player.removeMediaItem(currentIndex)
639-
player.addMediaItem(currentIndex, newMediaItem)
640-
641-
// Seek to the saved position and try to play
642-
player.seekTo(currentIndex, savedPosition)
643-
player.prepare()
644-
player.play()
645-
}
646-
} catch (e: Exception) {
647-
e.printStackTrace()
648-
}
649-
}
650-
}
651620
private fun createPlayerListener(): Player.Listener {
652621
return object : Player.Listener {
653622
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
@@ -695,54 +664,6 @@ class PlaybackService : MediaLibraryService() {
695664
)
696665
}
697666

698-
699-
if (error.cause?.message?.contains("403") == true
700-
|| error.cause?.message?.contains("maybeThrowPlaylistRefreshError") == true) {
701-
val retryState = retryStates.getOrPut(mediaId) { RetryState() }
702-
703-
// First phase: retry up to MAX_RETRIES_BEFORE_REFRESH times before refreshing
704-
if (!retryState.hasRefreshedStream && retryState.retryCount < MAX_RETRIES_BEFORE_REFRESH) {
705-
retryState.retryCount++
706-
ToastManager.show("403 error, retrying (${retryState.retryCount}/$MAX_RETRIES_BEFORE_REFRESH)...")
707-
708-
// Simple retry - just prepare and play again
709-
player.prepare()
710-
player.play()
711-
return
712-
}
713-
714-
// Second phase: refresh stream if we haven't done so yet
715-
if (!retryState.hasRefreshedStream) {
716-
retryState.hasRefreshedStream = true
717-
retryState.retryCount = 0
718-
ToastManager.show("Refreshing stream after $MAX_RETRIES_BEFORE_REFRESH retries...")
719-
720-
refreshStreamAndRetry()
721-
return
722-
}
723-
724-
// Third phase: retry up to MAX_RETRIES_AFTER_REFRESH more times after refresh
725-
if (retryState.retryCount < MAX_RETRIES_AFTER_REFRESH) {
726-
retryState.retryCount++
727-
ToastManager.show("403 error after refresh, retrying (${retryState.retryCount}/$MAX_RETRIES_AFTER_REFRESH)...")
728-
729-
// Simple retry - just prepare and play again
730-
player.prepare()
731-
player.play()
732-
return
733-
}
734-
735-
// Final phase: all retries exhausted, give up and skip to next
736-
ToastManager.show("Failed after all retries, skipping to next...")
737-
retryStates.remove(mediaId)
738-
SharedContext.queueManager.removeItemByUuid(player.currentMediaItem!!.uuid)
739-
if (player.mediaItemCount > 0) {
740-
player.prepare()
741-
player.play()
742-
}
743-
return
744-
}
745-
746667
// Handle network-related errors: just pause, don't evict
747668
when (error.errorCode) {
748669
PlaybackException.ERROR_CODE_IO_INVALID_HTTP_CONTENT_TYPE,

0 commit comments

Comments
 (0)