/// <summary> /// Utility method to write style block into a buffer. /// </summary> /// <param name="style">Style block to write.</param> /// <param name="builder">String builder buffer to write into.</param> private static void WrteStyle( Style style, StringBuilder builder) { if (false == string.IsNullOrWhiteSpace(style.RawContent)) { if (style.RawContent.Contains(Constants.ArrowToken)) { throw new ArgumentException(string.Format("Style cannot contain '{0}'.", Constants.ArrowToken)); } builder.AppendLine(); builder.Append(Constants.StyleToken); if (style.RawContent.IndexOfAny(WebVttSerializer.newLine) >= 0) { builder.AppendLine(); WebVttSerializer.WriteString(style.RawContent.TrimEnd(WebVttSerializer.newLine), false, builder); } else { builder.Append(" "); builder.Append(style.RawContent); } builder.AppendLine(); } }
/// <summary> /// Writes captions into a text in WebVTT format. /// </summary> /// <param name="captions">Caption blocks to serialize.</param> /// <param name="writer">Text writer to write into.</param> /// <remarks>See http://www.w3.org/TR/webvtt1/ for more details.</remarks> public static Task SerializeAsync( MediaCaptions captions, TextWriter writer) { return(WebVttSerializer.SerializeAsync( WebVttSerializer.GetMediaCaptionBlocks(captions), writer)); }
/// <summary> /// Utility method to write region definition block into a buffer. /// </summary> /// <param name="region">Region definition to write.</param> /// <param name="builder">String builder buffer to write into.</param> private static void WriteRegion( RegionDefinition region, StringBuilder builder) { builder.AppendLine(); builder.AppendLine(Constants.RegionToken); if (false == string.IsNullOrWhiteSpace(region.Id)) { builder.Append(Constants.RegionIdName).Append(":"); WebVttSerializer.WriteString(region.Id, true, builder); builder.AppendLine(); } if (region.Lines.HasValue && region.Lines.Value >= 0) { builder.Append(Constants.LinesName).Append(":").AppendLine(region.Lines.Value.ToString()); } if (region.WidthPercent.HasValue) { builder .Append(Constants.WidthName) .Append(":") .AppendLine(WebVttSerializer.GetPercentValue(region.WidthPercent.Value)); } if (region.RegionAnchor.HasValue) { builder .Append(Constants.RegionAnchorName).Append(":") .Append(WebVttSerializer.GetPercentValue(region.RegionAnchor.Value.XPercent)) .Append(',') .AppendLine(WebVttSerializer.GetPercentValue(region.RegionAnchor.Value.YPercent)); } if (region.ViewPortAnchor.HasValue) { builder .Append(Constants.ViewPortAnchorName).Append(":") .Append(WebVttSerializer.GetPercentValue(region.ViewPortAnchor.Value.XPercent)) .Append(',') .AppendLine(WebVttSerializer.GetPercentValue(region.ViewPortAnchor.Value.YPercent)); } if (region.Scroll.HasValue && region.Scroll.Value) { builder.Append(Constants.ScrollName).Append(':').AppendLine(Constants.ScrollUpValue); } }
/// <summary> /// Utility method to write a single block into a buffer. /// </summary> /// <param name="block">Block to write.</param> /// <param name="builder">String builder buffer to write into.</param> private static void WriteBlock( BaseBlock block, StringBuilder builder) { Cue cue = block as Cue; if (cue != null) { WebVttSerializer.WriteCue(cue, builder); return; } RegionDefinition region = block as RegionDefinition; if (region != null) { WebVttSerializer.WriteRegion(region, builder); return; } Style style = block as Style; if (style != null) { WebVttSerializer.WrteStyle(style, builder); return; } Comment comment = block as Comment; if (comment != null) { WebVttSerializer.WriteComment(comment, builder); return; } throw new ArgumentOutOfRangeException( string.Format("Unknown block type '{0}'.", block.GetType().FullName)); }
/// <summary> /// Writes captions into a text in WebVTT format. /// </summary> /// <param name="captions">Caption blocks to serialize.</param> /// <param name="writer">Text writer to write into.</param> /// <remarks>See http://www.w3.org/TR/webvtt1/ for more details.</remarks> public static async Task SerializeAsync( IEnumerable <BaseBlock> captions, TextWriter writer) { if (writer == null) { throw new ArgumentNullException("writer"); } StringBuilder builder = new StringBuilder(1024); builder.AppendLine(Constants.WebVttHeaderToken); if (captions != null) { Cue lastSeenCue = null; foreach (var block in captions) { if (block == null) { throw new ArgumentException("Caption block cannot be null.", "captions"); } Cue cue = block as Cue; if (lastSeenCue != null) { if (block is RegionDefinition || block is Style) { throw new ArgumentException( string.Format("{0} is not allowed after Cue.", block.GetType().Name), "captions"); } if (cue != null && cue.Start < lastSeenCue.Start) { throw new ArgumentException( string.Format("Cue start time '{0}' must be greater than or equal to previous cue start time '{1}'.", cue.Start.ToString("g"), lastSeenCue.Start.ToString("g")), "captions"); } } if (cue != null) { lastSeenCue = cue; } WebVttSerializer.WriteBlock(block, builder); if (builder.Length >= WebVttSerializer.MaxBufferSize) { await writer.WriteAsync(builder.ToString()) .ConfigureAwait(false); builder.Clear(); } } } if (builder.Length > 0) { await writer.WriteAsync(builder.ToString()) .ConfigureAwait(false); } await writer.FlushAsync() .ConfigureAwait(false); }
/// <summary> /// Utility method to write a single cue span into a buffer. /// </summary> /// <param name="span">Cue span to write.</param> /// <param name="builder">String builder buffer to write into.</param> private static void WriteSpan( Span span, StringBuilder builder) { if (span.Type == SpanType.Text) { if (string.IsNullOrEmpty(span.Text)) { return; } if (span.Text.Contains(Constants.ArrowToken)) { throw new ArgumentException("Cue text cannot contain '{0}'.", Constants.ArrowToken); } WebVttSerializer.WriteString(span.Text, true, builder); return; } string tagName = WebVttSerializer.GetSpanTagName(span.Type); builder.Append('<').Append(tagName); if (span.Classes != null && span.Classes.Length > 0) { foreach (string cls in span.Classes) { if (false == string.IsNullOrWhiteSpace(cls)) { if (WebVttSerializer.HasWhiteSpace(cls)) { throw new ArgumentException("White space characters are not allowed in span class name."); } builder.Append('.').Append(cls); } } } if (false == string.IsNullOrWhiteSpace(span.Annotation)) { builder.Append(' '); WebVttSerializer.WriteString(span.Annotation, true, builder); } builder.Append('>'); if (span.Children != null && span.Children.Length > 0) { foreach (var child in span.Children) { if (child != null) { WebVttSerializer.WriteSpan(child, builder); } } } builder.Append("</").Append(tagName).Append('>'); }
/// <summary> /// Utility method to write a caption cue into a buffer. /// </summary> /// <param name="cue">Cue to write.</param> /// <param name="builder">String builder buffer to write into.</param> private static void WriteCue( Cue cue, StringBuilder builder) { if (cue.End <= cue.Start) { throw new ArgumentException(string.Format("Cue start time '{0}' must be less than cue end time '{1}'.", cue.Start, cue.End)); } builder.AppendLine(); if (false == string.IsNullOrWhiteSpace(cue.Id)) { builder.AppendLine(cue.Id); } WebVttSerializer.WriteTimeSpanValue(cue.Start, builder); builder .Append(' ') .Append(Constants.ArrowToken) .Append(' '); WebVttSerializer.WriteTimeSpanValue(cue.End, builder); if (false == string.IsNullOrWhiteSpace(cue.Region)) { if (WebVttSerializer.HasWhiteSpace(cue.Region)) { throw new ArgumentException("White space characters are not allowed in cue region id."); } builder .Append(' ') .Append(Constants.RegionName).Append(':').Append(cue.Region); } if (cue.Alignment.HasValue) { builder .Append(' ') .Append(Constants.AlignName).Append(':').Append(WebVttSerializer.GetAlignmentValue(cue.Alignment.Value)); } if (cue.Line.HasValue) { builder .Append(' ') .Append(Constants.LineName).Append(':'); if (cue.Line.Value.Percent.HasValue) { builder.Append(WebVttSerializer.GetPercentValue(cue.Line.Value.Percent.Value)); } else if (cue.Line.Value.LineNumber.HasValue) { builder.Append(cue.Line.Value.LineNumber.Value); } else { throw new ArgumentException("Cue line setting must specify either percent or line number value."); } if (cue.Line.Value.Alignment.HasValue) { builder.Append(',').Append(WebVttSerializer.GetLineAlignmentValue(cue.Line.Value.Alignment.Value)); } } if (cue.Position.HasValue) { builder .Append(' ') .Append(Constants.PositionName).Append(':') .Append(WebVttSerializer.GetPercentValue( cue.Position.Value.PositionPercent.HasValue ? cue.Position.Value.PositionPercent.Value : 0.0)); if (cue.Position.Value.Alignment.HasValue) { builder .Append(',') .Append(WebVttSerializer.GetPositionAlignmentValue(cue.Position.Value.Alignment.Value)); } } if (cue.SizePercent.HasValue) { builder .Append(' ') .Append(Constants.SizeName) .Append(":") .Append(WebVttSerializer.GetPercentValue(cue.SizePercent.Value)); } if (cue.Vertical.HasValue) { builder .Append(' ') .Append(Constants.VerticalName) .Append(":") .Append(WebVttSerializer.GetVerticalAlignmentValue(cue.Vertical.Value)); } builder.AppendLine(); if (cue.Content != null && cue.Content.Length > 0) { Span previousSpan = null; foreach (var span in cue.Content) { if (span == null) { throw new ArgumentException("Cue content cannot be null."); } if (WebVttSerializer.NeedNewLine(previousSpan, span)) { builder.AppendLine(); } WebVttSerializer.WriteSpan(span, builder); previousSpan = span; } builder.AppendLine(); } }