mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-07-09 03:04:24 -04:00
Merge pull request #4877 from jellyfin/ass
This commit is contained in:
commit
45c6d79dc9
@ -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>
|
||||||
{
|
{
|
||||||
|
@ -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 -->
|
||||||
|
@ -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
tests/Jellyfin.MediaEncoding.Tests/Test Data/example.ass
Normal file
22
tests/Jellyfin.MediaEncoding.Tests/Test Data/example.ass
Normal file
@ -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
|
Loading…
x
Reference in New Issue
Block a user