mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 23:51:21 +02:00
Fix selecting subtitle tracks (#122)
Fixes subtitle track selection especially when there is a mix of embedded & external subtitles Fixes #116
This commit is contained in:
parent
c65831cb05
commit
799255814f
2 changed files with 74 additions and 6 deletions
|
|
@ -348,6 +348,7 @@ fun PlaybackPage(
|
||||||
}
|
}
|
||||||
|
|
||||||
PlaybackAction.SearchCaptions -> {
|
PlaybackAction.SearchCaptions -> {
|
||||||
|
controllerViewState.hideControls()
|
||||||
viewModel.searchForSubtitles()
|
viewModel.searchForSubtitles()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -479,7 +479,7 @@ class PlaybackViewModel
|
||||||
|
|
||||||
val externalSubtitle =
|
val externalSubtitle =
|
||||||
source.mediaStreams
|
source.mediaStreams
|
||||||
?.firstOrNull { it.type == MediaStreamType.SUBTITLE && it.index == subtitleIndex && it.isExternal }
|
?.firstOrNull { it.type == MediaStreamType.SUBTITLE && it.isExternal && it.index == subtitleIndex }
|
||||||
?.let {
|
?.let {
|
||||||
it.deliveryUrl?.let { deliveryUrl ->
|
it.deliveryUrl?.let { deliveryUrl ->
|
||||||
var flags = 0
|
var flags = 0
|
||||||
|
|
@ -488,7 +488,7 @@ class PlaybackViewModel
|
||||||
MediaItem.SubtitleConfiguration
|
MediaItem.SubtitleConfiguration
|
||||||
.Builder(
|
.Builder(
|
||||||
api.createUrl(deliveryUrl).toUri(),
|
api.createUrl(deliveryUrl).toUri(),
|
||||||
).setId("${it.index + 1}") // Indexes are 1 based
|
).setId("e:${it.index}")
|
||||||
.setMimeType(subtitleMimeTypes[it.codec])
|
.setMimeType(subtitleMimeTypes[it.codec])
|
||||||
.setLanguage(it.language)
|
.setLanguage(it.language)
|
||||||
.setSelectionFlags(flags)
|
.setSelectionFlags(flags)
|
||||||
|
|
@ -564,6 +564,7 @@ class PlaybackViewModel
|
||||||
audioIndex,
|
audioIndex,
|
||||||
subtitleIndex,
|
subtitleIndex,
|
||||||
externalSubtitleCount,
|
externalSubtitleCount,
|
||||||
|
externalSubtitle != null,
|
||||||
)
|
)
|
||||||
player.removeListener(this)
|
player.removeListener(this)
|
||||||
}
|
}
|
||||||
|
|
@ -871,7 +872,6 @@ class PlaybackViewModel
|
||||||
compareByDescending<RemoteSubtitleInfo> { it.communityRating }
|
compareByDescending<RemoteSubtitleInfo> { it.communityRating }
|
||||||
.thenByDescending { it.downloadCount },
|
.thenByDescending { it.downloadCount },
|
||||||
)
|
)
|
||||||
|
|
||||||
subtitleSearch.setValueOnMain(SubtitleSearch.Success(results))
|
subtitleSearch.setValueOnMain(SubtitleSearch.Success(results))
|
||||||
}
|
}
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
|
|
@ -902,9 +902,73 @@ class PlaybackViewModel
|
||||||
itemId = it.sourceId ?: it.itemId,
|
itemId = it.sourceId ?: it.itemId,
|
||||||
subtitleId = subtitleId,
|
subtitleId = subtitleId,
|
||||||
)
|
)
|
||||||
|
val currentSubtitleStreams =
|
||||||
|
this@PlaybackViewModel
|
||||||
|
.subtitleStreams.value
|
||||||
|
.orEmpty()
|
||||||
|
val subtitleCount = currentSubtitleStreams.size
|
||||||
|
var newCount = subtitleCount
|
||||||
|
var maxAttempts = 4
|
||||||
|
var newStreams: List<SubtitleStream> = listOf()
|
||||||
|
|
||||||
|
// The server triggers a refresh in the background, so query periodically for the item until its updated
|
||||||
|
while (maxAttempts > 0 && subtitleCount == newCount) {
|
||||||
|
maxAttempts--
|
||||||
|
delay(1500)
|
||||||
|
dto = api.userLibraryApi.getItem(itemId = dto.id).content
|
||||||
|
val mediaSource = chooseSource(dto, it)
|
||||||
|
if (mediaSource == null) {
|
||||||
|
// This shouldn't happen, but just in case
|
||||||
|
showToast(
|
||||||
|
context,
|
||||||
|
"Item is no longer playable...",
|
||||||
|
Toast.LENGTH_SHORT,
|
||||||
|
)
|
||||||
|
return@launchIO
|
||||||
|
}
|
||||||
|
|
||||||
|
val subtitleStreams =
|
||||||
|
mediaSource.mediaStreams
|
||||||
|
?.filter { it.type == MediaStreamType.SUBTITLE }
|
||||||
|
.orEmpty()
|
||||||
|
newCount = subtitleStreams.size
|
||||||
|
|
||||||
|
if (subtitleCount != newCount) {
|
||||||
|
newStreams =
|
||||||
|
subtitleStreams.map {
|
||||||
|
SubtitleStream(
|
||||||
|
it.index,
|
||||||
|
it.language,
|
||||||
|
it.title,
|
||||||
|
it.codec,
|
||||||
|
it.codecTag,
|
||||||
|
it.isExternal,
|
||||||
|
it.isForced,
|
||||||
|
it.isDefault,
|
||||||
|
it.displayTitle,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
this@PlaybackViewModel.subtitleStreams.setValueOnMain(newStreams)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (maxAttempts == 0) {
|
||||||
|
showToast(
|
||||||
|
context,
|
||||||
|
"Download is taking a long time, you may need to restart playback",
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// Find the new subtitle stream
|
||||||
|
val newStream =
|
||||||
|
newStreams
|
||||||
|
.toMutableList()
|
||||||
|
.apply {
|
||||||
|
removeAll(currentSubtitleStreams)
|
||||||
|
}.firstOrNull { it.external }
|
||||||
|
if (newStream != null) {
|
||||||
|
changeSubtitleStream(newStream.index).join()
|
||||||
|
}
|
||||||
|
}
|
||||||
subtitleSearch.setValueOnMain(null)
|
subtitleSearch.setValueOnMain(null)
|
||||||
changeSubtitleStream(0).join()
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
if (wasPlaying) {
|
if (wasPlaying) {
|
||||||
player.play()
|
player.play()
|
||||||
|
|
@ -966,18 +1030,21 @@ private fun applyTrackSelections(
|
||||||
audioIndex: Int?,
|
audioIndex: Int?,
|
||||||
subtitleIndex: Int?,
|
subtitleIndex: Int?,
|
||||||
externalSubtitleCount: Int,
|
externalSubtitleCount: Int,
|
||||||
|
subtitleIsExternal: Boolean,
|
||||||
) {
|
) {
|
||||||
if (source.supportsDirectPlay) {
|
if (source.supportsDirectPlay) {
|
||||||
if (subtitleIndex != null && subtitleIndex >= 0) {
|
if (subtitleIndex != null && subtitleIndex >= 0) {
|
||||||
|
val indexToFind =
|
||||||
|
subtitleIndex + if (subtitleIsExternal) 0 else (if (externalSubtitleCount > 0) -1 else 1)
|
||||||
val chosenTrack =
|
val chosenTrack =
|
||||||
player.currentTracks.groups.firstOrNull { group ->
|
player.currentTracks.groups.firstOrNull { group ->
|
||||||
group.type == C.TRACK_TYPE_TEXT && group.isSupported &&
|
group.type == C.TRACK_TYPE_TEXT && group.isSupported &&
|
||||||
(0..<group.mediaTrackGroup.length)
|
(0..<group.mediaTrackGroup.length)
|
||||||
.map {
|
.map {
|
||||||
group.getTrackFormat(it).idAsInt
|
group.getTrackFormat(it).idAsInt
|
||||||
}.contains(subtitleIndex + 1) // Indexes are 1 based
|
}.contains(indexToFind)
|
||||||
}
|
}
|
||||||
Timber.v("Chosen subtitle track: $chosenTrack")
|
Timber.v("Chosen subtitle ($subtitleIndex/$indexToFind) track: $chosenTrack")
|
||||||
chosenTrack?.let {
|
chosenTrack?.let {
|
||||||
player.trackSelectionParameters =
|
player.trackSelectionParameters =
|
||||||
player.trackSelectionParameters
|
player.trackSelectionParameters
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue