Преглед изворни кода

Merge pull request #4877 from jellyfin/ass

Bond-009 пре 4 година
родитељ
комит
45c6d79dc9

+ 8 - 6
MediaBrowser.MediaEncoding/Subtitles/AssParser.cs

@@ -24,7 +24,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
             using (var reader = new StreamReader(stream))
             using (var reader = new StreamReader(stream))
             {
             {
                 string line;
                 string line;
-                while (reader.ReadLine() != "[Events]")
+                while (!string.Equals(reader.ReadLine(), "[Events]", StringComparison.Ordinal))
                 {
                 {
                 }
                 }
 
 
@@ -46,12 +46,13 @@ namespace MediaBrowser.MediaEncoding.Subtitles
 
 
                     var subEvent = new SubtitleTrackEvent { Id = eventIndex.ToString(_usCulture) };
                     var subEvent = new SubtitleTrackEvent { Id = eventIndex.ToString(_usCulture) };
                     eventIndex++;
                     eventIndex++;
-                    var sections = line.Substring(10).Split(',');
+                    const string Dialogue = "Dialogue: ";
+                    var sections = line.Substring(Dialogue.Length).Split(',');
 
 
                     subEvent.StartPositionTicks = GetTicks(sections[headers["Start"]]);
                     subEvent.StartPositionTicks = GetTicks(sections[headers["Start"]]);
                     subEvent.EndPositionTicks = GetTicks(sections[headers["End"]]);
                     subEvent.EndPositionTicks = GetTicks(sections[headers["End"]]);
 
 
-                    subEvent.Text = string.Join(",", sections.Skip(headers["Text"]));
+                    subEvent.Text = string.Join(',', sections[headers["Text"]..]);
                     RemoteNativeFormatting(subEvent);
                     RemoteNativeFormatting(subEvent);
 
 
                     subEvent.Text = subEvent.Text.Replace("\\n", ParserValues.NewLine, StringComparison.OrdinalIgnoreCase);
                     subEvent.Text = subEvent.Text.Replace("\\n", ParserValues.NewLine, StringComparison.OrdinalIgnoreCase);
@@ -62,7 +63,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
                 }
                 }
             }
             }
 
 
-            trackInfo.TrackEvents = trackEvents.ToArray();
+            trackInfo.TrackEvents = trackEvents;
             return trackInfo;
             return trackInfo;
         }
         }
 
 
@@ -72,9 +73,10 @@ namespace MediaBrowser.MediaEncoding.Subtitles
                 ? span.Ticks : 0;
                 ? span.Ticks : 0;
         }
         }
 
 
-        private Dictionary<string, int> ParseFieldHeaders(string line)
+        internal static Dictionary<string, int> ParseFieldHeaders(string line)
         {
         {
-            var fields = line.Substring(8).Split(',').Select(x => x.Trim()).ToList();
+            const string Format = "Format: ";
+            var fields = line.Substring(Format.Length).Split(',').Select(x => x.Trim()).ToList();
 
 
             return new Dictionary<string, int>
             return new Dictionary<string, int>
             {
             {

+ 2 - 0
jellyfin.ruleset

@@ -10,6 +10,8 @@
 
 
     <!-- disable warning SA1009: Closing parenthesis should be followed by a space. -->
     <!-- disable warning SA1009: Closing parenthesis should be followed by a space. -->
     <Rule Id="SA1009" Action="None" />
     <Rule Id="SA1009" Action="None" />
+    <!-- disable warning SA1011: Closing square bracket should be followed by a space. -->
+    <Rule Id="SA1011" Action="None" />
     <!-- disable warning SA1101: Prefix local calls with 'this.' -->
     <!-- disable warning SA1101: Prefix local calls with 'this.' -->
     <Rule Id="SA1101" Action="None" />
     <Rule Id="SA1101" Action="None" />
     <!-- disable warning SA1108: Block statements should not contain embedded comments -->
     <!-- disable warning SA1108: Block statements should not contain embedded comments -->

+ 38 - 0
tests/Jellyfin.MediaEncoding.Tests/Subtitles/AssParserTests.cs

@@ -0,0 +1,38 @@
+using System;
+using System.Globalization;
+using System.IO;
+using System.Threading;
+using MediaBrowser.MediaEncoding.Subtitles;
+using Xunit;
+
+namespace Jellyfin.MediaEncoding.Subtitles.Tests
+{
+    public class AssParserTests
+    {
+        [Fact]
+        public void Parse_Valid_Success()
+        {
+            using (var stream = File.OpenRead("Test Data/example.ass"))
+            {
+                var parsed = new AssParser().Parse(stream, CancellationToken.None);
+                Assert.Single(parsed.TrackEvents);
+                var trackEvent = parsed.TrackEvents[0];
+
+                Assert.Equal("1", trackEvent.Id);
+                Assert.Equal(TimeSpan.Parse("00:00:01.18", CultureInfo.InvariantCulture).Ticks, trackEvent.StartPositionTicks);
+                Assert.Equal(TimeSpan.Parse("00:00:06.85", CultureInfo.InvariantCulture).Ticks, trackEvent.EndPositionTicks);
+                Assert.Equal("Like an Angel with pity on nobody\r\nThe second line in subtitle", trackEvent.Text);
+            }
+        }
+
+        [Fact]
+        public void ParseFieldHeaders_Valid_Success()
+        {
+            const string Line = "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text";
+            var headers = AssParser.ParseFieldHeaders(Line);
+            Assert.Equal(1, headers["Start"]);
+            Assert.Equal(2, headers["End"]);
+            Assert.Equal(9, headers["Text"]);
+        }
+    }
+}

+ 22 - 0
tests/Jellyfin.MediaEncoding.Tests/Test Data/example.ass

@@ -0,0 +1,22 @@
+[Script Info]
+; Script generated by Aegisub
+; http://www.aegisub.org
+Title: Neon Genesis Evangelion - Episode 26 (neutral Spanish)
+Original Script: RoRo
+Script Updated By: version 2.8.01
+ScriptType: v4.00+
+Collisions: Normal
+PlayResY: 600
+PlayDepth: 0
+Timer: 100,0000
+Video Aspect Ratio: 0
+Video Zoom: 6
+Video Position: 0
+
+[V4+ Styles]
+Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
+Style: DefaultVCD, Arial,28,&H00B4FCFC,&H00B4FCFC,&H00000008,&H80000008,-1,0,0,0,100,100,0.00,0.00,1,1.00,2.00,2,30,30,30,0
+
+[Events]
+Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
+Dialogue: 0,0:00:01.18,0:00:06.85,DefaultVCD, NTP,0000,0000,0000,,{\pos(400,570)}Like an Angel with pity on nobody\NThe second line in subtitle