public List <KaraokeSegment> Parse(Stream stream) { if (!stream.CanRead) { throw new ArgumentException("Cannot read from stream"); } var words = new List <KaraokeSegment>(); KaraokeSegment currentItem = null; float lastParsedTime = -1; bool mustBreakLine = false; using (var reader = new StreamReader(stream, true)) { string nextLine; while ((nextLine = reader.ReadLine()) != null) { int currPosition = 0; while (currPosition < nextLine.Length) { TokenType type; object token; nextLine = nextLine.Substring(currPosition); currPosition = NextToken(nextLine, out type, out token); if (type == TokenType.Text) { if (currentItem != null) // multi-line { if (string.IsNullOrEmpty(currentItem.text.Trim())) { currentItem.text = (string)token; } else { currentItem.text = currentItem.text + " " + (string)token; } } else { if (lastParsedTime < 0) { throw new FormatException("Unable to parse: start time not specified"); } currentItem = new KaraokeSegment(); currentItem.start = lastParsedTime; currentItem.text = (string)token; if (mustBreakLine) { currentItem.starsWithLineBreak = true; mustBreakLine = false; } } } else if (type == TokenType.BreakLine) { mustBreakLine = true; } else if (type == TokenType.Time) { lastParsedTime = (float)token; if (currentItem != null) // completed { if (string.IsNullOrEmpty(currentItem.text.Trim())) { // skip if (currentItem.starsWithLineBreak) { mustBreakLine = true; } } else { currentItem.end = lastParsedTime; words.Add(currentItem); } currentItem = null; } } } } } return(words); }
public List <KaraokeSegment> Parse(Stream stream) { if (!stream.CanRead) { throw new ArgumentException("Cannot read from stream"); } var words = new List <KaraokeSegment>(); using (var reader = new StreamReader(stream, true)) { var parts = GetParts(reader); if (parts.Count > 0) { foreach (var p in parts) { var lines = p.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); var item = new KaraokeSegment(); bool parsedTime = false; for (int i = 0; i < lines.Length; ++i) { var line = lines[i]; line = line.Trim(); if (string.IsNullOrEmpty(line)) { continue; } if (!parsedTime) { float startTime; float endTime; if (TryParseTime(line, out startTime, out endTime)) { parsedTime = true; item.start = startTime; item.end = endTime; } } else { if (string.IsNullOrEmpty(item.text)) { item.text = line; } else { item.text = item.text + " " + line; } } } if (parsedTime && item.text != null) { words.Add(item); } } if (words.Count > 0) { return(words); } else { throw new ArgumentException("The song is empty"); } } else { throw new FormatException("Unable to parse VTT format."); } } }