Fix live tv & recorded tv playback (#1770)
## Description #1654 broke playback for both live TV and recorded programs in `.ts` format. This PR fixes both issues! Jellyfin returns `NoCompatibleStream` for live tv if the source ID is passed in, so that is now skipped for live tv. `.ts` files may have IDs formatted with a slash instead of colon, so the logic is updated to handle that plus fallbacks for potentially unknown future formats. ### Related issues Fixes #1767 ### Testing Emulator & nvidia shield, plus unit tests ## Screenshots N/A ## AI or LLM usage None
This commit is contained in:
parent
7c6ab39436
commit
6ad96865e7
4 changed files with 116 additions and 33 deletions
|
|
@ -466,10 +466,16 @@ class PlaybackViewModel
|
|||
}
|
||||
}
|
||||
}
|
||||
val mediaSource = streamChoiceService.chooseSource(base, itemPlayback)
|
||||
val mediaSource =
|
||||
if (!isLiveTv) {
|
||||
streamChoiceService.chooseSource(base, itemPlayback)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
val plc = streamChoiceService.getPlaybackLanguageChoice(base)
|
||||
|
||||
if (mediaSource == null) {
|
||||
if (mediaSource == null && !isLiveTv) {
|
||||
showToast(
|
||||
context,
|
||||
"Item has no media sources, skipping...",
|
||||
|
|
@ -479,7 +485,8 @@ class PlaybackViewModel
|
|||
}
|
||||
|
||||
val videoStream =
|
||||
mediaSource.mediaStreams
|
||||
mediaSource
|
||||
?.mediaStreams
|
||||
?.firstOrNull { it.type == MediaStreamType.VIDEO }
|
||||
?.let {
|
||||
val isHdr =
|
||||
|
|
@ -493,37 +500,48 @@ class PlaybackViewModel
|
|||
// Create the correct player for the media
|
||||
createPlayer(videoStream?.hdr == true, videoStream?.is4k == true)
|
||||
|
||||
val subtitleStreams = getSubtitleStreams(mediaSource)
|
||||
val audioStreams = getAudioStreams(mediaSource)
|
||||
val subtitleStreams = mediaSource?.let { getSubtitleStreams(mediaSource) }.orEmpty()
|
||||
val audioStreams = mediaSource?.let { getAudioStreams(mediaSource) }.orEmpty()
|
||||
val audioStream =
|
||||
streamChoiceService
|
||||
.chooseAudioStream(
|
||||
source = mediaSource,
|
||||
seriesId = base.seriesId,
|
||||
itemPlayback = itemPlayback,
|
||||
plc = plc,
|
||||
prefs = preferences,
|
||||
)
|
||||
mediaSource?.let {
|
||||
streamChoiceService
|
||||
.chooseAudioStream(
|
||||
source = mediaSource,
|
||||
seriesId = base.seriesId,
|
||||
itemPlayback = itemPlayback,
|
||||
plc = plc,
|
||||
prefs = preferences,
|
||||
)
|
||||
}
|
||||
val audioIndex = audioStream?.index
|
||||
|
||||
val subtitleIndex =
|
||||
streamChoiceService
|
||||
.chooseSubtitleStream(
|
||||
source = mediaSource,
|
||||
audioStream = audioStream,
|
||||
seriesId = base.seriesId,
|
||||
itemPlayback = itemPlayback,
|
||||
plc = plc,
|
||||
prefs = preferences,
|
||||
)?.index
|
||||
|
||||
Timber.d("Selected mediaSource=${mediaSource.id}, audioIndex=$audioIndex, subtitleIndex=$subtitleIndex")
|
||||
mediaSource?.let {
|
||||
streamChoiceService
|
||||
.chooseSubtitleStream(
|
||||
source = mediaSource,
|
||||
audioStream = audioStream,
|
||||
seriesId = base.seriesId,
|
||||
itemPlayback = itemPlayback,
|
||||
plc = plc,
|
||||
prefs = preferences,
|
||||
)?.index
|
||||
}
|
||||
Timber.d(
|
||||
"Selected mediaSource=%s, audioIndex=%s, subtitleIndex=%s",
|
||||
mediaSource?.id,
|
||||
audioIndex,
|
||||
subtitleIndex,
|
||||
)
|
||||
|
||||
val trickPlayInfo =
|
||||
item.data.trickplay
|
||||
?.get(mediaSource.id)
|
||||
?.values
|
||||
?.firstOrNull()
|
||||
mediaSource?.id?.let { sourceId ->
|
||||
item.data.trickplay
|
||||
?.get(sourceId)
|
||||
?.values
|
||||
?.firstOrNull()
|
||||
}
|
||||
|
||||
trickPlayInfo?.let { trickplayInfo ->
|
||||
mediaSource.runTimeTicks?.ticks?.let { duration ->
|
||||
viewModelScope.launchIO {
|
||||
|
|
@ -545,7 +563,7 @@ class PlaybackViewModel
|
|||
}
|
||||
updateCurrentMedia {
|
||||
CurrentMediaInfo(
|
||||
sourceId = mediaSource.id,
|
||||
sourceId = mediaSource?.id,
|
||||
videoStream = videoStream,
|
||||
audioStreams = audioStreams,
|
||||
subtitleStreams = subtitleStreams,
|
||||
|
|
@ -559,7 +577,7 @@ class PlaybackViewModel
|
|||
audioIndex = audioIndex,
|
||||
subtitleIndex = subtitleIndex,
|
||||
positionMs = if (positionMs > 0) positionMs else C.TIME_UNSET,
|
||||
sourceId = mediaSource.id,
|
||||
sourceId = mediaSource?.id,
|
||||
enableDirectPlay = !forceTranscoding,
|
||||
enableDirectStream = !forceTranscoding,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -158,10 +158,16 @@ object TrackSelectionUtils {
|
|||
} else {
|
||||
track.trackFormats[0]
|
||||
.id
|
||||
?.split(":")
|
||||
?.map { it.toInt() }
|
||||
?.split(":", "/")
|
||||
?.map { it.toIntOrNull() ?: Int.MAX_VALUE }
|
||||
?.let {
|
||||
track to it
|
||||
if (it.size >= 2) {
|
||||
track to it
|
||||
} else if (it.isEmpty()) {
|
||||
track to listOf(Int.MAX_VALUE, Int.MAX_VALUE)
|
||||
} else {
|
||||
track to listOf(it[0], Int.MAX_VALUE)
|
||||
}
|
||||
}
|
||||
}
|
||||
}.sortedWith(compareBy<Pair<Tracks.Group, List<Int>>> { it.second[0] }.thenBy { it.second[1] })
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue