mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-05-13 16:47:46 +00:00
Merge 8dd989b5a8 into e9942c3857
This commit is contained in:
commit
2ee10a8ed4
4 changed files with 74 additions and 15 deletions
|
|
@ -127,6 +127,11 @@ namespace Emby.Server.Implementations.Library
|
|||
return true;
|
||||
}
|
||||
|
||||
if (stream.IsVobSubSubtitleStream)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -220,12 +220,11 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||
Path = outputPath,
|
||||
Protocol = MediaProtocol.File,
|
||||
Format = outputFormat,
|
||||
IsExternal = false
|
||||
IsExternal = MediaStream.IsVobSubFormat(outputFormat)
|
||||
};
|
||||
}
|
||||
|
||||
var currentFormat = subtitleStream.Codec ?? Path.GetExtension(subtitleStream.Path)
|
||||
.TrimStart('.');
|
||||
var currentFormat = subtitleStream.Codec ?? Path.GetExtension(subtitleStream.Path).TrimStart('.');
|
||||
|
||||
// Handle PGS subtitles as raw streams for the client to render
|
||||
if (MediaStream.IsPgsFormat(currentFormat))
|
||||
|
|
@ -475,6 +474,10 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||
{
|
||||
return subtitleStream.Codec;
|
||||
}
|
||||
else if (MediaStream.IsVobSubFormat(subtitleStream.Codec))
|
||||
{
|
||||
return "mks";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "srt";
|
||||
|
|
@ -488,6 +491,11 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||
{
|
||||
return "sup";
|
||||
}
|
||||
else if (MediaStream.IsVobSubFormat(subtitleStream.Codec))
|
||||
{
|
||||
// FFmpeg cannot mux VobSub subtitle streams back into the .idx/.sub pair, so we use .mks container instead.
|
||||
return "mks";
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetExtractableSubtitleFormat(subtitleStream);
|
||||
|
|
@ -500,7 +508,8 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||
|| string.Equals(codec, "ssa", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(codec, "srt", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(codec, "subrip", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(codec, "pgssub", StringComparison.OrdinalIgnoreCase);
|
||||
|| string.Equals(codec, "pgssub", StringComparison.OrdinalIgnoreCase)
|
||||
|| MediaStream.IsVobSubFormat(codec);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
@ -516,7 +525,8 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||
|
||||
foreach (var subtitleStream in subtitleStreams)
|
||||
{
|
||||
if (subtitleStream.IsExternal && !subtitleStream.Path.EndsWith(".mks", StringComparison.OrdinalIgnoreCase))
|
||||
if (subtitleStream.IsExternal
|
||||
&& !subtitleStream.Path.EndsWith(".mks", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -603,6 +613,8 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||
}
|
||||
|
||||
var outputCodec = IsCodecCopyable(subtitleStream.Codec) ? "copy" : "srt";
|
||||
// FFmpeg does not provide an .idx/.sub muxer, so VobSub streams must be written as MKS files.
|
||||
var outputFormatOption = MediaStream.IsVobSubFormat(subtitleStream.Codec) ? " -f matroska" : string.Empty;
|
||||
var streamIndex = EncodingHelper.FindIndex(mediaSource.MediaStreams, subtitleStream);
|
||||
|
||||
if (streamIndex == -1)
|
||||
|
|
@ -616,9 +628,10 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||
outputPaths.Add(outputPath);
|
||||
args += string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
" -map 0:{0} -an -vn -c:s {1} -flush_packets 1 \"{2}\"",
|
||||
" -map 0:{0} -an -vn -c:s {1}{2} -flush_packets 1 \"{3}\"",
|
||||
streamIndex,
|
||||
outputCodec,
|
||||
outputFormatOption,
|
||||
outputPath);
|
||||
}
|
||||
|
||||
|
|
@ -653,6 +666,8 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||
}
|
||||
|
||||
var outputCodec = IsCodecCopyable(subtitleStream.Codec) ? "copy" : "srt";
|
||||
// FFmpeg does not provide an .idx/.sub muxer, so VobSub streams must be written as MKS files.
|
||||
var outputFormatOption = MediaStream.IsVobSubFormat(subtitleStream.Codec) ? " -f matroska" : string.Empty;
|
||||
var streamIndex = EncodingHelper.FindIndex(mediaSource.MediaStreams, subtitleStream);
|
||||
|
||||
if (streamIndex == -1)
|
||||
|
|
@ -666,18 +681,17 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||
outputPaths.Add(outputPath);
|
||||
args += string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
" -map 0:{0} -an -vn -c:s {1} -flush_packets 1 \"{2}\"",
|
||||
" -map 0:{0} -an -vn -c:s {1}{2} -flush_packets 1 \"{3}\"",
|
||||
streamIndex,
|
||||
outputCodec,
|
||||
outputFormatOption,
|
||||
outputPath);
|
||||
}
|
||||
|
||||
if (outputPaths.Count == 0)
|
||||
if (outputPaths.Count > 0)
|
||||
{
|
||||
return;
|
||||
await ExtractSubtitlesForFile(inputPath, args, outputPaths, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await ExtractSubtitlesForFile(inputPath, args, outputPaths, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task ExtractSubtitlesForFile(
|
||||
|
|
|
|||
|
|
@ -575,7 +575,12 @@ namespace MediaBrowser.Model.Dlna
|
|||
{
|
||||
foreach (var profile in subtitleProfiles)
|
||||
{
|
||||
if (profile.Method == SubtitleDeliveryMethod.External && string.Equals(profile.Format, stream.Codec, StringComparison.OrdinalIgnoreCase))
|
||||
if (profile.Method == SubtitleDeliveryMethod.External
|
||||
&& (string.Equals(profile.Format, stream.Codec, StringComparison.OrdinalIgnoreCase)
|
||||
// FFmpeg cannot mux VobSub back into an .idx/.sub pair, so extracted VobSub streams are exposed as .mks.
|
||||
|| (string.Equals(profile.Format, "mks", StringComparison.OrdinalIgnoreCase)
|
||||
&& stream.IsVobSubSubtitleStream
|
||||
&& (!stream.IsExternal || stream.Path.EndsWith(".mks", StringComparison.OrdinalIgnoreCase)))))
|
||||
{
|
||||
return stream.Index;
|
||||
}
|
||||
|
|
@ -1564,10 +1569,17 @@ namespace MediaBrowser.Model.Dlna
|
|||
continue;
|
||||
}
|
||||
|
||||
if ((profile.Method == SubtitleDeliveryMethod.External && subtitleStream.IsTextSubtitleStream == MediaStream.IsTextFormat(profile.Format)) ||
|
||||
// FFmpeg cannot mux VobSub back into an .idx/.sub pair, so extracted VobSub streams are matched against external .mks delivery profiles.
|
||||
bool isVobSubMksProfile = string.Equals(profile.Format, "mks", StringComparison.OrdinalIgnoreCase)
|
||||
&& subtitleStream.IsVobSubSubtitleStream
|
||||
&& (!subtitleStream.IsExternal || subtitleStream.Path.EndsWith(".mks", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if ((profile.Method == SubtitleDeliveryMethod.External
|
||||
&& (isVobSubMksProfile || subtitleStream.IsTextSubtitleStream == MediaStream.IsTextFormat(profile.Format))) ||
|
||||
(profile.Method == SubtitleDeliveryMethod.Hls && subtitleStream.IsTextSubtitleStream))
|
||||
{
|
||||
bool requiresConversion = !string.Equals(subtitleStream.Codec, profile.Format, StringComparison.OrdinalIgnoreCase);
|
||||
bool requiresConversion = !isVobSubMksProfile
|
||||
&& !string.Equals(subtitleStream.Codec, profile.Format, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (!requiresConversion)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -644,13 +644,32 @@ namespace MediaBrowser.Model.Entities
|
|||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public bool IsVobSubSubtitleStream
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Type != MediaStreamType.Subtitle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(Codec) && !IsExternal)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return IsVobSubFormat(Codec);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this is a subtitle steam that is extractable by ffmpeg.
|
||||
/// All text-based and pgs subtitles can be extracted.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this is a extractable subtitle steam otherwise, <c>false</c>.</value>
|
||||
[JsonIgnore]
|
||||
public bool IsExtractableSubtitleStream => IsTextSubtitleStream || IsPgsSubtitleStream;
|
||||
public bool IsExtractableSubtitleStream => IsTextSubtitleStream || IsPgsSubtitleStream || IsVobSubSubtitleStream;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [supports external stream].
|
||||
|
|
@ -728,6 +747,7 @@ namespace MediaBrowser.Model.Entities
|
|||
return codec.Contains("microdvd", StringComparison.OrdinalIgnoreCase)
|
||||
|| (!codec.Contains("pgs", StringComparison.OrdinalIgnoreCase)
|
||||
&& !codec.Contains("dvdsub", StringComparison.OrdinalIgnoreCase)
|
||||
&& !codec.Contains("vobsub", StringComparison.OrdinalIgnoreCase)
|
||||
&& !codec.Contains("dvbsub", StringComparison.OrdinalIgnoreCase)
|
||||
&& !string.Equals(codec, "sup", StringComparison.OrdinalIgnoreCase)
|
||||
&& !string.Equals(codec, "sub", StringComparison.OrdinalIgnoreCase));
|
||||
|
|
@ -741,6 +761,14 @@ namespace MediaBrowser.Model.Entities
|
|||
|| string.Equals(codec, "sup", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public static bool IsVobSubFormat(string format)
|
||||
{
|
||||
string codec = format ?? string.Empty;
|
||||
|
||||
return codec.Contains("dvdsub", StringComparison.OrdinalIgnoreCase)
|
||||
|| codec.Contains("vobsub", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public bool SupportsSubtitleConversionTo(string toCodec)
|
||||
{
|
||||
if (!IsTextSubtitleStream)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue