예제 #1
0
        /// <summary>
        /// Reads WebVTT media captions from a given <see cref="TextReader"/>.
        /// </summary>
        /// <param name="reader">Text reader to read the captions.</param>
        /// <returns>A task that represents the asynchronous read operation.</returns>
        public static async Task <MediaCaptions> ReadMediaCaptionsAsync(
            TextReader reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }

            // Process stream header line
            var line = await reader.ReadLineAsync()
                       .ConfigureAwait(false);

            if (string.IsNullOrWhiteSpace(line) ||
                line.Length < 6 ||
                false == line.StartsWith(Constants.WebVttHeaderToken) ||
                line.Length >= 7 && line[6] != '\t' && line[6] != ' ')
            {
                throw new InvalidDataException("The stream does not start with the correct WebVTT file signature.");
            }

            var result = new MediaCaptions();

            // Process (skip over) optional headers from the stream
            while (false == string.IsNullOrEmpty(line))
            {
                line = await reader.ReadLineAsync()
                       .ConfigureAwait(false);
            }

            // Process media caption blocks.
            List <RegionDefinition> regions = new List <RegionDefinition>();
            List <Style>            styles  = new List <Style>();
            List <Cue> cues = new List <Cue>();

            BaseBlock block;

            do
            {
                block = await WebVttParser.ReadBlockAsync(reader)
                        .ConfigureAwait(false);

                RegionDefinition region = block as RegionDefinition;
                Style            style  = block as Style;
                Cue cue = block as Cue;

                if (cues.Count == 0)
                {
                    if (region != null)
                    {
                        regions.Add(region);
                    }
                    else if (style != null)
                    {
                        styles.Add(style);
                    }
                }
                else if (region != null || style != null)
                {
                    throw new InvalidDataException("Region or style blocks cannot be mixed with cue blocks.");
                }

                if (cue != null)
                {
                    cues.Add(cue);
                }
            }while (block != null);

            if (regions.Count > 0)
            {
                result.Regions = regions.ToArray();
            }

            if (styles.Count > 0)
            {
                result.Styles = styles.ToArray();
            }

            if (cues.Count > 0)
            {
                result.Cues = cues.ToArray();
            }

            return(result);
        }
예제 #2
0
        /// <summary>
        /// Reads WebVTT Region definition block from the stream.
        /// </summary>
        /// <param name="firstLine">First line of the block read from the reader.</param>
        /// <param name="reader">Text reader to read the region block.</param>
        /// <returns>A task that represents the asynchronous read operation.</returns>
        private static async Task <RegionDefinition> ReadRegionAsync(
            string firstLine,
            TextReader reader)
        {
            string line = firstLine;

            if (line.Length > Constants.RegionToken.Length &&
                false == string.IsNullOrWhiteSpace(line.Substring(Constants.RegionToken.Length)))
            {
                throw new InvalidDataException(string.Format("Invalid characters found after region definition header: {0}", line));
            }

            var content = new StringBuilder(100);

            while (false == string.IsNullOrEmpty(line))
            {
                line = await reader.ReadLineAsync()
                       .ConfigureAwait(false);

                if (false == string.IsNullOrEmpty(line))
                {
                    if (line.Contains(Constants.ArrowToken))
                    {
                        throw new InvalidDataException(string.Format("Region definition must not contain '{0}'.", Constants.ArrowToken));
                    }

                    content.SafeAppendLine(line);
                }
            }

            var result = new RegionDefinition()
            {
                RawContent = content.Length > 0 ? content.ToString() : null
            };

            if (result.RawContent != null)
            {
                var settings = WebVttParser.ParseSettings(result.RawContent);

                if (settings != null)
                {
                    string value;
                    if (WebVttParser.TryGetStringSetting(Constants.RegionIdName, settings, out value))
                    {
                        result.Id = value;
                    }

                    double percent;
                    if (WebVttParser.TryGetPercentSetting(Constants.WidthName, settings, out percent))
                    {
                        result.WidthPercent = percent;
                    }

                    Anchor anchor;
                    if (WebVttParser.TryGetAnchorSetting(Constants.RegionAnchorName, settings, out anchor))
                    {
                        result.RegionAnchor = anchor;
                    }

                    if (WebVttParser.TryGetAnchorSetting(Constants.ViewPortAnchorName, settings, out anchor))
                    {
                        result.ViewPortAnchor = anchor;
                    }

                    if (WebVttParser.TryGetStringSetting(Constants.ScrollName, settings, out value))
                    {
                        result.Scroll = string.Equals(value, Constants.ScrollUpValue, StringComparison.OrdinalIgnoreCase);
                    }

                    int lines;
                    if (WebVttParser.TryGetIntSetting(Constants.LinesName, settings, out lines))
                    {
                        result.Lines = lines;
                    }
                }
            }

            return(result);
        }