mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 15:50:16 +02:00
Handle external subtitles
This commit is contained in:
parent
64e881f51c
commit
81d0279cce
3 changed files with 60 additions and 5 deletions
|
|
@ -6,6 +6,7 @@ data class SubtitleStream(
|
||||||
val title: String?,
|
val title: String?,
|
||||||
val codec: String?,
|
val codec: String?,
|
||||||
val codecTag: String?,
|
val codecTag: String?,
|
||||||
|
val external: Boolean,
|
||||||
) {
|
) {
|
||||||
val displayName: String
|
val displayName: String
|
||||||
get() =
|
get() =
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import com.github.damontecres.dolphin.util.TrackActivityPlaybackListener
|
||||||
import com.github.damontecres.dolphin.util.TrackSupport
|
import com.github.damontecres.dolphin.util.TrackSupport
|
||||||
import com.github.damontecres.dolphin.util.checkForSupport
|
import com.github.damontecres.dolphin.util.checkForSupport
|
||||||
import com.github.damontecres.dolphin.util.profile.PlaybackListener
|
import com.github.damontecres.dolphin.util.profile.PlaybackListener
|
||||||
|
import com.github.damontecres.dolphin.util.subtitleMimeTypes
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
|
@ -142,7 +143,14 @@ class PlaybackViewModel
|
||||||
base.mediaStreams
|
base.mediaStreams
|
||||||
?.filter { it.type == MediaStreamType.SUBTITLE }
|
?.filter { it.type == MediaStreamType.SUBTITLE }
|
||||||
?.map {
|
?.map {
|
||||||
SubtitleStream(it.index, it.language, it.title, it.codec, it.codecTag)
|
SubtitleStream(
|
||||||
|
it.index,
|
||||||
|
it.language,
|
||||||
|
it.title,
|
||||||
|
it.codec,
|
||||||
|
it.codecTag,
|
||||||
|
it.isExternal,
|
||||||
|
)
|
||||||
}.orEmpty()
|
}.orEmpty()
|
||||||
val audioStreams =
|
val audioStreams =
|
||||||
base.mediaStreams
|
base.mediaStreams
|
||||||
|
|
@ -226,7 +234,7 @@ class PlaybackViewModel
|
||||||
allowAudioStreamCopy = true,
|
allowAudioStreamCopy = true,
|
||||||
autoOpenLiveStream = true,
|
autoOpenLiveStream = true,
|
||||||
mediaSourceId = null,
|
mediaSourceId = null,
|
||||||
alwaysBurnInSubtitleWhenTranscoding = false,
|
alwaysBurnInSubtitleWhenTranscoding = null,
|
||||||
),
|
),
|
||||||
).content
|
).content
|
||||||
val source = response.mediaSources.firstOrNull()
|
val source = response.mediaSources.firstOrNull()
|
||||||
|
|
@ -254,6 +262,33 @@ class PlaybackViewModel
|
||||||
val decision = StreamDecision(itemId, transcodeType, mediaUrl)
|
val decision = StreamDecision(itemId, transcodeType, mediaUrl)
|
||||||
Timber.v("Playback decision: $decision")
|
Timber.v("Playback decision: $decision")
|
||||||
|
|
||||||
|
val externalSubtitle =
|
||||||
|
source.mediaStreams
|
||||||
|
?.firstOrNull { it.type == MediaStreamType.SUBTITLE && it.index == subtitleIndex && it.isExternal }
|
||||||
|
?.let {
|
||||||
|
it.deliveryUrl?.let { deliveryUrl ->
|
||||||
|
var flags = 0
|
||||||
|
if (it.isForced) flags = flags.and(C.SELECTION_FLAG_FORCED)
|
||||||
|
if (it.isDefault) flags = flags.and(C.SELECTION_FLAG_DEFAULT)
|
||||||
|
MediaItem.SubtitleConfiguration
|
||||||
|
.Builder(
|
||||||
|
api.createUrl(deliveryUrl).toUri(),
|
||||||
|
).setId("${it.index + 1}") // Indexes are 1 based
|
||||||
|
.setMimeType(subtitleMimeTypes[it.codec])
|
||||||
|
.setLanguage(it.language)
|
||||||
|
.setSelectionFlags(flags)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val mediaItem =
|
||||||
|
MediaItem
|
||||||
|
.Builder()
|
||||||
|
.setMediaId(itemId.toString())
|
||||||
|
.setUri(mediaUrl.toUri())
|
||||||
|
.setSubtitleConfigurations(listOfNotNull(externalSubtitle))
|
||||||
|
.build()
|
||||||
|
|
||||||
val playback =
|
val playback =
|
||||||
CurrentPlayback(
|
CurrentPlayback(
|
||||||
itemId,
|
itemId,
|
||||||
|
|
@ -268,7 +303,7 @@ class PlaybackViewModel
|
||||||
stream.value = decision
|
stream.value = decision
|
||||||
currentPlayback.value = playback
|
currentPlayback.value = playback
|
||||||
player.setMediaItem(
|
player.setMediaItem(
|
||||||
decision.mediaItem,
|
mediaItem,
|
||||||
positionMs,
|
positionMs,
|
||||||
)
|
)
|
||||||
if (audioIndex != null || subtitleIndex != null) {
|
if (audioIndex != null || subtitleIndex != null) {
|
||||||
|
|
@ -377,7 +412,7 @@ private fun applyTrackSelections(
|
||||||
(0..<group.mediaTrackGroup.length)
|
(0..<group.mediaTrackGroup.length)
|
||||||
.map {
|
.map {
|
||||||
group.getTrackFormat(it).idAsInt
|
group.getTrackFormat(it).idAsInt
|
||||||
}.contains(subtitleIndex + 1)
|
}.contains(subtitleIndex + 1) // Indexes are 1 based
|
||||||
}
|
}
|
||||||
Timber.v("Chosen subtitle track: $chosenTrack")
|
Timber.v("Chosen subtitle track: $chosenTrack")
|
||||||
chosenTrack?.let {
|
chosenTrack?.let {
|
||||||
|
|
@ -406,7 +441,7 @@ private fun applyTrackSelections(
|
||||||
(0..<group.mediaTrackGroup.length)
|
(0..<group.mediaTrackGroup.length)
|
||||||
.map {
|
.map {
|
||||||
group.getTrackFormat(it).idAsInt
|
group.getTrackFormat(it).idAsInt
|
||||||
}.contains(audioIndex + 1)
|
}.contains(audioIndex + 1) // Indexes are 1 based
|
||||||
}
|
}
|
||||||
Timber.v("Chosen audio track: $chosenTrack")
|
Timber.v("Chosen audio track: $chosenTrack")
|
||||||
chosenTrack?.let {
|
chosenTrack?.let {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.github.damontecres.dolphin.util
|
||||||
|
|
||||||
|
import androidx.media3.common.MimeTypes
|
||||||
|
import com.github.damontecres.dolphin.util.profile.Codec
|
||||||
|
|
||||||
|
val subtitleMimeTypes =
|
||||||
|
mapOf(
|
||||||
|
Codec.Subtitle.ASS to MimeTypes.TEXT_SSA,
|
||||||
|
Codec.Subtitle.DVBSUB to MimeTypes.APPLICATION_VOBSUB,
|
||||||
|
Codec.Subtitle.DVBSUB to MimeTypes.APPLICATION_VOBSUB,
|
||||||
|
Codec.Subtitle.PGS to MimeTypes.APPLICATION_PGS,
|
||||||
|
Codec.Subtitle.PGSSUB to MimeTypes.APPLICATION_PGS,
|
||||||
|
Codec.Subtitle.SRT to MimeTypes.APPLICATION_SUBRIP,
|
||||||
|
Codec.Subtitle.SSA to MimeTypes.TEXT_SSA,
|
||||||
|
Codec.Subtitle.SUBRIP to MimeTypes.APPLICATION_SUBRIP,
|
||||||
|
Codec.Subtitle.TTML to MimeTypes.APPLICATION_TTML,
|
||||||
|
Codec.Subtitle.VTT to MimeTypes.TEXT_VTT,
|
||||||
|
Codec.Subtitle.WEBVTT to MimeTypes.TEXT_VTT,
|
||||||
|
)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue