diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/playback/VideoManager.java b/app/src/main/java/org/jellyfin/androidtv/ui/playback/VideoManager.java index ddf9327f2c..e8f10ba00c 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/playback/VideoManager.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/playback/VideoManager.java @@ -351,6 +351,7 @@ public void setMediaStreamInfo(ApiClient api, StreamInfo streamInfo) { .setLabel(mediaStream.getDisplayTitle()) .setSelectionFlags(getSubtitleSelectionFlags(mediaStream)) .build(); + Timber.i("Adding subtitle track %s of type %s", subtitleConfiguration.uri, subtitleConfiguration.mimeType); subtitleConfigurations.add(subtitleConfiguration); } } diff --git a/app/src/main/java/org/jellyfin/androidtv/util/profile/ExoPlayerProfile.kt b/app/src/main/java/org/jellyfin/androidtv/util/profile/ExoPlayerProfile.kt index 49ee144c3e..5c7bed755e 100644 --- a/app/src/main/java/org/jellyfin/androidtv/util/profile/ExoPlayerProfile.kt +++ b/app/src/main/java/org/jellyfin/androidtv/util/profile/ExoPlayerProfile.kt @@ -21,7 +21,6 @@ import org.jellyfin.apiclient.model.dlna.EncodingContext import org.jellyfin.apiclient.model.dlna.ProfileCondition import org.jellyfin.apiclient.model.dlna.ProfileConditionType import org.jellyfin.apiclient.model.dlna.ProfileConditionValue -import org.jellyfin.apiclient.model.dlna.SubtitleDeliveryMethod import org.jellyfin.apiclient.model.dlna.TranscodingProfile class ExoPlayerProfile( @@ -206,36 +205,27 @@ class ExoPlayerProfile( }.toTypedArray() subtitleProfiles = buildList { - // Rendering supported - arrayOf( - Codec.Subtitle.SRT, - Codec.Subtitle.SUBRIP, - Codec.Subtitle.DVBSUB, - Codec.Subtitle.VTT, - Codec.Subtitle.IDX, - ).forEach { codec -> - add(subtitleProfile(codec, SubtitleDeliveryMethod.Embed)) - add(subtitleProfile(codec, SubtitleDeliveryMethod.Hls)) - add(subtitleProfile(codec, SubtitleDeliveryMethod.External)) - } + // Jellyfin server only supports WebVTT subtitles in HLS, other text subtitles will be converted to WebVTT + // which we do not want so only allow delivery over HLS for WebVTT subtitles + subtitleProfile(Codec.Subtitle.VTT, embedded = true, hls = true, external = true) + subtitleProfile(Codec.Subtitle.WEBVTT, embedded = true, hls = true, external = true) - // Rendering supported, but needs to be embedded - arrayOf( - Codec.Subtitle.PGS, - Codec.Subtitle.PGSSUB, - ).forEach { codec -> - add(subtitleProfile(codec, SubtitleDeliveryMethod.Embed)) - add(subtitleProfile(codec, SubtitleDeliveryMethod.Hls)) - } + subtitleProfile(Codec.Subtitle.SRT, embedded = true, external = true) + subtitleProfile(Codec.Subtitle.SUBRIP, embedded = true, external = true) + subtitleProfile(Codec.Subtitle.TTML, embedded = true, external = true) - // Require baking - arrayOf( - Codec.Subtitle.ASS, - Codec.Subtitle.SSA, - Codec.Subtitle.DVDSUB, - ).forEach { codec -> - add(subtitleProfile(codec, SubtitleDeliveryMethod.Encode)) - } + // Not all subtitles can be loaded standalone by the player + subtitleProfile(Codec.Subtitle.DVBSUB, embedded = true, encode = true) + subtitleProfile(Codec.Subtitle.IDX, embedded = true, encode = true) + subtitleProfile(Codec.Subtitle.PGS, embedded = true, encode = true) + subtitleProfile(Codec.Subtitle.PGSSUB, embedded = true, encode = true) + + // ASS/SSA renderer only supports a small subset of the specification so encoding is required for correct rendering + subtitleProfile(Codec.Subtitle.ASS, encode = true) + subtitleProfile(Codec.Subtitle.SSA, encode = true) + + // Unsupported formats that need encoding + subtitleProfile(Codec.Subtitle.DVDSUB, encode = true) }.toTypedArray() } } diff --git a/app/src/main/java/org/jellyfin/androidtv/util/profile/ProfileHelper.kt b/app/src/main/java/org/jellyfin/androidtv/util/profile/ProfileHelper.kt index 959c9d774d..367a0f37ff 100644 --- a/app/src/main/java/org/jellyfin/androidtv/util/profile/ProfileHelper.kt +++ b/app/src/main/java/org/jellyfin/androidtv/util/profile/ProfileHelper.kt @@ -33,6 +33,7 @@ object ProfileHelper { ) ) } + !MediaTest.supportsAV1Main10() -> { Timber.i("*** Does NOT support AV1 10 bit") arrayOf( @@ -43,6 +44,7 @@ object ProfileHelper { ) ) } + else -> { // supports all AV1 Timber.i("*** Supports AV1 10 bit") @@ -83,6 +85,7 @@ object ProfileHelper { ) ) } + else -> { // If AVC is supported, include all relevant profiles Timber.i("*** Supports AVC") @@ -184,6 +187,7 @@ object ProfileHelper { ) ) } + else -> { // If HEVC is supported, include all relevant profiles Timber.i("*** Supports HEVC 10 bit") @@ -310,4 +314,17 @@ object ProfileHelper { this.format = format this.method = method } + + internal fun MutableList.subtitleProfile( + format: String, + embedded: Boolean = false, + external: Boolean = false, + hls: Boolean = false, + encode: Boolean = false, + ) { + if (embedded) add(subtitleProfile(format, SubtitleDeliveryMethod.Embed)) + if (external) add(subtitleProfile(format, SubtitleDeliveryMethod.External)) + if (hls) add(subtitleProfile(format, SubtitleDeliveryMethod.Hls)) + if (encode) add(subtitleProfile(format, SubtitleDeliveryMethod.Encode)) + } }