aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.MediaEncoding/Subtitles
diff options
context:
space:
mode:
authorKen Brazier <kbrazier@gmail.com>2020-07-18 11:39:53 -0600
committerKen Brazier <kbrazier@gmail.com>2020-07-18 11:39:53 -0600
commit6a39b1a4ca2b025dc094c364ebebeffacb285beb (patch)
tree16f828b978005988b4d7e7255501f3e3de66afa4 /MediaBrowser.MediaEncoding/Subtitles
parent36312c92f56671484caaeaf89e28f7737723e97d (diff)
parent09c05ff9faff4fd5013e19fad74835bdf796393f (diff)
Merge 'master' updates into 2354-soft-link-sizes
Diffstat (limited to 'MediaBrowser.MediaEncoding/Subtitles')
-rw-r--r--MediaBrowser.MediaEncoding/Subtitles/AssParser.cs10
-rw-r--r--MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs8
-rw-r--r--MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs85
-rw-r--r--MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs16
4 files changed, 109 insertions, 10 deletions
diff --git a/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs b/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs
index 293cf5ea5..0e2d70017 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs
@@ -23,6 +23,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
string line;
while (reader.ReadLine() != "[Events]")
{ }
+
var headers = ParseFieldHeaders(reader.ReadLine());
while ((line = reader.ReadLine()) != null)
@@ -33,10 +34,12 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
continue;
}
+
if (line.StartsWith("["))
+ {
break;
- if (string.IsNullOrEmpty(line))
- continue;
+ }
+
var subEvent = new SubtitleTrackEvent { Id = eventIndex.ToString(_usCulture) };
eventIndex++;
var sections = line.Substring(10).Split(',');
@@ -54,6 +57,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
trackEvents.Add(subEvent);
}
}
+
trackInfo.TrackEvents = trackEvents.ToArray();
return trackInfo;
}
@@ -110,11 +114,13 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
pre = s.Substring(0, 5) + "}";
}
+
int indexOfEnd = p.Text.IndexOf('}');
p.Text = p.Text.Remove(indexOfBegin, (indexOfEnd - indexOfBegin) + 1);
indexOfBegin = p.Text.IndexOf('{');
}
+
p.Text = pre + p.Text;
}
}
diff --git a/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs
index c98dd1502..728efa788 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs
@@ -35,6 +35,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
continue;
}
+
var subEvent = new SubtitleTrackEvent { Id = line };
line = reader.ReadLine();
@@ -52,11 +53,15 @@ namespace MediaBrowser.MediaEncoding.Subtitles
_logger.LogWarning("Unrecognized line in srt: {0}", line);
continue;
}
+
subEvent.StartPositionTicks = GetTicks(time[0]);
var endTime = time[1];
var idx = endTime.IndexOf(" ", StringComparison.Ordinal);
if (idx > 0)
+ {
endTime = endTime.Substring(0, idx);
+ }
+
subEvent.EndPositionTicks = GetTicks(endTime);
var multiline = new List<string>();
while ((line = reader.ReadLine()) != null)
@@ -65,8 +70,10 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
break;
}
+
multiline.Add(line);
}
+
subEvent.Text = string.Join(ParserValues.NewLine, multiline);
subEvent.Text = subEvent.Text.Replace(@"\N", ParserValues.NewLine, StringComparison.OrdinalIgnoreCase);
subEvent.Text = Regex.Replace(subEvent.Text, @"\{(?:\\\d?[\w.-]+(?:\([^\)]*\)|&H?[0-9A-Fa-f]+&|))+\}", string.Empty, RegexOptions.IgnoreCase);
@@ -76,6 +83,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
trackEvents.Add(subEvent);
}
}
+
trackInfo.TrackEvents = trackEvents.ToArray();
return trackInfo;
}
diff --git a/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs
index b94d45165..77033c6b4 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs
@@ -41,7 +41,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles
lineNumber++;
if (!eventsStarted)
+ {
header.AppendLine(line);
+ }
if (line.Trim().ToLowerInvariant() == "[events]")
{
@@ -62,17 +64,29 @@ namespace MediaBrowser.MediaEncoding.Subtitles
for (int i = 0; i < format.Length; i++)
{
if (format[i].Trim().ToLowerInvariant() == "layer")
+ {
indexLayer = i;
+ }
else if (format[i].Trim().ToLowerInvariant() == "start")
+ {
indexStart = i;
+ }
else if (format[i].Trim().ToLowerInvariant() == "end")
+ {
indexEnd = i;
+ }
else if (format[i].Trim().ToLowerInvariant() == "text")
+ {
indexText = i;
+ }
else if (format[i].Trim().ToLowerInvariant() == "effect")
+ {
indexEffect = i;
+ }
else if (format[i].Trim().ToLowerInvariant() == "style")
+ {
indexStyle = i;
+ }
}
}
}
@@ -89,28 +103,48 @@ namespace MediaBrowser.MediaEncoding.Subtitles
string[] splittedLine;
if (s.StartsWith("dialogue:"))
+ {
splittedLine = line.Substring(10).Split(',');
+ }
else
+ {
splittedLine = line.Split(',');
+ }
for (int i = 0; i < splittedLine.Length; i++)
{
if (i == indexStart)
+ {
start = splittedLine[i].Trim();
+ }
else if (i == indexEnd)
+ {
end = splittedLine[i].Trim();
+ }
else if (i == indexLayer)
+ {
layer = splittedLine[i];
+ }
else if (i == indexEffect)
+ {
effect = splittedLine[i];
+ }
else if (i == indexText)
+ {
text = splittedLine[i];
+ }
else if (i == indexStyle)
+ {
style = splittedLine[i];
+ }
else if (i == indexName)
+ {
name = splittedLine[i];
+ }
else if (i > indexText)
+ {
text += "," + splittedLine[i];
+ }
}
try
@@ -130,11 +164,12 @@ namespace MediaBrowser.MediaEncoding.Subtitles
}
}
- //if (header.Length > 0)
- //subtitle.Header = header.ToString();
+ // if (header.Length > 0)
+ // subtitle.Header = header.ToString();
- //subtitle.Renumber(1);
+ // subtitle.Renumber(1);
}
+
trackInfo.TrackEvents = trackEvents.ToArray();
return trackInfo;
}
@@ -168,15 +203,23 @@ namespace MediaBrowser.MediaEncoding.Subtitles
CheckAndAddSubTags(ref fontName, ref extraTags, out italic);
text = text.Remove(start, end - start + 1);
if (italic)
+ {
text = text.Insert(start, "<font face=\"" + fontName + "\"" + extraTags + "><i>");
+ }
else
+ {
text = text.Insert(start, "<font face=\"" + fontName + "\"" + extraTags + ">");
+ }
int indexOfEndTag = text.IndexOf("{\\fn}", start);
if (indexOfEndTag > 0)
+ {
text = text.Remove(indexOfEndTag, "{\\fn}".Length).Insert(indexOfEndTag, "</font>");
+ }
else
+ {
text += "</font>";
+ }
}
}
@@ -193,15 +236,23 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
text = text.Remove(start, end - start + 1);
if (italic)
+ {
text = text.Insert(start, "<font size=\"" + fontSize + "\"" + extraTags + "><i>");
+ }
else
+ {
text = text.Insert(start, "<font size=\"" + fontSize + "\"" + extraTags + ">");
+ }
int indexOfEndTag = text.IndexOf("{\\fs}", start);
if (indexOfEndTag > 0)
+ {
text = text.Remove(indexOfEndTag, "{\\fs}".Length).Insert(indexOfEndTag, "</font>");
+ }
else
+ {
text += "</font>";
+ }
}
}
}
@@ -225,14 +276,22 @@ namespace MediaBrowser.MediaEncoding.Subtitles
text = text.Remove(start, end - start + 1);
if (italic)
+ {
text = text.Insert(start, "<font color=\"" + color + "\"" + extraTags + "><i>");
+ }
else
+ {
text = text.Insert(start, "<font color=\"" + color + "\"" + extraTags + ">");
+ }
int indexOfEndTag = text.IndexOf("{\\c}", start);
if (indexOfEndTag > 0)
+ {
text = text.Remove(indexOfEndTag, "{\\c}".Length).Insert(indexOfEndTag, "</font>");
+ }
else
+ {
text += "</font>";
+ }
}
}
@@ -255,32 +314,41 @@ namespace MediaBrowser.MediaEncoding.Subtitles
text = text.Remove(start, end - start + 1);
if (italic)
+ {
text = text.Insert(start, "<font color=\"" + color + "\"" + extraTags + "><i>");
+ }
else
+ {
text = text.Insert(start, "<font color=\"" + color + "\"" + extraTags + ">");
+ }
text += "</font>";
}
}
-
}
text = text.Replace(@"{\i1}", "<i>");
text = text.Replace(@"{\i0}", "</i>");
text = text.Replace(@"{\i}", "</i>");
if (CountTagInText(text, "<i>") > CountTagInText(text, "</i>"))
+ {
text += "</i>";
+ }
text = text.Replace(@"{\u1}", "<u>");
text = text.Replace(@"{\u0}", "</u>");
text = text.Replace(@"{\u}", "</u>");
if (CountTagInText(text, "<u>") > CountTagInText(text, "</u>"))
+ {
text += "</u>";
+ }
text = text.Replace(@"{\b1}", "<b>");
text = text.Replace(@"{\b0}", "</b>");
text = text.Replace(@"{\b}", "</b>");
if (CountTagInText(text, "<b>") > CountTagInText(text, "</b>"))
+ {
text += "</b>";
+ }
return text;
}
@@ -288,7 +356,10 @@ namespace MediaBrowser.MediaEncoding.Subtitles
private static bool IsInteger(string s)
{
if (int.TryParse(s, out var i))
+ {
return true;
+ }
+
return false;
}
@@ -300,9 +371,13 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
count++;
if (index == text.Length)
+ {
return count;
+ }
+
index = text.IndexOf(tag, index + 1);
}
+
return count;
}
@@ -330,6 +405,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
rest = string.Empty;
}
+
extraTags += " size=\"" + fontSize.Substring(2) + "\"";
}
else if (rest.StartsWith("fn") && rest.Length > 2)
@@ -345,6 +421,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
rest = string.Empty;
}
+
extraTags += " face=\"" + fontName.Substring(2) + "\"";
}
else if (rest.StartsWith("c") && rest.Length > 2)
diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
index ba171295e..f1aa8ea5f 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
@@ -25,7 +25,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
public class SubtitleEncoder : ISubtitleEncoder
{
private readonly ILibraryManager _libraryManager;
- private readonly ILogger _logger;
+ private readonly ILogger<SubtitleEncoder> _logger;
private readonly IApplicationPaths _appPaths;
private readonly IFileSystem _fileSystem;
private readonly IMediaEncoder _mediaEncoder;
@@ -115,6 +115,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
throw new ArgumentNullException(nameof(item));
}
+
if (string.IsNullOrWhiteSpace(mediaSourceId))
{
throw new ArgumentNullException(nameof(mediaSourceId));
@@ -271,8 +272,11 @@ namespace MediaBrowser.MediaEncoding.Subtitles
}
public string Path { get; set; }
+
public MediaProtocol Protocol { get; set; }
+
public string Format { get; set; }
+
public bool IsExternal { get; set; }
}
@@ -287,10 +291,12 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
return new SrtParser(_logger);
}
+
if (string.Equals(format, SubtitleFormat.SSA, StringComparison.OrdinalIgnoreCase))
{
return new SsaParser();
}
+
if (string.Equals(format, SubtitleFormat.ASS, StringComparison.OrdinalIgnoreCase))
{
return new AssParser();
@@ -315,14 +321,17 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
return new JsonWriter();
}
+
if (string.Equals(format, SubtitleFormat.SRT, StringComparison.OrdinalIgnoreCase))
{
return new SrtWriter();
}
+
if (string.Equals(format, SubtitleFormat.VTT, StringComparison.OrdinalIgnoreCase))
{
return new VttWriter();
}
+
if (string.Equals(format, SubtitleFormat.TTML, StringComparison.OrdinalIgnoreCase))
{
return new TtmlWriter();
@@ -344,7 +353,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
}
/// <summary>
- /// The _semaphoreLocks
+ /// The _semaphoreLocks.
/// </summary>
private readonly ConcurrentDictionary<string, SemaphoreSlim> _semaphoreLocks =
new ConcurrentDictionary<string, SemaphoreSlim>();
@@ -640,7 +649,6 @@ namespace MediaBrowser.MediaEncoding.Subtitles
}
catch (FileNotFoundException)
{
-
}
catch (IOException ex)
{
@@ -737,7 +745,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
var charset = CharsetDetector.DetectFromStream(stream).Detected?.EncodingName;
// UTF16 is automatically converted to UTF8 by FFmpeg, do not specify a character encoding
- if ((path.EndsWith(".ass") || path.EndsWith(".ssa"))
+ if ((path.EndsWith(".ass") || path.EndsWith(".ssa") || path.EndsWith(".srt"))
&& (string.Equals(charset, "utf-16le", StringComparison.OrdinalIgnoreCase)
|| string.Equals(charset, "utf-16be", StringComparison.OrdinalIgnoreCase)))
{