Subtitle.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Text.RegularExpressions;
  6. using UnityEngine;
  7. using UnityEngine.UI;
  8. public class SubtitleBlock
  9. {
  10. private static readonly Regex TimeStampRegex = new Regex(@"^(?<start>\d{2}:\d{2}:\d{2},\d{3})\s+(?<end>\d{2}:\d{2}:\d{2},\d{3})$");
  11. public int Index { get; private set; }
  12. public double Length { get; private set; }
  13. public double From { get; private set; }
  14. public double To { get; private set; }
  15. public string Text { get; private set; }
  16. public SubtitleBlock(int index, double from, double to, string text)
  17. {
  18. this.Index = index;
  19. this.From = from;
  20. this.To = to;
  21. this.Length = to - from;
  22. this.Text = text;
  23. }
  24. public override string ToString()
  25. {
  26. return "Index: " + Index + " From: " + From + " To: " + To + " Text: " + Text;
  27. }
  28. static public List<SubtitleBlock> ParseSubtitles(string content)
  29. {
  30. var subtitles = new List<SubtitleBlock>();
  31. //var regex = new Regex($@"(?<index>\d*\s*)\n(?<start>\d*:\d*:\d*,\d*)\s*-->\s*(?<end>\d*:\d*:\d*,\d*)\s*\n(?<content>.*)\n(?<content2>.*)\n");
  32. var regex = new Regex(@"(?<index>\d+)\r?\n(?<start>\d{2}:\d{2}:\d{2},\d{3}) --> (?<end>\d{2}:\d{2}:\d{2},\d{3})\r?\n(?<content>.*?)(\r?\n\r?\n|$)", RegexOptions.Singleline);
  33. var matches = regex.Matches(content);
  34. foreach (Match match in matches)
  35. {
  36. var groups = match.Groups;
  37. int ind = int.Parse(groups["index"].Value);
  38. TimeSpan fromtime, totime;
  39. TimeSpan.TryParse(groups["start"].Value.Replace(',', '.'), out fromtime);
  40. TimeSpan.TryParse(groups["end"].Value.Replace(',', '.'), out totime);
  41. string contenttext = groups["content"].Value;
  42. subtitles.Add(new SubtitleBlock(ind, fromtime.TotalSeconds, totime.TotalSeconds, contenttext));
  43. }
  44. return subtitles;
  45. }
  46. //public static List<SubtitleBlock> ParseSubtitles1(string srtFilePath)
  47. //{
  48. // List<SubtitleBlock> subtitles = new List<SubtitleBlock>();
  49. // string[] lines = File.ReadAllLines(srtFilePath);
  50. // for (int i = 0; i < lines.Length; i++)
  51. // {
  52. // var line = lines[i].Trim();
  53. // if (int.TryParse(line, out int index))
  54. // {
  55. // // 当前行是新字幕的索引,开始解析新的字幕
  56. // int tmpIndex = index;
  57. // i++; // 跳过空行
  58. // var timeStampLine = lines[i];
  59. // var match = TimeStampRegex.Match(timeStampLine);
  60. // if (match.Success)
  61. // {
  62. // Double From = TimeSpan.Parse(match.Groups["start"].Value).TotalSeconds;
  63. // Double To = TimeSpan.Parse(match.Groups["end"].Value).TotalSeconds;
  64. // }
  65. // i++; // 跳过时间戳行
  66. // while (i < lines.Length && !string.IsNullOrWhiteSpace(lines[i]))
  67. // {
  68. // // 添加字幕文本直到遇到下一个索引
  69. // string Text += lines[i++] + Environment.NewLine;
  70. // }
  71. // subtitles.Add(new SubtitleBlock(index,From,To,Text));
  72. // }
  73. // }
  74. // return subtitles;
  75. //}
  76. }
  77. public class Subtitle : MonoBehaviour
  78. {
  79. public float offset;
  80. List<SubtitleBlock> subt;
  81. public Text subtitletext;
  82. string subcontent;
  83. public TextAsset subTitleSource;
  84. void Start()
  85. {
  86. if (subTitleSource == null) return;
  87. subt = SubtitleBlock.ParseSubtitles(subTitleSource.text);
  88. offset = (float)subt[0].From;
  89. Play();
  90. }
  91. private void Play()
  92. {
  93. StartCoroutine(DisplaySubtitles());
  94. }
  95. public float localtimer;
  96. public IEnumerator DisplaySubtitles()
  97. {
  98. for (int j = 0; j < subt.Count; j++)
  99. {
  100. subt[j].ToString();
  101. var i = subt[j];
  102. subtitletext.text = "";
  103. if (i.From <= localtimer && i.To >= localtimer)
  104. {
  105. subtitletext.text = i.Text;
  106. yield return new WaitForSeconds((float)i.Length);
  107. }
  108. else if (i.From > localtimer)
  109. {
  110. yield return new WaitForSeconds(Mathf.Min((float)i.From - localtimer, 0.1f));
  111. j--;
  112. }
  113. }
  114. yield return null;
  115. }
  116. }