public static TextSubtitle ReadFile(string fileName) { TextSubtitle result = new TextSubtitle(); if (!File.Exists(fileName)) { Log.DebugFormat("File \"{0}\" doesn't exist. Aborting file import", fileName); return(result); } string lines; using (TextReader reader = File.OpenText(fileName)) { lines = reader.ReadToEnd(); } if (string.IsNullOrEmpty(lines)) { return(result); } List <string> textCaps = lines.Split(new[] { "\r\n\r\n", "\n\n" }, StringSplitOptions.RemoveEmptyEntries).ToList(); foreach (string textCap in textCaps) { string[] capLines = textCap.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); if (capLines.Length >= 3) { string[] timings = capLines[1].Split(new[] { " --> " }, StringSplitOptions.RemoveEmptyEntries); if (timings.Length >= 2) { SubCaption caption = new SubCaption { StartTime = DateTime.ParseExact(timings[0], "hh:mm:ss,fff", AppSettings.CInfo).TimeOfDay, EndTime = DateTime.ParseExact(timings[1], "hh:mm:ss,fff", AppSettings.CInfo).TimeOfDay, Text = string.Join(Environment.NewLine, capLines, 2, capLines.Length - 2), }; result.Captions.Add(caption); } } } result.SetDefaultStyle(); return(result); }
public static TextSubtitle ReadFile(string fileName) { TextSubtitle result = new TextSubtitle(); if (!File.Exists(fileName)) { Log.DebugFormat("File \"{0}\" doesn't exist. Aborting file import", fileName); return(result); } string lines; using (TextReader reader = File.OpenText(fileName)) { lines = reader.ReadToEnd(); } if (string.IsNullOrEmpty(lines)) { return(result); } List <string> textLines = lines.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries).ToList(); List <string> textCaps = new List <string>(); StringBuilder sb = new StringBuilder(); foreach (string line in textLines) { if (line.Trim().StartsWith("[")) { if (sb.Length > 0) { textCaps.Add(sb.ToString()); sb.Clear(); } sb.AppendLine(line.Trim()); } else { sb.AppendLine(line.Trim()); } } if (sb.Length > 0) { textCaps.Add(sb.ToString()); } sb.Clear(); //textCaps = lines.Split(new[] {"\r\n\r\n", "\n\n"}, StringSplitOptions.RemoveEmptyEntries).ToList(); if (!textCaps.Any()) { return(result); } string sInfo = textCaps[0]; if (!sInfo.Any()) { return(result); } sInfo = Regex.Replace(sInfo, "^;.*$|^Title.*$", "", RegexOptions.Multiline); bool isAdvancedScript = false; try { Match matchAdvanced = Regex.Match(sInfo, @"^\[Script Info\].*ScriptType: v4\.00+.*$", RegexOptions.Singleline | RegexOptions.Multiline); Match matchResults = Regex.Match(sInfo, @"^\[Script Info\].*ScriptType: v4\.00.*$", RegexOptions.Singleline | RegexOptions.Multiline); if (!matchResults.Success && !matchAdvanced.Success) { return(result); } if (matchAdvanced.Success) { isAdvancedScript = true; } } catch (ArgumentException ex) { Log.Error(ex); } bool setFormat = false; for (int i = 1; i <= textCaps.Count - 1; i++) { string section = textCaps[i]; try { Match matchStyles = Regex.Match(section, @"^\[V4.*Styles\].*$", RegexOptions.Multiline); Match matchEvents = Regex.Match(section, @"^\[Events\].*$", RegexOptions.Multiline); if (matchStyles.Success && !setFormat) { string[] styles = section.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); if (styles.Length < 3) { return(result); } List <String> formatAttribs = styles[1].Split(new[] { "," }, StringSplitOptions.None).ToList(); List <String> formatValues = styles[2].Split(new[] { "," }, StringSplitOptions.None).ToList(); for (int index = 0; index <= formatAttribs.Count - 1; index++) { string formatAttrib = formatAttribs[index].Trim(); string formatValue = formatValues[index].Trim(); switch (formatAttrib) { case "Fontname": result.Style.FontName = formatValue; break; case "Fontsize": result.Style.FontSize = int.Parse(formatValue, NumberStyles.Integer); break; case "PrimaryColour": result.Style.PrimaryColor = GetCorrectColor(formatValue); break; case "SecondaryColour": result.Style.SecondaryColor = GetCorrectColor(formatValue); break; case "TertiaryColour": case "OutlineColour": result.Style.OutlineColor = GetCorrectColor(formatValue); break; case "BackColour": result.Style.BackColor = GetCorrectColor(formatValue); break; case "Bold": result.Style.Bold = formatValue == "-1"; break; case "Italic": result.Style.Italic = formatValue == "-1"; break; case "Underline": result.Style.Underline = formatValue == "-1"; break; case "StrikeOut": result.Style.StrikeThrough = formatValue == "-1"; break; case "BorderStyle": result.Style.BorderStyle = int.Parse(formatValue, NumberStyles.Integer); break; case "Outline": result.Style.Outline = int.Parse(formatValue, NumberStyles.Integer); break; case "Shadow": result.Style.Shadow = int.Parse(formatValue, NumberStyles.Integer); break; case "Alignment": result.Style.Alignment = GetAlignment(formatValue, isAdvancedScript); break; case "MarginL": result.Style.MarginL = int.Parse(formatValue, NumberStyles.Integer); break; case "MarginR": result.Style.MarginR = int.Parse(formatValue, NumberStyles.Integer); break; case "MarginV": result.Style.MarginV = int.Parse(formatValue, NumberStyles.Integer); break; case "Alphalevel": result.Style.AlphaLevel = int.Parse(formatValue, NumberStyles.Integer); break; case "Encoding": result.Style.Encoding = formatValue; break; } } setFormat = true; } else if (matchEvents.Success) { string[] events = section.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); if (events.Length < 2) { return(result); } List <String> eventFormat = events[1].Split(new[] { "," }, StringSplitOptions.None).ToList(); int startTimeRow = -1, endTimeRow = -1, textRow = -1; for (int j = 0; j <= eventFormat.Count - 1; j++) { string label = eventFormat[j].Trim(); if (label.Equals("Start")) { startTimeRow = j; } else if (label.Equals("End")) { endTimeRow = j; } else if (label.Equals("Text")) { textRow = j; } } if (startTimeRow < 0 || endTimeRow < 0 || textRow < 0) { return(result); } for (int j = 2; j <= events.Length - 1; j++) { string eventLine = events[j]; string[] eventRows = eventLine.Split(new[] { "," }, StringSplitOptions.None); if (eventRows.Length < textRow + 1) { continue; } TimeSpan startTime = DateTime.ParseExact(eventRows[startTimeRow].Trim(), "h:mm:ss.ff", AppSettings.CInfo). TimeOfDay; TimeSpan endTime = DateTime.ParseExact(eventRows[endTimeRow].Trim(), "h:mm:ss.ff", AppSettings.CInfo). TimeOfDay; string text = string.Join(", ", eventRows, textRow, eventRows.Length - textRow); // line break text = Regex.Replace(text, @"(?:\\N|\\n)", Environment.NewLine, RegexOptions.Multiline); // remove line break strategy text = Regex.Replace(text, @"\\q\d*?", string.Empty, RegexOptions.Multiline); // bold text text = Regex.Replace(text, @"\{\\b1\}(.*?)\{\\b0*?\}", "<b>$1</b>", RegexOptions.Singleline | RegexOptions.Multiline); // italic text text = Regex.Replace(text, @"\{\\i1\}(.*?)\{\\i0*?\}", "<i>$1</i>", RegexOptions.Singleline | RegexOptions.Multiline); // underlined text text = Regex.Replace(text, @"\{\\u1\}(.*?)\{\\u0*?\}", "<u>$1</u>", RegexOptions.Singleline | RegexOptions.Multiline); // strike-through text text = Regex.Replace(text, @"\{\\s1\}(.*?)\{\\s0*?\}", "<s>$1</s>", RegexOptions.Singleline | RegexOptions.Multiline); // remove border and shadow override text = Regex.Replace(text, @"\{\\(?:bord|shad)\d*?\}", string.Empty, RegexOptions.Multiline); // remove blurry text border text = Regex.Replace(text, @"\{\\be(?:1|0)\}", string.Empty, RegexOptions.Multiline); // remove fontname text = Regex.Replace(text, @"\{\\fn.*\}", string.Empty, RegexOptions.Multiline); // remove fontsize text = Regex.Replace(text, @"\{\\fs.*\}", string.Empty, RegexOptions.Multiline); // remove color definition text = Regex.Replace(text, @"\{\\\d?c&H.*&\}", string.Empty, RegexOptions.Multiline); // remove alpha definition text = Regex.Replace(text, @"\{\\\d?(?:a|alpha)&H.*&\}", string.Empty, RegexOptions.Multiline); // remove x/y text scaling text = Regex.Replace(text, @"\{\\(?:fscy|fscx)\d+\}", string.Empty, RegexOptions.Multiline); // remove text spacing text = Regex.Replace(text, @"\{\\fsp\d+\}", string.Empty, RegexOptions.Multiline); // remove charset definition text = Regex.Replace(text, @"\{\\fe.*?\}", string.Empty, RegexOptions.Multiline); // parse and remove text alignment Regex align = new Regex(@"\{\\an*?(\d*?)\}", RegexOptions.Multiline); int alignment = GetAlignment(align.Match(text).Value, isAdvancedScript); text = align.Replace(text, string.Empty); // remove x/y/z text rotation text = Regex.Replace(text, @"\{\\fr(?:x|y|z)??(-??\d*?)\}", string.Empty, RegexOptions.Multiline); // remove karaoke formatting text = Regex.Replace(text, @"\{\\(?:k|ko|kf|K)(\d*?)\}", string.Empty, RegexOptions.Multiline); // remove format reset text = Regex.Replace(text, @"\{\\r.*\}", string.Empty, RegexOptions.Multiline); // remove text animation text = Regex.Replace(text, @"\{\\(?:move|pos|t|org|fad|fade|clip)\(.*?\)\}", string.Empty, RegexOptions.Multiline); // remove anything that was not catched above text = Regex.Replace(text, @"\{(?:\\(?:fscy|fscx)\d+|\\fn.*|\\fs.*|\\\d?c&H.*&|\\\d?(?:a|alpha)&H.*&|\\(?:fscy|fscx)\d+|" + @"\\fsp\d+|\\fe.*?|\\an*?(\d*?)|\\fr(?:x|y|z)??(-??\d*?)|\\(?:k|ko|kf|K)(\d*?)|\\r.*|" + @"\\(?:move|pos|t|org|fad|fade|clip)\(.*?\)\\N|\\n|\\q\d*?|\\(?:b|i|u|s|be)(?:1|0)*?|\\(?:bord|shad)\d*?)*?\}", string.Empty, RegexOptions.Multiline); SubCaption caption = new SubCaption { StartTime = startTime, EndTime = endTime, Text = text, Alignment = alignment }; result.Captions.Add(caption); } } } catch (ArgumentException ex) { Log.Error(ex); } } if (!setFormat) { result.SetDefaultStyle(); } return(result); }
public static ImageHolder CreateImage(SubCaption caption, SubtitleStyle style, int number, int videoWidth, int videoHeight, string baseFName) { _boldStyle = false; _italicStyle = false; _underlineStyle = false; _strikeStyle = false; ImageHolder result = new ImageHolder(); if (string.IsNullOrEmpty(baseFName)) return new ImageHolder(); string basePath = Path.GetDirectoryName(baseFName); string baseName = Path.GetFileNameWithoutExtension(baseFName); if (string.IsNullOrEmpty(basePath) || string.IsNullOrEmpty(baseName)) return new ImageHolder(); result.FileName = string.Format(AppSettings.CInfo, "{0}_{1:g}.png", Path.Combine(basePath, baseName), number); SizeF imgSize = new SizeF(); FontStyle styleFontStyle = FontStyle.Regular; if (style.Bold) styleFontStyle = styleFontStyle | FontStyle.Bold; if (style.Italic) styleFontStyle = styleFontStyle | FontStyle.Italic; Font styleFont = new Font(style.FontName, style.FontSize, styleFontStyle, GraphicsUnit.Point); StringFormat stringFormat = new StringFormat(); List<SizeF> lineSizes = new List<SizeF>(); string rawText = Regex.Replace(caption.Text, "</*?(?:i|b)>", "", RegexOptions.Singleline | RegexOptions.Multiline); string[] rawTextLines = rawText.Split(new[] {Environment.NewLine}, StringSplitOptions.None); foreach (string rawTextLine in rawTextLines) { using (GraphicsPath rawLinePath = new GraphicsPath()) { rawLinePath.AddString(rawTextLine, styleFont.FontFamily, (int) styleFontStyle, styleFont.SizeInPoints, new PointF(), stringFormat); lineSizes.Add(rawLinePath.GetBounds().Size); } } string[] textLines = caption.Text.Split(new[] { Environment.NewLine }, StringSplitOptions.None); float lastLineBreak = 0f; foreach (SizeF lineSize in lineSizes) { imgSize.Height += lineSize.Height; lastLineBreak = lineSize.Height/3; imgSize.Height += lastLineBreak; if (lineSize.Width > imgSize.Width) imgSize.Width = lineSize.Width; } imgSize.Height -= lastLineBreak; if (imgSize.IsEmpty) return new ImageHolder(); stringFormat.SetMeasurableCharacterRanges(new[] { new CharacterRange(0, 1) }); RectangleF whiteSpace; using (Image img = new Bitmap((int)imgSize.Width, (int)imgSize.Height, PixelFormat.Format32bppArgb)) { using (Graphics g = Graphics.FromImage(img)) { RectangleF origin = new RectangleF(new PointF(0f,0f), imgSize); Region[] regions2 = g.MeasureCharacterRanges(" .", styleFont, origin, stringFormat); if (!regions2.Any()) return new ImageHolder(); whiteSpace = regions2[0].GetBounds(g); } } GraphicsPath wordpath = new GraphicsPath(); GraphicsPath wordPathShadow = new GraphicsPath(); int shadowOffset = style.Shadow; RectangleF wStart = new RectangleF { Y = 0, X = 0 }; RectangleF wStartShadow = wStart; wStartShadow.Offset(shadowOffset, shadowOffset); for (int i = 0; i < textLines.Length; i++) { string textLine = textLines[i]; SizeF lineSize = lineSizes[i]; wStart.Offset(imgSize.Width / 2 - lineSize.Width / 2, 0); wStartShadow.Offset(imgSize.Width / 2 - lineSize.Width / 2, 0); string[] words = textLine.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries); foreach (string word in words) { using (GraphicsPath singleWord = new GraphicsPath(), singleWordShadow = new GraphicsPath()) { string lWord; FontStyle fontStyle = GetStyleFont(word, out lWord, styleFontStyle); if (string.IsNullOrEmpty(lWord)) continue; singleWord.AddString(lWord, styleFont.FontFamily, (int) fontStyle, styleFont.SizeInPoints, wStart.Location, stringFormat); singleWordShadow.AddString(lWord, styleFont.FontFamily, (int) fontStyle, styleFont.SizeInPoints, wStartShadow.Location, stringFormat); wordpath.AddPath(singleWord, false); wordPathShadow.AddPath(singleWordShadow, false); wStart.Offset(singleWord.GetBounds().Size.Width + whiteSpace.Size.Width, 0); wStartShadow.Offset(singleWordShadow.GetBounds().Size.Width + whiteSpace.Size.Width, 0); } } wStart.X = 0; wStart.Offset(0, lineSize.Height + lineSize.Height / 3); wStartShadow.X = shadowOffset; wStartShadow.Offset(0, lineSize.Height + lineSize.Height / 3); } imgSize.Width = wordPathShadow.GetBounds().Right; imgSize.Height = wordPathShadow.GetBounds().Bottom; using (Image img = new Bitmap((int)imgSize.Width + style.MarginL + style.MarginR, (int)imgSize.Height + style.MarginV * 2, PixelFormat.Format32bppArgb)) { using (Graphics g = Graphics.FromImage(img)) { g.CompositingMode = CompositingMode.SourceOver; g.CompositingQuality = CompositingQuality.HighQuality; g.TextRenderingHint = TextRenderingHint.AntiAlias; g.SmoothingMode = SmoothingMode.HighQuality; g.PixelOffsetMode = PixelOffsetMode.HighQuality; g.InterpolationMode = InterpolationMode.High; Brush primBrush = new SolidBrush(style.PrimaryColor); Brush shadowBrush = new SolidBrush(Color.FromArgb(64, style.BackColor)); Pen outPen = new Pen(style.OutlineColor) {Alignment = PenAlignment.Outset}; if (style.BorderStyle == 1) { outPen.Width = style.Outline == 0 && style.Shadow > 0 ? 1 : style.Outline; style.Outline = (int) outPen.Width; } g.FillRectangle(Brushes.Transparent, 0, 0, img.Width, img.Height); // draw shadow if (style.BorderStyle == 1 && style.Shadow > 0) g.FillPath(shadowBrush, wordPathShadow); g.FillPath(primBrush, wordpath); // draw outline if (style.BorderStyle == 1 && style.Outline > 0) g.DrawPath(outPen, wordpath); } img.Save(result.FileName, ImageFormat.Png); result.FileName = Path.GetFileName(result.FileName); result.Height = img.Height; result.Width = img.Width; } return result; }
public static ImageHolder CreateImage(SubCaption caption, SubtitleStyle style, int number, int videoWidth, int videoHeight, string baseFName) { _boldStyle = false; _italicStyle = false; _underlineStyle = false; _strikeStyle = false; ImageHolder result = new ImageHolder(); if (string.IsNullOrEmpty(baseFName)) { return(new ImageHolder()); } string basePath = Path.GetDirectoryName(baseFName); string baseName = Path.GetFileNameWithoutExtension(baseFName); if (string.IsNullOrEmpty(basePath) || string.IsNullOrEmpty(baseName)) { return(new ImageHolder()); } result.FileName = string.Format(AppSettings.CInfo, "{0}_{1:g}.png", Path.Combine(basePath, baseName), number); SizeF imgSize = new SizeF(); FontStyle styleFontStyle = FontStyle.Regular; if (style.Bold) { styleFontStyle = styleFontStyle | FontStyle.Bold; } if (style.Italic) { styleFontStyle = styleFontStyle | FontStyle.Italic; } Font styleFont = new Font(style.FontName, style.FontSize, styleFontStyle, GraphicsUnit.Point); StringFormat stringFormat = new StringFormat(); List <SizeF> lineSizes = new List <SizeF>(); string rawText = Regex.Replace(caption.Text, "</*?(?:i|b)>", "", RegexOptions.Singleline | RegexOptions.Multiline); string[] rawTextLines = rawText.Split(new[] { Environment.NewLine }, StringSplitOptions.None); foreach (string rawTextLine in rawTextLines) { using (GraphicsPath rawLinePath = new GraphicsPath()) { rawLinePath.AddString(rawTextLine, styleFont.FontFamily, (int)styleFontStyle, styleFont.SizeInPoints, new PointF(), stringFormat); lineSizes.Add(rawLinePath.GetBounds().Size); } } string[] textLines = caption.Text.Split(new[] { Environment.NewLine }, StringSplitOptions.None); float lastLineBreak = 0f; foreach (SizeF lineSize in lineSizes) { imgSize.Height += lineSize.Height; lastLineBreak = lineSize.Height / 3; imgSize.Height += lastLineBreak; if (lineSize.Width > imgSize.Width) { imgSize.Width = lineSize.Width; } } imgSize.Height -= lastLineBreak; if (imgSize.IsEmpty) { return(new ImageHolder()); } stringFormat.SetMeasurableCharacterRanges(new[] { new CharacterRange(0, 1) }); RectangleF whiteSpace; using (Image img = new Bitmap((int)imgSize.Width, (int)imgSize.Height, PixelFormat.Format32bppArgb)) { using (Graphics g = Graphics.FromImage(img)) { RectangleF origin = new RectangleF(new PointF(0f, 0f), imgSize); Region[] regions2 = g.MeasureCharacterRanges(" .", styleFont, origin, stringFormat); if (!regions2.Any()) { return(new ImageHolder()); } whiteSpace = regions2[0].GetBounds(g); } } GraphicsPath wordpath = new GraphicsPath(); GraphicsPath wordPathShadow = new GraphicsPath(); int shadowOffset = style.Shadow; RectangleF wStart = new RectangleF { Y = 0, X = 0 }; RectangleF wStartShadow = wStart; wStartShadow.Offset(shadowOffset, shadowOffset); for (int i = 0; i < textLines.Length; i++) { string textLine = textLines[i]; SizeF lineSize = lineSizes[i]; wStart.Offset(imgSize.Width / 2 - lineSize.Width / 2, 0); wStartShadow.Offset(imgSize.Width / 2 - lineSize.Width / 2, 0); string[] words = textLine.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries); foreach (string word in words) { using (GraphicsPath singleWord = new GraphicsPath(), singleWordShadow = new GraphicsPath()) { string lWord; FontStyle fontStyle = GetStyleFont(word, out lWord, styleFontStyle); if (string.IsNullOrEmpty(lWord)) { continue; } singleWord.AddString(lWord, styleFont.FontFamily, (int)fontStyle, styleFont.SizeInPoints, wStart.Location, stringFormat); singleWordShadow.AddString(lWord, styleFont.FontFamily, (int)fontStyle, styleFont.SizeInPoints, wStartShadow.Location, stringFormat); wordpath.AddPath(singleWord, false); wordPathShadow.AddPath(singleWordShadow, false); wStart.Offset(singleWord.GetBounds().Size.Width + whiteSpace.Size.Width, 0); wStartShadow.Offset(singleWordShadow.GetBounds().Size.Width + whiteSpace.Size.Width, 0); } } wStart.X = 0; wStart.Offset(0, lineSize.Height + lineSize.Height / 3); wStartShadow.X = shadowOffset; wStartShadow.Offset(0, lineSize.Height + lineSize.Height / 3); } imgSize.Width = wordPathShadow.GetBounds().Right; imgSize.Height = wordPathShadow.GetBounds().Bottom; using (Image img = new Bitmap((int)imgSize.Width + style.MarginL + style.MarginR, (int)imgSize.Height + style.MarginV * 2, PixelFormat.Format32bppArgb)) { using (Graphics g = Graphics.FromImage(img)) { g.CompositingMode = CompositingMode.SourceOver; g.CompositingQuality = CompositingQuality.HighQuality; g.TextRenderingHint = TextRenderingHint.AntiAlias; g.SmoothingMode = SmoothingMode.HighQuality; g.PixelOffsetMode = PixelOffsetMode.HighQuality; g.InterpolationMode = InterpolationMode.High; Brush primBrush = new SolidBrush(style.PrimaryColor); Brush shadowBrush = new SolidBrush(Color.FromArgb(64, style.BackColor)); Pen outPen = new Pen(style.OutlineColor) { Alignment = PenAlignment.Outset }; if (style.BorderStyle == 1) { outPen.Width = style.Outline == 0 && style.Shadow > 0 ? 1 : style.Outline; style.Outline = (int)outPen.Width; } g.FillRectangle(Brushes.Transparent, 0, 0, img.Width, img.Height); // draw shadow if (style.BorderStyle == 1 && style.Shadow > 0) { g.FillPath(shadowBrush, wordPathShadow); } g.FillPath(primBrush, wordpath); // draw outline if (style.BorderStyle == 1 && style.Outline > 0) { g.DrawPath(outPen, wordpath); } } img.Save(result.FileName, ImageFormat.Png); result.FileName = Path.GetFileName(result.FileName); result.Height = img.Height; result.Width = img.Width; } return(result); }
public static TextSubtitle ReadFile(string fileName) { TextSubtitle result = new TextSubtitle(); if (!File.Exists(fileName)) { Log.DebugFormat("File \"{0}\" doesn't exist. Aborting file import", fileName); return result; } string lines; using (TextReader reader = File.OpenText(fileName)) { lines = reader.ReadToEnd(); } if (string.IsNullOrEmpty(lines)) return result; List<string> textCaps = lines.Split(new[] {"\r\n\r\n", "\n\n"}, StringSplitOptions.RemoveEmptyEntries).ToList(); if (!textCaps.Any()) return result; string sInfo = textCaps[0]; if (!sInfo.Any()) return result; bool isAdvancedScript = false; try { Match matchAdvanced = Regex.Match(sInfo, @"^\[Script Info\].*ScriptType: v4\.00+.*$", RegexOptions.Singleline | RegexOptions.Multiline); Match matchResults = Regex.Match(sInfo, @"^\[Script Info\].*ScriptType: v4\.00.*$", RegexOptions.Singleline | RegexOptions.Multiline); if (!matchResults.Success && !matchAdvanced.Success) { return result; } if (matchAdvanced.Success) isAdvancedScript = true; } catch (ArgumentException ex) { Log.Error(ex); } bool setFormat = false; for (int i = 1; i <= textCaps.Count - 1; i++ ) { string section = textCaps[i]; try { Match matchStyles = Regex.Match(section, @"^\[V4.*Styles\].*$", RegexOptions.Multiline); Match matchEvents = Regex.Match(section, @"^\[Events\].*$", RegexOptions.Multiline); if (matchStyles.Success && !setFormat) { string[] styles = section.Split(new[] {"\r\n", "\n"}, StringSplitOptions.RemoveEmptyEntries); if (styles.Length < 3) return result; List<String> formatAttribs = styles[1].Split(new[] {","}, StringSplitOptions.None).ToList(); List<String> formatValues = styles[2].Split(new[] {","}, StringSplitOptions.None).ToList(); for (int index = 0; index <= formatAttribs.Count - 1; index++) { string formatAttrib = formatAttribs[index].Trim(); string formatValue = formatValues[index].Trim(); switch (formatAttrib) { case "Fontname": result.Style.FontName = formatValue; break; case "Fontsize": result.Style.FontSize = int.Parse(formatValue, NumberStyles.Integer); break; case "PrimaryColour": result.Style.PrimaryColor = GetCorrectColor(formatValue); break; case "SecondaryColour": result.Style.SecondaryColor = GetCorrectColor(formatValue); break; case "TertiaryColour": case "OutlineColour": result.Style.OutlineColor = GetCorrectColor(formatValue); break; case "BackColour": result.Style.BackColor = GetCorrectColor(formatValue); break; case "Bold": result.Style.Bold = formatValue == "-1"; break; case "Italic": result.Style.Italic = formatValue == "-1"; break; case "Underline": result.Style.Underline = formatValue == "-1"; break; case "StrikeOut": result.Style.StrikeThrough = formatValue == "-1"; break; case "BorderStyle": result.Style.BorderStyle = int.Parse(formatValue, NumberStyles.Integer); break; case "Outline": result.Style.Outline = int.Parse(formatValue, NumberStyles.Integer); break; case "Shadow": result.Style.Shadow = int.Parse(formatValue, NumberStyles.Integer); break; case "Alignment": result.Style.Alignment = GetAlignment(formatValue, isAdvancedScript); break; case "MarginL": result.Style.MarginL = int.Parse(formatValue, NumberStyles.Integer); break; case "MarginR": result.Style.MarginR = int.Parse(formatValue, NumberStyles.Integer); break; case "MarginV": result.Style.MarginV = int.Parse(formatValue, NumberStyles.Integer); break; case "Alphalevel": result.Style.AlphaLevel = int.Parse(formatValue, NumberStyles.Integer); break; case "Encoding": result.Style.Encoding = formatValue; break; } } setFormat = true; } else if (matchEvents.Success) { string[] events = section.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); if (events.Length < 2) return result; List<String> eventFormat = events[1].Split(new[] { "," }, StringSplitOptions.None).ToList(); int startTimeRow = -1, endTimeRow = -1, textRow = -1; for (int j = 0; j <= eventFormat.Count - 1; j++) { string label = eventFormat[j].Trim(); if (label.Equals("Start")) startTimeRow = j; else if (label.Equals("End")) endTimeRow = j; else if (label.Equals("Text")) textRow = j; } if (startTimeRow < 0 || endTimeRow < 0 || textRow < 0) return result; for (int j = 2; j <= events.Length - 1; j++) { string eventLine = events[j]; string[] eventRows = eventLine.Split(new[] {","}, StringSplitOptions.None); if (eventRows.Length < textRow + 1) continue; TimeSpan startTime = DateTime.ParseExact(eventRows[startTimeRow].Trim(), "h:mm:ss.ff", AppSettings.CInfo). TimeOfDay; TimeSpan endTime = DateTime.ParseExact(eventRows[endTimeRow].Trim(), "h:mm:ss.ff", AppSettings.CInfo). TimeOfDay; string text = string.Join(", ", eventRows, textRow, eventRows.Length - textRow); // line break text = Regex.Replace(text, @"(?:\\N|\\n)", Environment.NewLine, RegexOptions.Multiline); // remove line break strategy text = Regex.Replace(text, @"\\q\d*?", string.Empty, RegexOptions.Multiline); // bold text text = Regex.Replace(text, @"\{\\b1\}(.*?)\{\\b0*?\}", "<b>$1</b>", RegexOptions.Singleline | RegexOptions.Multiline); // italic text text = Regex.Replace(text, @"\{\\i1\}(.*?)\{\\i0*?\}", "<i>$1</i>", RegexOptions.Singleline | RegexOptions.Multiline); // underlined text text = Regex.Replace(text, @"\{\\u1\}(.*?)\{\\u0*?\}", "<u>$1</u>", RegexOptions.Singleline | RegexOptions.Multiline); // strike-through text text = Regex.Replace(text, @"\{\\s1\}(.*?)\{\\s0*?\}", "<s>$1</s>", RegexOptions.Singleline | RegexOptions.Multiline); // remove border and shadow override text = Regex.Replace(text, @"\{\\(?:bord|shad)\d*?\}", string.Empty, RegexOptions.Multiline); // remove blurry text border text = Regex.Replace(text, @"\{\\be(?:1|0)\}", string.Empty, RegexOptions.Multiline); // remove fontname text = Regex.Replace(text, @"\{\\fn.*\}", string.Empty, RegexOptions.Multiline); // remove fontsize text = Regex.Replace(text, @"\{\\fs.*\}", string.Empty, RegexOptions.Multiline); // remove color definition text = Regex.Replace(text, @"\{\\\d?c&H.*&\}", string.Empty, RegexOptions.Multiline); // remove alpha definition text = Regex.Replace(text, @"\{\\\d?(?:a|alpha)&H.*&\}", string.Empty, RegexOptions.Multiline); // remove x/y text scaling text = Regex.Replace(text, @"\{\\(?:fscy|fscx)\d+\}", string.Empty, RegexOptions.Multiline); // remove text spacing text = Regex.Replace(text, @"\{\\fsp\d+\}", string.Empty, RegexOptions.Multiline); // remove charset definition text = Regex.Replace(text, @"\{\\fe.*?\}", string.Empty, RegexOptions.Multiline); // parse and remove text alignment Regex align = new Regex(@"\{\\an*?(\d*?)\}", RegexOptions.Multiline); int alignment = GetAlignment(align.Match(text).Value, isAdvancedScript); text = align.Replace(text, string.Empty); // remove x/y/z text rotation text = Regex.Replace(text, @"\{\\fr(?:x|y|z)??(-??\d*?)\}", string.Empty, RegexOptions.Multiline); // remove karaoke formatting text = Regex.Replace(text, @"\{\\(?:k|ko|kf|K)(\d*?)\}", string.Empty, RegexOptions.Multiline); // remove format reset text = Regex.Replace(text, @"\{\\r.*\}", string.Empty, RegexOptions.Multiline); // remove text animation text = Regex.Replace(text, @"\{\\(?:move|pos|t|org|fad|fade|clip)\(.*?\)\}", string.Empty, RegexOptions.Multiline); // remove anything that was not catched above text = Regex.Replace(text, @"\{(?:\\(?:fscy|fscx)\d+|\\fn.*|\\fs.*|\\\d?c&H.*&|\\\d?(?:a|alpha)&H.*&|\\(?:fscy|fscx)\d+|" + @"\\fsp\d+|\\fe.*?|\\an*?(\d*?)|\\fr(?:x|y|z)??(-??\d*?)|\\(?:k|ko|kf|K)(\d*?)|\\r.*|" + @"\\(?:move|pos|t|org|fad|fade|clip)\(.*?\)\\N|\\n|\\q\d*?|\\(?:b|i|u|s|be)(?:1|0)*?|\\(?:bord|shad)\d*?)*?\}", string.Empty, RegexOptions.Multiline); SubCaption caption = new SubCaption { StartTime = startTime, EndTime = endTime, Text = text, Alignment = alignment }; result.Captions.Add(caption); } } } catch (ArgumentException ex) { Log.Error(ex); } } if (!setFormat) { result.SetDefaultStyle(); } return result; }