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);
        }
示例#2
0
        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.");
                }
            }
        }