jellyfin-server/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs

72 lines
2.7 KiB
C#
Raw Normal View History

2014-05-05 14:45:45 +00:00
using System;
using System.Collections.Generic;
2014-05-11 04:23:16 +00:00
using System.Globalization;
2014-05-05 14:45:45 +00:00
using System.IO;
using System.Linq;
2014-05-11 04:23:16 +00:00
using System.Text.RegularExpressions;
using System.Threading;
2014-05-05 14:45:45 +00:00
namespace MediaBrowser.MediaEncoding.Subtitles
{
2014-05-07 02:28:19 +00:00
public class SsaParser : ISubtitleParser
2014-05-05 14:45:45 +00:00
{
2014-05-11 04:23:16 +00:00
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
public SubtitleTrackInfo Parse(Stream stream, CancellationToken cancellationToken)
2014-05-05 14:45:45 +00:00
{
2014-05-11 04:23:16 +00:00
var trackInfo = new SubtitleTrackInfo();
var eventIndex = 1;
using (var reader = new StreamReader(stream))
{
string line;
while (reader.ReadLine() != "[Events]")
{}
var headers = ParseFieldHeaders(reader.ReadLine());
while ((line = reader.ReadLine()) != null)
{
cancellationToken.ThrowIfCancellationRequested();
2014-05-11 04:23:16 +00:00
if (string.IsNullOrWhiteSpace(line))
{
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(',');
subEvent.StartPositionTicks = GetTicks(sections[headers["Start"]]);
subEvent.EndPositionTicks = GetTicks(sections[headers["End"]]);
subEvent.Text = string.Join(",", sections.Skip(headers["Text"]));
2014-05-11 04:33:14 +00:00
subEvent.Text = Regex.Replace(subEvent.Text, @"\{(\\[\w]+\(?([\w\d]+,?)+\)?)+\}", string.Empty, RegexOptions.IgnoreCase);
2014-05-11 04:23:16 +00:00
trackInfo.TrackEvents.Add(subEvent);
}
}
return trackInfo;
}
long GetTicks(string time)
{
TimeSpan span;
return TimeSpan.TryParseExact(time, @"h\:mm\:ss\.ff", _usCulture, out span)
? span.Ticks: 0;
}
private Dictionary<string,int> ParseFieldHeaders(string line) {
var fields = line.Substring(8).Split(',').Select(x=>x.Trim()).ToList();
var result = new Dictionary<string, int> {
{"Start", fields.IndexOf("Start")},
{"End", fields.IndexOf("End")},
{"Text", fields.IndexOf("Text")}
};
return result;
2014-05-05 14:45:45 +00:00
}
}
}