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 e8f10ba00c..28e9015264 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 @@ -44,7 +44,6 @@ import org.jellyfin.androidtv.data.compat.StreamInfo; import org.jellyfin.androidtv.preference.UserPreferences; import org.jellyfin.androidtv.preference.constant.ZoomMode; -import org.jellyfin.playback.media3.exoplayer.mapping.SubtitleKt; import org.jellyfin.sdk.api.client.ApiClient; import org.jellyfin.sdk.model.api.MediaStream; import org.jellyfin.sdk.model.api.MediaStreamType; @@ -346,7 +345,7 @@ public void setMediaStreamInfo(ApiClient api, StreamInfo streamInfo) { Uri subtitleUri = Uri.parse(api.createUrl(mediaStream.getDeliveryUrl(), Collections.emptyMap(), Collections.emptyMap(), true)); MediaItem.SubtitleConfiguration subtitleConfiguration = new MediaItem.SubtitleConfiguration.Builder(subtitleUri) .setId("JF_EXTERNAL:" + String.valueOf(mediaStream.getIndex())) - .setMimeType(SubtitleKt.getFfmpegSubtitleMimeType(mediaStream.getCodec())) + .setMimeType(VideoManagerHelperKt.getSubtitleMediaStreamCodec(mediaStream)) .setLanguage(mediaStream.getLanguage()) .setLabel(mediaStream.getDisplayTitle()) .setSelectionFlags(getSubtitleSelectionFlags(mediaStream)) diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/playback/VideoManagerHelper.kt b/app/src/main/java/org/jellyfin/androidtv/ui/playback/VideoManagerHelper.kt new file mode 100644 index 0000000000..b35ff89a5e --- /dev/null +++ b/app/src/main/java/org/jellyfin/androidtv/ui/playback/VideoManagerHelper.kt @@ -0,0 +1,19 @@ +package org.jellyfin.androidtv.ui.playback + +import androidx.core.net.toUri +import org.jellyfin.playback.media3.exoplayer.mapping.getFfmpegSubtitleMimeType +import org.jellyfin.sdk.model.api.MediaStream + +/** + * Return the media type for the codec found in this media stream. First tries to infer the media type from the streams delivery URL and + * falls back to the original stream codec. + */ +fun getSubtitleMediaStreamCodec(stream: MediaStream): String { + val codec = requireNotNull(stream.codec) + val codecMediaType = getFfmpegSubtitleMimeType(codec, "").ifBlank { null } + + val urlSubtitleExtension = stream.deliveryUrl?.toUri()?.lastPathSegment?.split('.')?.last() + val urlExtensionMediaType = urlSubtitleExtension?.let { getFfmpegSubtitleMimeType(it, "") }?.ifBlank { null } + + return urlExtensionMediaType ?: codecMediaType ?: urlSubtitleExtension ?: codec +} diff --git a/playback/media3/exoplayer/src/main/kotlin/mapping/audio.kt b/playback/media3/exoplayer/src/main/kotlin/mapping/audio.kt index 39a6a20213..3bd1b08860 100644 --- a/playback/media3/exoplayer/src/main/kotlin/mapping/audio.kt +++ b/playback/media3/exoplayer/src/main/kotlin/mapping/audio.kt @@ -5,10 +5,10 @@ import androidx.media3.common.MimeTypes import androidx.media3.common.util.UnstableApi @OptIn(UnstableApi::class) -fun getFfmpegAudioMimeType(codec: String) = codec.lowercase().let { codec -> +fun getFfmpegAudioMimeType(codec: String, fallback: String = codec) = codec.lowercase().let { codec -> ffmpegAudioMimeTypes[codec] ?: MimeTypes.getAudioMediaMimeType(codec) - ?: codec + ?: fallback } val ffmpegAudioMimeTypes = mapOf( diff --git a/playback/media3/exoplayer/src/main/kotlin/mapping/container.kt b/playback/media3/exoplayer/src/main/kotlin/mapping/container.kt index f3dd497b90..cc4898248e 100644 --- a/playback/media3/exoplayer/src/main/kotlin/mapping/container.kt +++ b/playback/media3/exoplayer/src/main/kotlin/mapping/container.kt @@ -5,12 +5,12 @@ import androidx.media3.common.MimeTypes import androidx.media3.common.util.UnstableApi @OptIn(UnstableApi::class) -fun getFfmpegContainerMimeType(codec: String) = codec.lowercase().let { codec -> +fun getFfmpegContainerMimeType(codec: String, fallback: String = codec) = codec.lowercase().let { codec -> ffmpegContainerMimeTypes[codec] ?: ffmpegVideoMimeTypes[codec] ?: ffmpegAudioMimeTypes[codec] ?: MimeTypes.getMediaMimeType(codec) - ?: codec + ?: fallback } @OptIn(UnstableApi::class) diff --git a/playback/media3/exoplayer/src/main/kotlin/mapping/subtitle.kt b/playback/media3/exoplayer/src/main/kotlin/mapping/subtitle.kt index 7bd18aa635..4479e8bc6a 100644 --- a/playback/media3/exoplayer/src/main/kotlin/mapping/subtitle.kt +++ b/playback/media3/exoplayer/src/main/kotlin/mapping/subtitle.kt @@ -5,10 +5,10 @@ import androidx.media3.common.MimeTypes import androidx.media3.common.util.UnstableApi @OptIn(UnstableApi::class) -fun getFfmpegSubtitleMimeType(codec: String): String = codec.lowercase().let { codec -> +fun getFfmpegSubtitleMimeType(codec: String, fallback: String = codec): String = codec.lowercase().let { codec -> ffmpegSubtitleMimeTypes[codec] ?: MimeTypes.getTextMediaMimeType(codec) - ?: codec + ?: fallback } @OptIn(UnstableApi::class) diff --git a/playback/media3/exoplayer/src/main/kotlin/mapping/video.kt b/playback/media3/exoplayer/src/main/kotlin/mapping/video.kt index d36e91b7cb..0c0c3d3e70 100644 --- a/playback/media3/exoplayer/src/main/kotlin/mapping/video.kt +++ b/playback/media3/exoplayer/src/main/kotlin/mapping/video.kt @@ -5,10 +5,10 @@ import androidx.media3.common.MimeTypes import androidx.media3.common.util.UnstableApi @OptIn(UnstableApi::class) -fun getFfmpegVideoMimeType(codec: String) = codec.lowercase().let { codec -> +fun getFfmpegVideoMimeType(codec: String, fallback: String = codec) = codec.lowercase().let { codec -> ffmpegVideoMimeTypes[codec] ?: MimeTypes.getVideoMediaMimeType(codec) - ?: codec + ?: fallback } @OptIn(UnstableApi::class)