SrtParser.cs 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.IO;
  5. using System.Text.RegularExpressions;
  6. using System.Threading;
  7. namespace MediaBrowser.MediaEncoding.Subtitles
  8. {
  9. public class SrtParser : ISubtitleParser
  10. {
  11. private readonly CultureInfo _usCulture = new CultureInfo("en-US");
  12. public SubtitleTrackInfo Parse(Stream stream, CancellationToken cancellationToken)
  13. {
  14. var trackInfo = new SubtitleTrackInfo();
  15. using ( var reader = new StreamReader(stream))
  16. {
  17. string line;
  18. while ((line = reader.ReadLine()) != null)
  19. {
  20. cancellationToken.ThrowIfCancellationRequested();
  21. if (string.IsNullOrWhiteSpace(line))
  22. {
  23. continue;
  24. }
  25. var subEvent = new SubtitleTrackEvent {Id = line};
  26. line = reader.ReadLine();
  27. if (string.IsNullOrWhiteSpace(line))
  28. {
  29. continue;
  30. }
  31. var time = Regex.Split(line, @"[\t ]*-->[\t ]*");
  32. subEvent.StartPositionTicks = GetTicks(time[0]);
  33. var endTime = time[1];
  34. var idx = endTime.IndexOf(" ", StringComparison.Ordinal);
  35. if (idx > 0)
  36. endTime = endTime.Substring(0, idx);
  37. subEvent.EndPositionTicks = GetTicks(endTime);
  38. var multiline = new List<string>();
  39. while ((line = reader.ReadLine()) != null)
  40. {
  41. if (string.IsNullOrEmpty(line))
  42. {
  43. break;
  44. }
  45. multiline.Add(line);
  46. }
  47. subEvent.Text = string.Join(@"\n", multiline);
  48. subEvent.Text = Regex.Replace(subEvent.Text, @"\{(\\[\w]+\(?([\w\d]+,?)+\)?)+\}", string.Empty, RegexOptions.IgnoreCase);
  49. subEvent.Text = Regex.Replace(subEvent.Text, "<", "&lt;", RegexOptions.IgnoreCase);
  50. subEvent.Text = Regex.Replace(subEvent.Text, ">", "&gt;", RegexOptions.IgnoreCase);
  51. subEvent.Text = Regex.Replace(subEvent.Text, "&lt;(\\/?(font|b|u|i|s))((\\s+(\\w|\\w[\\w\\-]*\\w)(\\s*=\\s*(?:\\\".*?\\\"|'.*?'|[^'\\\">\\s]+))?)+\\s*|\\s*)(\\/?)&gt;", "<$1$3$7>", RegexOptions.IgnoreCase);
  52. trackInfo.TrackEvents.Add(subEvent);
  53. }
  54. }
  55. return trackInfo;
  56. }
  57. long GetTicks(string time) {
  58. TimeSpan span;
  59. return TimeSpan.TryParseExact(time, @"hh\:mm\:ss\.fff", _usCulture, out span)
  60. ? span.Ticks
  61. : (TimeSpan.TryParseExact(time, @"hh\:mm\:ss\,fff", _usCulture, out span)
  62. ? span.Ticks : 0);
  63. }
  64. }
  65. }