fix: selected caption option not properly showing current selection (#7176)

This commit is contained in:
Bnyro 2025-03-08 12:08:00 +01:00 committed by GitHub
commit 6b328e1e08
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 44 additions and 19 deletions

View File

@ -16,6 +16,7 @@ import androidx.core.graphics.drawable.IconCompat
import androidx.core.net.toUri
import androidx.media3.common.AudioAttributes
import androidx.media3.common.C
import androidx.media3.common.Format
import androidx.media3.common.PlaybackParameters
import androidx.media3.common.Player
import androidx.media3.common.TrackSelectionOverride
@ -33,6 +34,7 @@ import com.github.libretube.R
import com.github.libretube.api.obj.ChapterSegment
import com.github.libretube.api.obj.Segment
import com.github.libretube.api.obj.Streams
import com.github.libretube.api.obj.Subtitle
import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.db.DatabaseHolder
import com.github.libretube.db.obj.WatchPosition
@ -56,7 +58,7 @@ object PlayerHelper {
private const val ACTION_MEDIA_CONTROL = "media_control"
const val CONTROL_TYPE = "control_type"
const val SPONSOR_HIGHLIGHT_CATEGORY = "poi_highlight"
const val ROLE_FLAG_AUTO_GEN_SUBTITLE = C.ROLE_FLAG_SUPPLEMENTARY
private const val ROLE_FLAG_AUTO_GEN_SUBTITLE = C.ROLE_FLAG_SUPPLEMENTARY
private const val MINIMUM_BUFFER_DURATION = 1000 * 10 // exo default is 50s
const val WATCH_POSITION_TIMER_DELAY_MS = 1000L
@ -670,6 +672,28 @@ object PlayerHelper {
}
}
fun getCurrentPlayedCaptionFormat(player: Player): Format? {
for (trackGroup in player.currentTracks.groups) {
if (trackGroup.type != C.TRACK_TYPE_TEXT) continue
for (i in 0 until trackGroup.length) {
if (trackGroup.isTrackSelected(i)) return trackGroup.getTrackFormat(i)
}
}
return null
}
fun getSubtitleRoleFlags(subtitle: Subtitle?): Int {
if (subtitle?.code == null) return 0
return if (subtitle.autoGenerated != true) {
C.ROLE_FLAG_CAPTION
} else {
ROLE_FLAG_AUTO_GEN_SUBTITLE
}
}
/**
* Get the track type string resource corresponding to ExoPlayer role flags used for audio
* track types.

View File

@ -32,6 +32,7 @@ import com.github.libretube.extensions.parcelableExtra
import com.github.libretube.extensions.toastFromMainThread
import com.github.libretube.extensions.updateParameters
import com.github.libretube.helpers.PlayerHelper
import com.github.libretube.helpers.PlayerHelper.getSubtitleRoleFlags
import com.github.libretube.ui.activities.MainActivity
import com.github.libretube.util.NowPlayingNotification
import com.github.libretube.util.PauseableTimer
@ -169,8 +170,7 @@ abstract class AbstractPlayerService : MediaLibraryService(), MediaLibrarySessio
val subtitle: Subtitle? = args.parcelable(PlayerCommand.SET_SUBTITLE.name)
trackSelector?.updateParameters {
val roleFlags =
if (subtitle?.code != null) getSubtitleRoleFlags(subtitle) else 0
val roleFlags = getSubtitleRoleFlags(subtitle)
setPreferredTextRoleFlags(roleFlags)
setPreferredTextLanguage(subtitle?.code)
}
@ -190,14 +190,6 @@ abstract class AbstractPlayerService : MediaLibraryService(), MediaLibrarySessio
}
}
fun getSubtitleRoleFlags(subtitle: Subtitle?): Int {
return if (subtitle?.autoGenerated != true) {
C.ROLE_FLAG_CAPTION
} else {
PlayerHelper.ROLE_FLAG_AUTO_GEN_SUBTITLE
}
}
/**
* Update the [videoId] to the new videoId and change the playlist metadata
* to reflect that videoId change

View File

@ -26,6 +26,7 @@ import com.github.libretube.extensions.toastFromMainDispatcher
import com.github.libretube.extensions.toastFromMainThread
import com.github.libretube.helpers.PlayerHelper
import com.github.libretube.helpers.PlayerHelper.checkForSegments
import com.github.libretube.helpers.PlayerHelper.getSubtitleRoleFlags
import com.github.libretube.helpers.PreferenceHelper
import com.github.libretube.helpers.ProxyHelper
import com.github.libretube.parcelable.PlayerData

View File

@ -335,9 +335,10 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {
}
// JSON-encode as work-around for https://github.com/androidx/media/issues/564
val segments: List<Segment>? = mediaMetadata.extras?.getString(IntentData.segments)?.let {
JsonHelper.json.decodeFromString(it)
}
val segments: List<Segment>? =
mediaMetadata.extras?.getString(IntentData.segments)?.let {
JsonHelper.json.decodeFromString(it)
}
viewModel.segments.postValue(segments.orEmpty())
}
@ -521,9 +522,10 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {
if (!startNewSession) {
// JSON-encode as work-around for https://github.com/androidx/media/issues/564
val streams: Streams? =
playerController.mediaMetadata.extras?.getString(IntentData.streams)?.let { json ->
JsonHelper.json.decodeFromString(json)
}
playerController.mediaMetadata.extras?.getString(IntentData.streams)
?.let { json ->
JsonHelper.json.decodeFromString(json)
}
// reload the streams data and playback, metadata apparently no longer exists
if (streams == null) {
@ -1296,7 +1298,11 @@ class PlayerFragment : Fragment(R.layout.fragment_player), OnlinePlayerOptions {
BaseBottomSheet()
.setSimpleItems(
subtitles.map { it.getDisplayName(requireContext()) },
preselectedItem = subtitles.firstOrNull { it == viewModel.currentSubtitle }
preselectedItem = subtitles.firstOrNull {
val roleFlags = PlayerHelper.getSubtitleRoleFlags(it)
val currentSubtitle = PlayerHelper.getCurrentPlayedCaptionFormat(playerController)
it.code == currentSubtitle?.language && currentSubtitle?.roleFlags == roleFlags
}
?.getDisplayName(requireContext()) ?: getString(R.string.none)
) { index ->
val subtitle = subtitles.getOrNull(index) ?: return@setSimpleItems

View File

@ -11,6 +11,8 @@ import com.github.libretube.helpers.PlayerHelper
class PlayerViewModel : ViewModel() {
var segments = MutableLiveData<List<Segment>>()
// this is only used to restore the subtitle after leaving PiP, the actual caption state
// should always be read from the player's selected tracks!
var currentSubtitle = Subtitle(code = PlayerHelper.defaultSubtitleCode)
var sponsorBlockConfig = PlayerHelper.getSponsorBlockCategories()

View File

@ -76,7 +76,7 @@ class OnlinePlayerView(
context.getString(R.string.captions),
R.drawable.ic_caption,
{
playerViewModel?.currentSubtitle?.code
player?.let { PlayerHelper.getCurrentPlayedCaptionFormat(it)?.language }
?: context.getString(R.string.none)
}
) {