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:
Piotr Niełacny
2026-03-21 21:57:58 +01:00
parent 2c66447f08
commit 2a689f268b
3 changed files with 104 additions and 23 deletions

View File

@@ -1451,7 +1451,7 @@ namespace MediaBrowser.Model.Dlna
string? outputContainer,
MediaStreamProtocol? transcodingSubProtocol)
{
if (!subtitleStream.IsExternal && (playMethod != PlayMethod.Transcode || transcodingSubProtocol != MediaStreamProtocol.hls))
if (CanConsiderEmbedSubtitle(subtitleStream, playMethod, transcodingSubProtocol, outputContainer))
{
// Look for supported embedded subs of the same format
foreach (var profile in subtitleProfiles)
@@ -1540,6 +1540,19 @@ namespace MediaBrowser.Model.Dlna
return false;
}
private static bool CanConsiderEmbedSubtitle(MediaStream subtitleStream, PlayMethod playMethod, MediaStreamProtocol? transcodingSubProtocol, string? outputContainer)
{
if (subtitleStream.IsExternal)
{
return playMethod == PlayMethod.Transcode
&& transcodingSubProtocol != MediaStreamProtocol.hls
&& IsSubtitleEmbedSupported(outputContainer);
}
return playMethod != PlayMethod.Transcode
|| transcodingSubProtocol != MediaStreamProtocol.hls;
}
private static SubtitleProfile? GetExternalSubtitleProfile(MediaSourceInfo mediaSource, MediaStream subtitleStream, SubtitleProfile[] subtitleProfiles, PlayMethod playMethod, ITranscoderSupport transcoderSupport, bool allowConversion)
{
foreach (var profile in subtitleProfiles)