mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-05-21 16:17:00 +01:00
Embed external subtitles into MKV when transcoding
Allow external subtitle files (SRT, ASS, PGS, etc.) to be muxed into MKV output containers when the device profile requests Embed delivery. Previously, the IsExternal guard in GetSubtitleProfile excluded external subtitles from Embed consideration entirely, forcing them to be served as separate sidecar files even when the output container supports embedding. Changes: - Extract CanConsiderEmbedSubtitle in StreamBuilder to allow external subs through when transcoding to MKV - Add external subtitle file as FFmpeg input (-i) for Embed delivery - Map external embedded subs from the correct FFmpeg input index - Fix external audio map index to account for the new subtitle input - Extract NeedsExternalSubtitleMuxing in EncodingHelper to deduplicate the external subtitle input check Fixes #16403
This commit is contained in:
@@ -675,5 +675,59 @@ namespace Jellyfin.Model.Tests
|
||||
|
||||
Assert.Equal(expectedMethod, result.Method);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
// External text subs embedded into MKV when transcoding (#16403)
|
||||
[InlineData("srt", true, PlayMethod.Transcode, "mkv", MediaStreamProtocol.http, SubtitleDeliveryMethod.Embed)]
|
||||
[InlineData("ass", true, PlayMethod.Transcode, "mkv", MediaStreamProtocol.http, SubtitleDeliveryMethod.Embed)]
|
||||
// External graphical subs embedded into MKV when transcoding
|
||||
[InlineData("pgssub", true, PlayMethod.Transcode, "mkv", MediaStreamProtocol.http, SubtitleDeliveryMethod.Embed)]
|
||||
[InlineData("dvdsub", true, PlayMethod.Transcode, "mkv", MediaStreamProtocol.http, SubtitleDeliveryMethod.Embed)]
|
||||
// External subs remain external when transcoding to non-MKV containers
|
||||
[InlineData("srt", true, PlayMethod.Transcode, "mp4", MediaStreamProtocol.hls, SubtitleDeliveryMethod.External)]
|
||||
[InlineData("srt", true, PlayMethod.Transcode, "ts", MediaStreamProtocol.hls, SubtitleDeliveryMethod.External)]
|
||||
// External subs remain external during DirectPlay even with MKV
|
||||
[InlineData("srt", true, PlayMethod.DirectPlay, "mkv", null, SubtitleDeliveryMethod.External)]
|
||||
// Internal subs still embedded into MKV when transcoding (existing behavior)
|
||||
[InlineData("srt", false, PlayMethod.Transcode, "mkv", MediaStreamProtocol.http, SubtitleDeliveryMethod.Embed)]
|
||||
[InlineData("pgssub", false, PlayMethod.Transcode, "mkv", MediaStreamProtocol.http, SubtitleDeliveryMethod.Embed)]
|
||||
public void GetSubtitleProfile_ReturnsExpectedDeliveryMethod(
|
||||
string codec,
|
||||
bool isExternal,
|
||||
PlayMethod playMethod,
|
||||
string outputContainer,
|
||||
MediaStreamProtocol? transcodingSubProtocol,
|
||||
SubtitleDeliveryMethod expectedMethod)
|
||||
{
|
||||
var mediaSource = new MediaSourceInfo();
|
||||
var subtitleStream = new MediaStream
|
||||
{
|
||||
Codec = codec,
|
||||
Language = "eng",
|
||||
IsExternal = isExternal,
|
||||
Type = MediaStreamType.Subtitle,
|
||||
SupportsExternalStream = true
|
||||
};
|
||||
|
||||
var subtitleProfiles = new[]
|
||||
{
|
||||
new SubtitleProfile { Format = codec, Method = SubtitleDeliveryMethod.Embed },
|
||||
new SubtitleProfile { Format = codec, Method = SubtitleDeliveryMethod.External }
|
||||
};
|
||||
|
||||
var transcoderSupport = new Mock<ITranscoderSupport>();
|
||||
transcoderSupport.Setup(x => x.CanExtractSubtitles(It.IsAny<string>())).Returns(true);
|
||||
|
||||
var result = StreamBuilder.GetSubtitleProfile(
|
||||
mediaSource,
|
||||
subtitleStream,
|
||||
subtitleProfiles,
|
||||
playMethod,
|
||||
transcoderSupport.Object,
|
||||
outputContainer,
|
||||
transcodingSubProtocol);
|
||||
|
||||
Assert.Equal(expectedMethod, result.Method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user