aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraltqx <al@altqx.com>2026-08-01 22:49:34 +0700
committeraltqx <al@altqx.com>2026-08-01 22:49:34 +0700
commitd4376e0539577e922b99fd300520d78909c65aae (patch)
treea987ead31b591075cdda5a80012fa7e36909257a
parent744ca84a8b5f0a5083d0e8c82e74dc62ca380ac7 (diff)
Allow client-rendered graphical subtitles during remux
-rw-r--r--MediaBrowser.Model/Dlna/StreamBuilder.cs6
-rw-r--r--tests/Jellyfin.Model.Tests/Dlna/StreamBuilderTests.cs46
2 files changed, 48 insertions, 4 deletions
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index a9ab7d6db0..ab8d5dd5b2 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -1582,7 +1582,11 @@ namespace MediaBrowser.Model.Dlna
continue;
}
- if (!subtitleStream.IsExternal && playMethod == PlayMethod.Transcode && !transcoderSupport.CanExtractSubtitles(subtitleStream.Codec))
+ if (!subtitleStream.IsExternal
+ && playMethod == PlayMethod.Transcode
+ && !transcoderSupport.CanExtractSubtitles(subtitleStream.Codec)
+ && !subtitleStream.IsPgsSubtitleStream
+ && !subtitleStream.IsVobSubSubtitleStream)
{
continue;
}
diff --git a/tests/Jellyfin.Model.Tests/Dlna/StreamBuilderTests.cs b/tests/Jellyfin.Model.Tests/Dlna/StreamBuilderTests.cs
index 5ba061296a..f5a023686c 100644
--- a/tests/Jellyfin.Model.Tests/Dlna/StreamBuilderTests.cs
+++ b/tests/Jellyfin.Model.Tests/Dlna/StreamBuilderTests.cs
@@ -371,6 +371,45 @@ namespace Jellyfin.Model.Tests
Assert.Equal(streamInfo?.SubtitleStreamIndex, options.SubtitleStreamIndex);
}
+ [Theory]
+ [InlineData("pgssub", null)]
+ [InlineData("vobsub", "mks")]
+ public async Task BuildVideoItemWithSecondaryAudioAndExternalGraphicalSubtitleKeepsVideoCopy(string subtitleCodec, string? subtitleContainer)
+ {
+ var options = await GetMediaOptions("Chrome", "mp4-h264-ac3-aac-srt-2600k");
+ var subtitleStream = options.MediaSources[0].MediaStreams[^1];
+ subtitleStream.Codec = subtitleCodec;
+ subtitleStream.IsExternal = false;
+ subtitleStream.SupportsExternalStream = true;
+ subtitleStream.Path = null;
+
+ options.Profile.SubtitleProfiles =
+ [
+ new SubtitleProfile
+ {
+ Format = subtitleCodec,
+ Container = subtitleContainer,
+ Method = SubtitleDeliveryMethod.External
+ }
+ ];
+ options.AudioStreamIndex = 2;
+ options.SubtitleStreamIndex = subtitleStream.Index;
+
+ var streamInfo = GetStreamBuilder(enableSubtitleExtraction: false).GetOptimalVideoStream(options);
+
+ Assert.NotNull(streamInfo);
+ Assert.Equal(PlayMethod.Transcode, streamInfo.PlayMethod);
+ Assert.Equal(TranscodeReason.SecondaryAudioNotSupported, streamInfo.TranscodeReasons);
+ Assert.Equal(SubtitleDeliveryMethod.External, streamInfo.SubtitleDeliveryMethod);
+ Assert.Contains("h264", streamInfo.VideoCodecs);
+ Assert.Contains("aac", streamInfo.AudioCodecs);
+
+ var queryString = streamInfo.ToUrl("media:", "ACCESSTOKEN", null).Split('?', 2).ElementAtOrDefault(1);
+ var query = System.Web.HttpUtility.ParseQueryString(queryString ?? string.Empty);
+ Assert.Null(query["SubtitleStreamIndex"]);
+ Assert.Null(query["SubtitleMethod"]);
+ }
+
private StreamInfo? BuildVideoItemSimpleTest(MediaOptions options, PlayMethod? playMethod, TranscodeReason why, string transcodeMode, string transcodeProtocol)
{
if (string.IsNullOrEmpty(transcodeProtocol))
@@ -573,9 +612,10 @@ namespace Jellyfin.Model.Tests
throw new SerializationException("Invalid test data: " + name);
}
- private StreamBuilder GetStreamBuilder()
+ private StreamBuilder GetStreamBuilder(bool enableSubtitleExtraction = false)
{
var transcodeSupport = new Mock<ITranscoderSupport>();
+ transcodeSupport.Setup(t => t.CanExtractSubtitles(It.IsAny<string>())).Returns(enableSubtitleExtraction);
var logger = new NullLogger<StreamBuilderTests>();
return new StreamBuilder(transcodeSupport.Object, logger);
@@ -625,7 +665,7 @@ namespace Jellyfin.Model.Tests
// EnableSubtitleExtraction = false, internal subtitles
[InlineData("srt", "srt", false, false, PlayMethod.Transcode, SubtitleDeliveryMethod.Encode)]
[InlineData("srt", "srt", false, false, PlayMethod.DirectPlay, SubtitleDeliveryMethod.External)]
- [InlineData("pgssub", "pgssub", false, false, PlayMethod.Transcode, SubtitleDeliveryMethod.Encode)]
+ [InlineData("pgssub", "pgssub", false, false, PlayMethod.Transcode, SubtitleDeliveryMethod.External)]
[InlineData("pgssub", "pgssub", false, false, PlayMethod.DirectPlay, SubtitleDeliveryMethod.External)]
[InlineData("pgssub", "srt", false, false, PlayMethod.Transcode, SubtitleDeliveryMethod.Encode)]
// EnableSubtitleExtraction = false, external subtitles
@@ -678,7 +718,7 @@ namespace Jellyfin.Model.Tests
[Theory]
[InlineData(false, null, true, SubtitleDeliveryMethod.External)]
- [InlineData(false, null, false, SubtitleDeliveryMethod.Encode)]
+ [InlineData(false, null, false, SubtitleDeliveryMethod.External)]
[InlineData(true, "/media/sub.mks", true, SubtitleDeliveryMethod.External)]
[InlineData(true, "/media/sub.idx", true, SubtitleDeliveryMethod.Encode)]
[InlineData(true, "/media/sub.sub", true, SubtitleDeliveryMethod.Encode)]