Merge pull request #12718 from IceStormNG/extract-mks-subtitles

Extract subtitles of MKS aux files if they're extractable.
This commit is contained in:
Joshua M. Boniface 2025-08-03 17:31:13 -04:00 committed by GitHub
commit 5cae44fdf7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -489,10 +489,15 @@ namespace MediaBrowser.MediaEncoding.Subtitles
try
{
var subtitleStreams = mediaSource.MediaStreams
.Where(stream => stream is { IsExtractableSubtitleStream: true, SupportsExternalStream: true, IsExternal: false });
.Where(stream => stream is { IsExtractableSubtitleStream: true, SupportsExternalStream: true });
foreach (var subtitleStream in subtitleStreams)
{
if (subtitleStream.IsExternal && !subtitleStream.Path.EndsWith(".mks", StringComparison.OrdinalIgnoreCase))
{
continue;
}
var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, "." + GetExtractableSubtitleFileExtension(subtitleStream));
var releaser = await _semaphoreLocks.LockAsync(outputPath, cancellationToken).ConfigureAwait(false);
@ -510,6 +515,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
if (extractableStreams.Count > 0)
{
await ExtractAllExtractableSubtitlesInternal(mediaSource, extractableStreams, cancellationToken).ConfigureAwait(false);
await ExtractAllExtractableSubtitlesMKS(mediaSource, extractableStreams, cancellationToken).ConfigureAwait(false);
}
}
catch (Exception ex)
@ -522,6 +528,72 @@ namespace MediaBrowser.MediaEncoding.Subtitles
}
}
private async Task ExtractAllExtractableSubtitlesMKS(
MediaSourceInfo mediaSource,
List<MediaStream> subtitleStreams,
CancellationToken cancellationToken)
{
var mksFiles = new List<string>();
foreach (var subtitleStream in subtitleStreams)
{
if (string.IsNullOrEmpty(subtitleStream.Path) || !subtitleStream.Path.EndsWith(".mks", StringComparison.OrdinalIgnoreCase))
{
continue;
}
if (!mksFiles.Contains(subtitleStream.Path))
{
mksFiles.Add(subtitleStream.Path);
}
}
if (mksFiles.Count == 0)
{
return;
}
foreach (string mksFile in mksFiles)
{
var inputPath = _mediaEncoder.GetInputArgument(mksFile, mediaSource);
var outputPaths = new List<string>();
var args = string.Format(
CultureInfo.InvariantCulture,
"-i {0} -copyts",
inputPath);
foreach (var subtitleStream in subtitleStreams)
{
if (!subtitleStream.Path.Equals(mksFile, StringComparison.OrdinalIgnoreCase))
{
continue;
}
var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, "." + GetExtractableSubtitleFileExtension(subtitleStream));
var outputCodec = IsCodecCopyable(subtitleStream.Codec) ? "copy" : "srt";
var streamIndex = EncodingHelper.FindIndex(mediaSource.MediaStreams, subtitleStream);
if (streamIndex == -1)
{
_logger.LogError("Cannot find subtitle stream index for {InputPath} ({Index}), skipping this stream", inputPath, subtitleStream.Index);
continue;
}
Directory.CreateDirectory(Path.GetDirectoryName(outputPath) ?? throw new FileNotFoundException($"Calculated path ({outputPath}) is not valid."));
outputPaths.Add(outputPath);
args += string.Format(
CultureInfo.InvariantCulture,
" -map 0:{0} -an -vn -c:s {1} \"{2}\"",
streamIndex,
outputCodec,
outputPath);
}
await ExtractSubtitlesForFile(inputPath, args, outputPaths, cancellationToken).ConfigureAwait(false);
}
}
private async Task ExtractAllExtractableSubtitlesInternal(
MediaSourceInfo mediaSource,
List<MediaStream> subtitleStreams,
@ -536,6 +608,12 @@ namespace MediaBrowser.MediaEncoding.Subtitles
foreach (var subtitleStream in subtitleStreams)
{
if (!string.IsNullOrEmpty(subtitleStream.Path) && subtitleStream.Path.EndsWith(".mks", StringComparison.OrdinalIgnoreCase))
{
_logger.LogDebug("Subtitle {Index} for file {InputPath} is part in an MKS file. Skipping", inputPath, subtitleStream.Index);
continue;
}
var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, "." + GetExtractableSubtitleFileExtension(subtitleStream));
var outputCodec = IsCodecCopyable(subtitleStream.Codec) ? "copy" : "srt";
var streamIndex = EncodingHelper.FindIndex(mediaSource.MediaStreams, subtitleStream);
@ -557,6 +635,20 @@ namespace MediaBrowser.MediaEncoding.Subtitles
outputPath);
}
if (outputPaths.Count == 0)
{
return;
}
await ExtractSubtitlesForFile(inputPath, args, outputPaths, cancellationToken).ConfigureAwait(false);
}
private async Task ExtractSubtitlesForFile(
string inputPath,
string args,
List<string> outputPaths,
CancellationToken cancellationToken)
{
int exitCode;
using (var process = new Process