public override string ToText(Subtitle subtitle, string title) { bool convertedFromSubStationAlpha = false; if (subtitle.Header != null) { XmlNode styleHead = null; try { var x = new XmlDocument(); x.LoadXml(subtitle.Header); var xnsmgr = new XmlNamespaceManager(x.NameTable); xnsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml"); if (x.DocumentElement != null) { styleHead = x.DocumentElement.SelectSingleNode("ttml:head", xnsmgr); } } catch { styleHead = null; } if (styleHead == null && (subtitle.Header.Contains("[V4+ Styles]") || subtitle.Header.Contains("[V4 Styles]"))) { var x = new XmlDocument(); x.LoadXml(new ItunesTimedText().ToText(new Subtitle(), "tt")); // load default xml var xnsmgr = new XmlNamespaceManager(x.NameTable); xnsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml"); if (x.DocumentElement != null) { styleHead = x.DocumentElement.SelectSingleNode("ttml:head", xnsmgr); styleHead.SelectSingleNode("ttml:styling", xnsmgr).RemoveAll(); foreach (string styleName in AdvancedSubStationAlpha.GetStylesFromHeader(subtitle.Header)) { try { var ssaStyle = AdvancedSubStationAlpha.GetSsaStyle(styleName, subtitle.Header); string fontStyle = "normal"; if (ssaStyle.Italic) { fontStyle = "italic"; } string fontWeight = "normal"; if (ssaStyle.Bold) { fontWeight = "bold"; } AddStyleToXml(x, styleHead, xnsmgr, ssaStyle.Name, ssaStyle.FontName, fontWeight, fontStyle, Utilities.ColorToHex(ssaStyle.Primary), ssaStyle.FontSize.ToString(CultureInfo.InvariantCulture)); convertedFromSubStationAlpha = true; } catch { // ignored } } } subtitle.Header = x.OuterXml; // save new xml with styles in header } } var xml = new XmlDocument { XmlResolver = null }; var nsmgr = new XmlNamespaceManager(xml.NameTable); nsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml"); nsmgr.AddNamespace("ttp", "http://www.w3.org/ns/10/ttml#parameter"); nsmgr.AddNamespace("tts", "http://www.w3.org/ns/10/ttml#style"); nsmgr.AddNamespace("ttm", "http://www.w3.org/ns/10/ttml#metadata"); nsmgr.AddNamespace("ttm", "http://www.w3.org/ns/10/ttml#metadata"); nsmgr.AddNamespace("smpte", "http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt"); nsmgr.AddNamespace("m608", "http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt#cea608"); var xmlStructure = @"<?xml version='1.0' encoding='utf-8'?> <tt xml:lang='[LANG]' xmlns='http://www.w3.org/ns/ttml' xmlns:tts='http://www.w3.org/ns/ttml#styling' xmlns:ttm='http://www.w3.org/ns/ttml#metadata' xmlns:ttp='http://www.w3.org/ns/ttml#parameter' ttp:timeBase='media' ttp:frameRate='24' ttp:frameRateMultiplier='1000 1001' xmlns:smpte='http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt' xmlns:m608='http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt#cea608'> <head> <metadata> <ttm:title>SMPTE-TT 2052 subtitle</ttm:title> <ttm:desc>SMPTE Timed Text document created by Subtitle Edit</ttm:desc> <smpte:information xmlns:m608='http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt#cea608' origin='http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt#cea608' mode='Preserved' m608:channel='CC1' m608:programName='Demo' m608:captionService='F1C1CC'/> </metadata> <styling> <style xml:id='basic' tts:color='white' tts:fontFamily='Arial' tts:backgroundColor='transparent' tts:fontSize='21' tts:fontWeight='normal' tts:fontStyle='normal' /> </styling> <layout> <region xml:id='bottom' tts:backgroundColor='transparent' tts:showBackground='whenActive' tts:origin='10% 55%' tts:extent='80% 80%' tts:displayAlign='after' /> <region xml:id='top' tts:backgroundColor='transparent' tts:showBackground='whenActive' tts:origin='10% 10%' tts:extent='80% 80%' tts:displayAlign='before' /> </layout> </head> <body> <div></div> </body> </tt>"; string frameRate = ((int)Math.Round(Configuration.Settings.General.CurrentFrameRate)).ToString(); string frameRateMultiplier = "1000 1001"; if (Configuration.Settings.General.CurrentFrameRate % 1.0 < 0.01) { frameRateMultiplier = "1 1"; } xmlStructure = xmlStructure.Replace("frameRate='24'", $"frameRate='{frameRate}'"); xmlStructure = xmlStructure.Replace("frameRateMultiplier='1000 1001'", $"frameRateMultiplier='{frameRateMultiplier}'"); var languageCode = LanguageAutoDetect.AutoDetectGoogleLanguage(subtitle); xml.LoadXml(xmlStructure.Replace("[LANG]", languageCode)); if (!string.IsNullOrWhiteSpace(title)) { var headNode = xml.DocumentElement.SelectSingleNode("//ttml:head", nsmgr); var metadataNode = headNode?.SelectSingleNode("ttml:metadata", nsmgr); var titleNode = metadataNode?.FirstChild; if (titleNode != null) { titleNode.InnerText = title; } } var div = xml.DocumentElement.SelectSingleNode("//ttml:body", nsmgr).SelectSingleNode("ttml:div", nsmgr); bool hasBottomCenterRegion = false; bool hasTopCenterRegion = false; foreach (XmlNode node in xml.DocumentElement.SelectNodes("//ttml:head/ttml:layout/ttml:region", nsmgr)) { string id = null; if (node.Attributes["xml:id"] != null) { id = node.Attributes["xml:id"].Value; } else if (node.Attributes["id"] != null) { id = node.Attributes["id"].Value; } if (id != null && id == "bottom") { hasBottomCenterRegion = true; } if (id != null && (id == "topCenter" || id == "top")) { hasTopCenterRegion = true; } } foreach (var p in subtitle.Paragraphs) { XmlNode paragraph = xml.CreateElement("p", "http://www.w3.org/ns/ttml"); string text = p.Text; XmlAttribute start = xml.CreateAttribute("begin"); start.InnerText = string.Format(CultureInfo.InvariantCulture, "{0:00}:{1:00}:{2:00}:{3:00}", p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, MillisecondsToFramesMaxFrameRate(p.StartTime.Milliseconds)); paragraph.Attributes.Append(start); XmlAttribute end = xml.CreateAttribute("end"); end.InnerText = string.Format(CultureInfo.InvariantCulture, "{0:00}:{1:00}:{2:00}:{3:00}", p.EndTime.Hours, p.EndTime.Minutes, p.EndTime.Seconds, MillisecondsToFramesMaxFrameRate(p.EndTime.Milliseconds)); paragraph.Attributes.Append(end); XmlAttribute style = xml.CreateAttribute("style"); style.InnerText = "basic"; paragraph.Attributes.Append(style); XmlAttribute textAlign = xml.CreateAttribute("textAlign"); textAlign.InnerText = "center"; paragraph.Attributes.Append(textAlign); XmlAttribute regionP = xml.CreateAttribute("region"); if (text.StartsWith("{\\an7}", StringComparison.Ordinal) || text.StartsWith("{\\an8}", StringComparison.Ordinal) || text.StartsWith("{\\an9}", StringComparison.Ordinal)) { if (hasTopCenterRegion) { regionP.InnerText = "top"; paragraph.Attributes.Append(regionP); } } else if (hasBottomCenterRegion) { regionP.InnerText = "bottom"; paragraph.Attributes.Append(regionP); } if (text.StartsWith("{\\an", StringComparison.Ordinal) && text.Length > 6 && text[5] == '}') { text = text.Remove(0, 6); } XmlAttribute styleAttribute = xml.CreateAttribute("style"); styleAttribute.InnerText = "basic"; paragraph.Attributes.Append(styleAttribute); if (convertedFromSubStationAlpha) { if (string.IsNullOrEmpty(p.Style)) { p.Style = p.Extra; } } bool first = true; bool italicOn = false; foreach (string line in Utilities.RemoveSsaTags(text).SplitToLines()) { if (!first) { XmlNode br = xml.CreateElement("br", "http://www.w3.org/ns/ttml"); paragraph.AppendChild(br); } var styles = new Stack <XmlNode>(); XmlNode currentStyle = xml.CreateTextNode(string.Empty); paragraph.AppendChild(currentStyle); int skipCount = 0; for (int i = 0; i < line.Length; i++) { if (skipCount > 0) { skipCount--; } else if (line.Substring(i).StartsWith("<i>", StringComparison.Ordinal)) { styles.Push(currentStyle); currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:fontStyle", "http://www.w3.org/ns/10/ttml#style"); attr.InnerText = "italic"; currentStyle.Attributes.Append(attr); skipCount = 2; italicOn = true; } else if (line.Substring(i).StartsWith("<b>", StringComparison.Ordinal)) { currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:fontWeight", "http://www.w3.org/ns/10/ttml#style"); attr.InnerText = "bold"; currentStyle.Attributes.Append(attr); skipCount = 2; } else if (line.Substring(i).StartsWith("<font ", StringComparison.Ordinal)) { int endIndex = line.Substring(i + 1).IndexOf('>'); if (endIndex > 0) { skipCount = endIndex + 1; string fontContent = line.Substring(i, skipCount); if (fontContent.Contains(" color=")) { var arr = fontContent.Substring(fontContent.IndexOf(" color=", StringComparison.Ordinal) + 7).Trim().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (arr.Length > 0) { string fontColor = arr[0].Trim('\'').Trim('"').Trim('\''); currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:color", "http://www.w3.org/ns/10/ttml#style"); attr.InnerText = fontColor; currentStyle.Attributes.Append(attr); } } } else { skipCount = line.Length; } } else if (line.Substring(i).StartsWith("</i>", StringComparison.Ordinal) || line.Substring(i).StartsWith("</b>", StringComparison.Ordinal) || line.Substring(i).StartsWith("</font>", StringComparison.Ordinal)) { currentStyle = xml.CreateTextNode(string.Empty); if (styles.Count > 0) { currentStyle = styles.Pop().CloneNode(true); currentStyle.InnerText = string.Empty; } paragraph.AppendChild(currentStyle); if (line.Substring(i).StartsWith("</font>", StringComparison.Ordinal)) { skipCount = 6; } else { skipCount = 3; } italicOn = false; } else { if (i == 0 && italicOn && !(line.Substring(i).StartsWith("<i>", StringComparison.Ordinal))) { styles.Push(currentStyle); currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:fontStyle", "http://www.w3.org/ns/10/ttml#style"); attr.InnerText = "italic"; currentStyle.Attributes.Append(attr); } currentStyle.InnerText = currentStyle.InnerText + line[i]; } } first = false; } div.AppendChild(paragraph); } string xmlString = ToUtf8XmlString(xml).Replace(" xmlns=\"\"", string.Empty).Replace(" xmlns:tts=\"http://www.w3.org/ns/10/ttml#style\">", ">").Replace("<br />", "<br/>"); if (subtitle.Header == null) { subtitle.Header = xmlString; } return(xmlString); }
public override string ToText(Subtitle subtitle, string title) { bool convertedFromSubStationAlpha = false; if (subtitle.Header != null) { XmlNode styleHead = null; try { var x = new XmlDocument(); x.LoadXml(subtitle.Header); var xnsmgr = new XmlNamespaceManager(x.NameTable); xnsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml"); if (x.DocumentElement != null) { styleHead = x.DocumentElement.SelectSingleNode("ttml:head", xnsmgr); } } catch { styleHead = null; } if (styleHead == null && (subtitle.Header.Contains("[V4+ Styles]") || subtitle.Header.Contains("[V4 Styles]"))) { var x = new XmlDocument(); x.LoadXml(new ItunesTimedText().ToText(new Subtitle(), "tt")); // load default xml var xnsmgr = new XmlNamespaceManager(x.NameTable); xnsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml"); if (x.DocumentElement != null) { styleHead = x.DocumentElement.SelectSingleNode("ttml:head", xnsmgr); styleHead.SelectSingleNode("ttml:styling", xnsmgr).RemoveAll(); foreach (string styleName in AdvancedSubStationAlpha.GetStylesFromHeader(subtitle.Header)) { try { var ssaStyle = AdvancedSubStationAlpha.GetSsaStyle(styleName, subtitle.Header); string fontStyle = "normal"; if (ssaStyle.Italic) { fontStyle = "italic"; } string fontWeight = "normal"; if (ssaStyle.Bold) { fontWeight = "bold"; } AddStyleToXml(x, styleHead, xnsmgr, ssaStyle.Name, ssaStyle.FontName, fontWeight, fontStyle, Utilities.ColorToHex(ssaStyle.Primary), ssaStyle.FontSize.ToString()); convertedFromSubStationAlpha = true; } catch { // ignored } } } subtitle.Header = x.OuterXml; // save new xml with styles in header } } var xml = new XmlDocument { XmlResolver = null }; var nsmgr = new XmlNamespaceManager(xml.NameTable); nsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml"); nsmgr.AddNamespace("ttp", "http://www.w3.org/ns/10/ttml#parameter"); nsmgr.AddNamespace("tts", "http://www.w3.org/ns/10/ttml#style"); nsmgr.AddNamespace("ttm", "http://www.w3.org/ns/10/ttml#metadata"); const string xmlStructure = @"<?xml version='1.0' encoding='utf-8'?> <tt xmlns='http://www.w3.org/ns/ttml' xmlns:ttm='http://www.w3.org/ns/ttml#metadata' xmlns:tts='http://www.w3.org/ns/ttml#styling' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xml:lang='en'> <head> <metadata> <ttm:title>Netflix Subtitle</ttm:title> </metadata> <styling> <style tts:fontStyle='normal' tts:fontWeight='normal' xml:id='s1' tts:color='white' tts:fontFamily='Arial' tts:fontSize='100%'></style> </styling> <layout> <region tts:extent='80% 40%' tts:origin='10% 10%' tts:displayAlign='before' tts:textAlign='center' xml:id='topCenter' /> <region tts:extent='80% 40%' tts:origin='10% 50%' tts:displayAlign='after' tts:textAlign='center' xml:id='bottomCenter' /> </layout> </head> <body> <div style='s1' xml:id='d1'></div> </body> </tt>"; xml.LoadXml(xmlStructure); if (!string.IsNullOrWhiteSpace(title)) { var headNode = xml.DocumentElement.SelectSingleNode("//ttml:head", nsmgr); var metadataNode = headNode?.SelectSingleNode("ttml:metadata", nsmgr); var titleNode = metadataNode?.FirstChild; if (titleNode != null) { titleNode.InnerText = "Netflix Subtitle for " + title; } } var div = xml.DocumentElement.SelectSingleNode("//ttml:body", nsmgr).SelectSingleNode("ttml:div", nsmgr); bool hasBottomCenterRegion = false; bool hasTopCenterRegion = false; foreach (XmlNode node in xml.DocumentElement.SelectNodes("//ttml:head/ttml:layout/ttml:region", nsmgr)) { string id = null; if (node.Attributes["xml:id"] != null) { id = node.Attributes["xml:id"].Value; } else if (node.Attributes["id"] != null) { id = node.Attributes["id"].Value; } if (id != null && id == "bottomCenter") { hasBottomCenterRegion = true; } if (id != null && id == "topCenter") { hasTopCenterRegion = true; } } int no = 0; foreach (var p in subtitle.Paragraphs) { XmlNode paragraph = xml.CreateElement("p", "http://www.w3.org/ns/ttml"); string text = p.Text; XmlAttribute pid = xml.CreateAttribute("xml:id"); pid.InnerText = "p" + ++no; paragraph.Attributes.Append(pid); XmlAttribute start = xml.CreateAttribute("begin"); start.InnerText = string.Format(CultureInfo.InvariantCulture, "{0:00}:{1:00}:{2:00}.{3:000}", p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, p.StartTime.Milliseconds); paragraph.Attributes.Append(start); XmlAttribute end = xml.CreateAttribute("end"); end.InnerText = string.Format(CultureInfo.InvariantCulture, "{0:00}:{1:00}:{2:00}.{3:000}", p.EndTime.Hours, p.EndTime.Minutes, p.EndTime.Seconds, p.EndTime.Milliseconds); paragraph.Attributes.Append(end); XmlAttribute regionP = xml.CreateAttribute("region"); if (text.StartsWith("{\\an7}", StringComparison.Ordinal) || text.StartsWith("{\\an8}", StringComparison.Ordinal) || text.StartsWith("{\\an9}", StringComparison.Ordinal)) { if (hasTopCenterRegion) { regionP.InnerText = "topCenter"; paragraph.Attributes.Append(regionP); } } else if (hasBottomCenterRegion) { regionP.InnerText = "bottomCenter"; paragraph.Attributes.Append(regionP); } if (text.StartsWith("{\\an", StringComparison.Ordinal) && text.Length > 6 && text[5] == '}') { text = text.Remove(0, 6); } if (convertedFromSubStationAlpha) { if (string.IsNullOrEmpty(p.Style)) { p.Style = p.Extra; } } bool first = true; bool italicOn = false; foreach (string line in text.SplitToLines()) { if (!first) { XmlNode br = xml.CreateElement("br", "http://www.w3.org/ns/ttml"); paragraph.AppendChild(br); } var styles = new Stack <XmlNode>(); XmlNode currentStyle = xml.CreateTextNode(string.Empty); paragraph.AppendChild(currentStyle); int skipCount = 0; for (int i = 0; i < line.Length; i++) { if (skipCount > 0) { skipCount--; } else if (line.Substring(i).StartsWith("<i>", StringComparison.OrdinalIgnoreCase)) { styles.Push(currentStyle); currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:fontStyle", "http://www.w3.org/ns/10/ttml#style"); attr.InnerText = "italic"; currentStyle.Attributes.Append(attr); skipCount = 2; italicOn = true; } else if (line.Substring(i).StartsWith("<b>", StringComparison.OrdinalIgnoreCase)) { currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:fontWeight", "http://www.w3.org/ns/10/ttml#style"); attr.InnerText = "bold"; currentStyle.Attributes.Append(attr); skipCount = 2; } else if (line.Substring(i).StartsWith("<font ", StringComparison.OrdinalIgnoreCase)) { int endIndex = line.Substring(i + 1).IndexOf('>'); if (endIndex > 0) { skipCount = endIndex + 1; string fontContent = line.Substring(i, skipCount); if (fontContent.Contains(" color=", StringComparison.OrdinalIgnoreCase)) { var arr = fontContent.Substring(fontContent.IndexOf(" color=", StringComparison.Ordinal) + 7).Trim().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (arr.Length > 0) { string fontColor = arr[0].Trim('\'').Trim('"').Trim('\''); currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:color", "http://www.w3.org/ns/10/ttml#style"); attr.InnerText = fontColor; currentStyle.Attributes.Append(attr); } } } else { skipCount = line.Length; } } else if (line.Substring(i).StartsWith("</i>", StringComparison.OrdinalIgnoreCase) || line.Substring(i).StartsWith("</b>", StringComparison.OrdinalIgnoreCase) || line.Substring(i).StartsWith("</font>", StringComparison.OrdinalIgnoreCase)) { currentStyle = xml.CreateTextNode(string.Empty); if (styles.Count > 0) { currentStyle = styles.Pop().CloneNode(true); currentStyle.InnerText = string.Empty; } paragraph.AppendChild(currentStyle); if (line.Substring(i).StartsWith("</font>", StringComparison.OrdinalIgnoreCase)) { skipCount = 6; } else { skipCount = 3; } italicOn = false; } else { if (i == 0 && italicOn && !line.Substring(i).StartsWith("<i>", StringComparison.OrdinalIgnoreCase)) { styles.Push(currentStyle); currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:fontStyle", "http://www.w3.org/ns/10/ttml#style"); attr.InnerText = "italic"; currentStyle.Attributes.Append(attr); } currentStyle.InnerText = currentStyle.InnerText + line[i]; } } first = false; } div.AppendChild(paragraph); } string xmlString = ToUtf8XmlString(xml).Replace(" xmlns=\"\"", string.Empty).Replace(" xmlns:tts=\"http://www.w3.org/ns/10/ttml#style\">", ">").Replace("<br />", "<br/>"); if (subtitle.Header == null) { subtitle.Header = xmlString; } return(xmlString); }
private static void LoadStylesFromAdvancedSubstationAlpha(Subtitle subtitle, string title, string header, string headerNoStyles, StringBuilder sb) { try { bool styleFound = false; var ttStyles = new StringBuilder(); foreach (string styleName in AdvancedSubStationAlpha.GetStylesFromHeader(subtitle.Header)) { try { var ssaStyle = AdvancedSubStationAlpha.GetSsaStyle(styleName, subtitle.Header); string bold = "0"; if (ssaStyle.Bold) { bold = "-1"; } string italic = "0"; if (ssaStyle.Italic) { italic = "-1"; } string newAlignment = "2"; switch (ssaStyle.Alignment) { case "1": newAlignment = "1"; break; case "3": newAlignment = "3"; break; case "4": newAlignment = "9"; break; case "5": newAlignment = "10"; break; case "6": newAlignment = "11"; break; case "7": newAlignment = "5"; break; case "8": newAlignment = "6"; break; case "9": newAlignment = "7"; break; } //Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, TertiaryColour, BackColour, Bold, Italic, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding const string styleFormat = "Style: {0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},0,1"; // N FN FS PC SC TC BC Bo It BS O Sh Ali ML MR MV A Encoding ttStyles.AppendLine(string.Format(styleFormat, ssaStyle.Name, ssaStyle.FontName, ssaStyle.FontSize, ssaStyle.Primary.ToArgb(), ssaStyle.Secondary.ToArgb(), ssaStyle.Outline.ToArgb(), ssaStyle.Background.ToArgb(), bold, italic, ssaStyle.BorderStyle, ssaStyle.OutlineWidth.ToString(CultureInfo.InvariantCulture), ssaStyle.ShadowWidth.ToString(CultureInfo.InvariantCulture), newAlignment, ssaStyle.MarginLeft, ssaStyle.MarginRight, ssaStyle.MarginVertical)); styleFound = true; } catch { // ignored } } if (styleFound) { sb.AppendLine(string.Format(headerNoStyles, title, ttStyles)); subtitle.Header = sb.ToString(); } else { sb.AppendLine(string.Format(header, title)); } } catch { sb.AppendLine(string.Format(header, title)); } }
public override string ToText(Subtitle subtitle, string title) { XmlNode styleHead = null; bool convertedFromSubStationAlpha = false; if (subtitle.Header != null) { try { var x = new XmlDocument(); x.LoadXml(subtitle.Header); var xnsmgr = new XmlNamespaceManager(x.NameTable); xnsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml"); styleHead = x.DocumentElement.SelectSingleNode("ttml:head", xnsmgr); } catch { styleHead = null; } if (styleHead == null && (subtitle.Header.Contains("[V4+ Styles]") || subtitle.Header.Contains("[V4 Styles]"))) { var x = new XmlDocument(); x.LoadXml(new ItunesTimedText().ToText(new Subtitle(), "tt")); // load default xml var xnsmgr = new XmlNamespaceManager(x.NameTable); xnsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml"); styleHead = x.DocumentElement.SelectSingleNode("ttml:head", xnsmgr); styleHead.SelectSingleNode("ttml:styling", xnsmgr).RemoveAll(); foreach (string styleName in AdvancedSubStationAlpha.GetStylesFromHeader(subtitle.Header)) { try { var ssaStyle = AdvancedSubStationAlpha.GetSsaStyle(styleName, subtitle.Header); string fontStyle = "normal"; if (ssaStyle.Italic) { fontStyle = "italic"; } string fontWeight = "normal"; if (ssaStyle.Bold) { fontWeight = "bold"; } AddStyleToXml(x, styleHead, xnsmgr, ssaStyle.Name, ssaStyle.FontName, fontWeight, fontStyle, Utilities.ColorToHex(ssaStyle.Primary), ssaStyle.FontSize.ToString()); convertedFromSubStationAlpha = true; } catch { // ignored } } subtitle.Header = x.OuterXml; // save new xml with styles in header } } var xml = new XmlDocument { XmlResolver = null }; var nsmgr = new XmlNamespaceManager(xml.NameTable); nsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml"); nsmgr.AddNamespace("ttp", "http://www.w3.org/ns/10/ttml#parameter"); nsmgr.AddNamespace("tts", "http://www.w3.org/ns/ttml#styling"); nsmgr.AddNamespace("ttm", "http://www.w3.org/ns/10/ttml#metadata"); string frameRate = ((int)Math.Round(Configuration.Settings.General.CurrentFrameRate)).ToString(); string frameRateMultiplier = "999 1000"; if (Configuration.Settings.General.CurrentFrameRate % 1.0 < 0.01) { frameRateMultiplier = "1 1"; } string dropMode = "nonDrop"; if (Math.Abs(Configuration.Settings.General.CurrentFrameRate - 29.97) < 0.01) { dropMode = "dropNTSC"; } const string language = "en-US"; string xmlStructure = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + Environment.NewLine + "<tt xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.w3.org/ns/ttml\" xmlns:tt=\"http://www.w3.org/ns/ttml\" xmlns:tts=\"http://www.w3.org/ns/ttml#styling\" xmlns:ttp=\"http://www.w3.org/ns/ttml#parameter\" xml:lang=\"" + language + "\" ttp:timeBase=\"smpte\" ttp:frameRate=\"" + frameRate + "\" ttp:frameRateMultiplier=\"" + frameRateMultiplier + "\" ttp:dropMode=\"" + dropMode + "\">" + Environment.NewLine + " <head>" + Environment.NewLine + " <styling>" + Environment.NewLine + " <style tts:fontSize=\"100%\" tts:color=\"white\" tts:fontStyle=\"normal\" tts:fontWeight=\"normal\" tts:fontFamily=\"sansSerif\" xml:id=\"normal\"/>" + Environment.NewLine + " <style tts:fontSize=\"100%\" tts:color=\"white\" tts:fontStyle=\"normal\" tts:fontWeight=\"bold\" tts:fontFamily=\"sansSerif\" xml:id=\"bold\"/>" + Environment.NewLine + " <style tts:fontSize=\"100%\" tts:color=\"white\" tts:fontStyle=\"italic\" tts:fontWeight=\"normal\" tts:fontFamily=\"sansSerif\" xml:id=\"italic\"/>" + Environment.NewLine + " </styling>" + Environment.NewLine + " <layout>" + Environment.NewLine + " <region xml:id=\"top\" tts:origin=\"0% 0%\" tts:extent=\"100% 15%\" tts:textAlign=\"center\" tts:displayAlign=\"before\"/>" + Environment.NewLine + " <region xml:id=\"bottom\" tts:origin=\"0% 85%\" tts:extent=\"100% 15%\" tts:textAlign=\"center\" tts:displayAlign=\"after\"/>" + Environment.NewLine + " </layout>" + Environment.NewLine + " </head>" + Environment.NewLine + " <body>" + Environment.NewLine + " <div />" + Environment.NewLine + " </body>" + Environment.NewLine + "</tt>"; if (styleHead == null) { xml.LoadXml(xmlStructure); } else { try { xml.LoadXml(subtitle.Header); XmlNode divNode = xml.DocumentElement.SelectSingleNode("//ttml:body", nsmgr).SelectSingleNode("ttml:div", nsmgr); if (divNode == null) { divNode = xml.DocumentElement.SelectSingleNode("//ttml:body", nsmgr).FirstChild; } if (divNode != null) { var lst = new List <XmlNode>(); foreach (XmlNode child in divNode.ChildNodes) { lst.Add(child); } foreach (XmlNode child in lst) { divNode.RemoveChild(child); } } else { xml.LoadXml(xmlStructure); } } catch { xml.LoadXml(xmlStructure); } } XmlNode body = xml.DocumentElement.SelectSingleNode("ttml:body", nsmgr); string defaultStyle = Guid.NewGuid().ToString(); if (body.Attributes["style"] != null) { defaultStyle = body.Attributes["style"].InnerText; } XmlNode div = xml.DocumentElement.SelectSingleNode("//ttml:body", nsmgr).SelectSingleNode("ttml:div", nsmgr); if (div == null) { div = xml.DocumentElement.SelectSingleNode("//ttml:body", nsmgr).FirstChild; } bool hasBottomRegion = false; bool hasTopRegion = false; foreach (XmlNode node in xml.DocumentElement.SelectNodes("//ttml:head/ttml:layout/ttml:region", nsmgr)) { string id = null; if (node.Attributes["xml:id"] != null) { id = node.Attributes["xml:id"].Value; } else if (node.Attributes["id"] != null) { id = node.Attributes["id"].Value; } if (id != null && id == "bottom") { hasBottomRegion = true; } if (id != null && id == "top") { hasTopRegion = true; } } var headerStyles = GetStylesFromHeader(subtitle.Header); foreach (Paragraph p in subtitle.Paragraphs) { XmlNode paragraph = xml.CreateElement("p", "http://www.w3.org/ns/ttml"); string text = p.Text; XmlAttribute regionP = xml.CreateAttribute("region"); if (text.StartsWith("{\\an7}", StringComparison.Ordinal) || text.StartsWith("{\\an8}", StringComparison.Ordinal) || text.StartsWith("{\\an9}", StringComparison.Ordinal)) { if (hasTopRegion) { regionP.InnerText = "top"; paragraph.Attributes.Append(regionP); } } else if (hasBottomRegion) { regionP.InnerText = "bottom"; paragraph.Attributes.Append(regionP); } if (text.StartsWith("{\\an", StringComparison.Ordinal) && text.Length > 6 && text[5] == '}') { text = text.Remove(0, 6); } if (convertedFromSubStationAlpha) { if (string.IsNullOrEmpty(p.Style)) { p.Style = p.Extra; } } if (subtitle.Header != null && p.Style != null && headerStyles.Contains(p.Style)) { if (p.Style != defaultStyle) { XmlAttribute styleAttr = xml.CreateAttribute("style"); styleAttr.InnerText = p.Style; paragraph.Attributes.Append(styleAttr); } } else if (!string.IsNullOrEmpty(p.Style)) { XmlAttribute styleP = xml.CreateAttribute("style"); styleP.InnerText = p.Style; paragraph.Attributes.Append(styleP); } bool first = true; bool italicOn = false; foreach (string line in text.SplitToLines()) { if (!first) { XmlNode br = xml.CreateElement("br", "http://www.w3.org/ns/ttml"); paragraph.AppendChild(br); } Stack <XmlNode> styles = new Stack <XmlNode>(); XmlNode currentStyle = xml.CreateTextNode(string.Empty); paragraph.AppendChild(currentStyle); int skipCount = 0; for (int i = 0; i < line.Length; i++) { if (skipCount > 0) { skipCount--; } else if (line.Substring(i).StartsWith("<i>", StringComparison.OrdinalIgnoreCase)) { styles.Push(currentStyle); currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:fontStyle", "http://www.w3.org/ns/ttml#styling"); attr.InnerText = "italic"; currentStyle.Attributes.Append(attr); skipCount = 2; italicOn = true; } else if (line.Substring(i).StartsWith("<b>", StringComparison.OrdinalIgnoreCase)) { currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:fontWeight", "http://www.w3.org/ns/ttml#styling"); attr.InnerText = "bold"; currentStyle.Attributes.Append(attr); skipCount = 2; } else if (line.Substring(i).StartsWith("<font ", StringComparison.OrdinalIgnoreCase)) { int endIndex = line.Substring(i + 1).IndexOf('>'); if (endIndex > 0) { skipCount = endIndex + 1; string fontContent = line.Substring(i, skipCount); if (fontContent.Contains(" color=", StringComparison.OrdinalIgnoreCase)) { var arr = fontContent.Substring(fontContent.IndexOf(" color=", StringComparison.OrdinalIgnoreCase) + 7).Trim().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (arr.Length > 0) { string fontColor = arr[0].Trim('\'').Trim('"').Trim('\''); currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:color", "http://www.w3.org/ns/ttml#styling"); attr.InnerText = fontColor; currentStyle.Attributes.Append(attr); } } } else { skipCount = line.Length; } } else if (line.Substring(i).StartsWith("</i>", StringComparison.OrdinalIgnoreCase) || line.Substring(i).StartsWith("</b>", StringComparison.OrdinalIgnoreCase) || line.Substring(i).StartsWith("</font>", StringComparison.OrdinalIgnoreCase)) { currentStyle = xml.CreateTextNode(string.Empty); if (styles.Count > 0) { currentStyle = styles.Pop().CloneNode(true); currentStyle.InnerText = string.Empty; } paragraph.AppendChild(currentStyle); if (line.Substring(i).StartsWith("</font>", StringComparison.OrdinalIgnoreCase)) { skipCount = 6; } else { skipCount = 3; } italicOn = false; } else { if (i == 0 && italicOn && !line.Substring(i).StartsWith("<i>", StringComparison.OrdinalIgnoreCase)) { styles.Push(currentStyle); currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:fontStyle", "http://www.w3.org/ns/ttml#styling"); attr.InnerText = "italic"; currentStyle.Attributes.Append(attr); } currentStyle.InnerText += line[i]; } } first = false; } XmlAttribute start = xml.CreateAttribute("begin"); start.InnerText = ConvertToTimeString(p.StartTime); paragraph.Attributes.Append(start); XmlAttribute end = xml.CreateAttribute("end"); end.InnerText = ConvertToTimeString(p.EndTime); paragraph.Attributes.Append(end); div.AppendChild(paragraph); } string xmlString = ToUtf8XmlString(xml).Replace(" xmlns=\"\"", string.Empty).Replace("<br />", "<br/>"); if (subtitle.Header == null) { subtitle.Header = xmlString; } return(xmlString); }
private void buttonOK_Click(object sender, EventArgs e) { ExportedStyles = new List <string>(); foreach (ListViewItem item in listViewExportStyles.Items) { if (item.Checked) { ExportedStyles.Add(item.Text); } } if (ExportedStyles.Count == 0) { return; } saveFileDialogStyle.Title = LanguageSettings.Current.SubStationAlphaStyles.ExportStyleToFile; saveFileDialogStyle.InitialDirectory = Configuration.DataDirectory; if (_isSubStationAlpha) { saveFileDialogStyle.Filter = SubStationAlpha.NameOfFormat + "|*.ssa|" + LanguageSettings.Current.General.AllFiles + "|*.*"; saveFileDialogStyle.FileName = "my_styles.ssa"; } else { saveFileDialogStyle.Filter = AdvancedSubStationAlpha.NameOfFormat + "|*.ass|" + LanguageSettings.Current.General.AllFiles + "|*.*"; saveFileDialogStyle.FileName = "my_styles.ass"; } if (saveFileDialogStyle.ShowDialog(this) == DialogResult.OK) { if (File.Exists(saveFileDialogStyle.FileName)) { var s = new Subtitle(); var format = s.LoadSubtitle(saveFileDialogStyle.FileName, out _, null); if (format == null) { MessageBox.Show("Not subtitle format: " + _format.Name); return; } if (format.Name != _format.Name) { MessageBox.Show(string.Format("Cannot save {1} style in {0} file!", format.Name, _format.Name)); } else { var sb = new StringBuilder(); bool stylesOn = false; bool done = false; string styleFormat = SsaStyle.DefaultAssStyleFormat; foreach (string line in File.ReadAllLines(saveFileDialogStyle.FileName)) { if (line.StartsWith("format:", StringComparison.OrdinalIgnoreCase)) { styleFormat = line; } else if (line.StartsWith("style:", StringComparison.OrdinalIgnoreCase)) { stylesOn = true; } else if (stylesOn && !done) { done = true; foreach (var styleName in ExportedStyles) { SsaStyle style = AdvancedSubStationAlpha.GetSsaStyle(styleName, _header); if (_isSubStationAlpha) { sb.AppendLine(style.ToRawSsa(styleFormat)); } else { sb.AppendLine(style.ToRawAss(styleFormat)); } } } sb.AppendLine(line); foreach (var styleName in ExportedStyles) { var toLower = line.Trim().ToLowerInvariant(); while (toLower.Contains(": ")) { toLower = toLower.Replace(": ", ":"); } while (toLower.Contains(" :")) { toLower = toLower.Replace(" :", ":"); } if (stylesOn && toLower.StartsWith("style:" + styleName.Trim() + ",", StringComparison.OrdinalIgnoreCase)) { MessageBox.Show(string.Format(LanguageSettings.Current.SubStationAlphaStyles.StyleAlreadyExits, styleName)); return; } } } File.WriteAllText(saveFileDialogStyle.FileName, sb.ToString(), Encoding.UTF8); } } else { var sb = new StringBuilder(); foreach (var line in _header.Replace(Environment.NewLine, "\n").Split('\n')) { if (line.StartsWith("style:", StringComparison.OrdinalIgnoreCase)) { foreach (var styleName in ExportedStyles) { var toLower = line.Trim().ToLowerInvariant(); while (toLower.Contains(": ")) { toLower = toLower.Replace(": ", ":"); } while (toLower.Contains(" :")) { toLower = toLower.Replace(" :", ":"); } if (toLower.StartsWith("style:" + styleName.ToLowerInvariant().Trim() + ",", StringComparison.Ordinal)) { sb.AppendLine(line); } } } else { sb.AppendLine(line); } } string content = sb.ToString(); if (content.TrimEnd().EndsWith("[Events]", StringComparison.Ordinal)) { content = content.Trim() + Environment.NewLine + "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text" + Environment.NewLine + "Dialogue: 0,0:00:31.91,0:00:33.91,Default,,0,0,0,,My Styles :)"; } else if (content.TrimEnd().EndsWith("Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text", StringComparison.Ordinal)) { content = content.Trim() + Environment.NewLine + "Dialogue: 0,0:00:31.91,0:00:33.91,Default,,0,0,0,,My Styles :)"; } else if (!content.Contains("[Events]", StringComparison.OrdinalIgnoreCase)) { content = content.Trim() + Environment.NewLine + Environment.NewLine + "[Events]" + Environment.NewLine + "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text" + Environment.NewLine + "Dialogue: 0,0:00:31.91,0:00:33.91,Default,,0,0,0,,My Styles :)"; } File.WriteAllText(saveFileDialogStyle.FileName, content, Encoding.UTF8); DialogResult = DialogResult.OK; } } }
private SsaStyle GetSsaStyle(string styleName) { return(AdvancedSubStationAlpha.GetSsaStyle(styleName, _header)); }
public override string ToText(Subtitle subtitle, string title) { XmlNode styleHead = null; if (subtitle.Header != null) { try { var x = new XmlDocument(); x.LoadXml(subtitle.Header); var xnsmgr = new XmlNamespaceManager(x.NameTable); xnsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml"); styleHead = x.DocumentElement.SelectSingleNode("ttml:head", xnsmgr); } catch { } if (styleHead == null && (subtitle.Header.Contains("[V4+ Styles]") || subtitle.Header.Contains("[V4 Styles]"))) { var x = new XmlDocument(); x.LoadXml(new TimedText10().ToText(new Subtitle(), "tt")); // load default xml var xnsmgr = new XmlNamespaceManager(x.NameTable); xnsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml"); styleHead = x.DocumentElement.SelectSingleNode("ttml:head", xnsmgr); styleHead.SelectSingleNode("ttml:styling", xnsmgr).RemoveAll(); foreach (string styleName in AdvancedSubStationAlpha.GetStylesFromHeader(subtitle.Header)) { try { var ssaStyle = AdvancedSubStationAlpha.GetSsaStyle(styleName, subtitle.Header); if (ssaStyle != null) { string fontStyle = "normal"; if (ssaStyle.Italic) { fontStyle = "italic"; } string fontWeight = "normal"; if (ssaStyle.Bold) { fontWeight = "bold"; } AddStyleToXml(x, styleHead, xnsmgr, ssaStyle.Name, ssaStyle.FontName, fontWeight, fontStyle, Utilities.ColorToHex(ssaStyle.Primary), ssaStyle.FontSize.ToString(CultureInfo.InvariantCulture)); } } catch { } } subtitle.Header = x.OuterXml; // save new xml with styles in header } } var xml = new XmlDocument(); var nsmgr = new XmlNamespaceManager(xml.NameTable); nsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml"); nsmgr.AddNamespace("ttp", "http://www.w3.org/ns/10/ttml#parameter"); nsmgr.AddNamespace("tts", "http://www.w3.org/ns/10/ttml#style"); nsmgr.AddNamespace("ttm", "http://www.w3.org/ns/10/ttml#metadata"); string xmlStructure = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + Environment.NewLine + "<tt xmlns=\"http://www.w3.org/ns/ttml\" xmlns:ttp=\"http://www.w3.org/ns/ttml#parameter\" ttp:timeBase=\"media\" xmlns:tts=\"http://www.w3.org/ns/ttml#style\" xml:lang=\"en\" xmlns:ttm=\"http://www.w3.org/ns/ttml#metadata\">" + Environment.NewLine + " <head>" + Environment.NewLine + " <metadata>" + Environment.NewLine + " <ttm:title></ttm:title>" + Environment.NewLine + " </metadata>" + Environment.NewLine + " <styling>" + Environment.NewLine + " <style id=\"s0\" tts:backgroundColor=\"black\" tts:fontStyle=\"normal\" tts:fontSize=\"16\" tts:fontFamily=\"sansSerif\" tts:color=\"white\" />" + Environment.NewLine + " </styling>" + Environment.NewLine + " </head>" + Environment.NewLine + " <body style=\"s0\">" + Environment.NewLine + " <div />" + Environment.NewLine + " </body>" + Environment.NewLine + "</tt>"; if (styleHead == null) { xml.LoadXml(xmlStructure); } else { xml.LoadXml(subtitle.Header); XmlNode bodyNode = xml.DocumentElement.SelectSingleNode("//ttml:body", nsmgr); XmlNode divNode = bodyNode.SelectSingleNode("ttml:div", nsmgr); if (divNode == null) { divNode = xml.DocumentElement.SelectSingleNode("//ttml:body", nsmgr).FirstChild; } if (divNode != null) { // Remove all but first div int innerNodeCount = 0; var innerNodeList = new List <XmlNode>(); foreach (XmlNode innerNode in bodyNode.SelectNodes("ttml:div", nsmgr)) { if (innerNodeCount > 0) { innerNodeList.Add(innerNode); } innerNodeCount++; } foreach (XmlNode child in innerNodeList) { bodyNode.RemoveChild(child); } var lst = new List <XmlNode>(); foreach (XmlNode child in divNode.ChildNodes) { lst.Add(child); } foreach (XmlNode child in lst) { divNode.RemoveChild(child); } } else { xml.LoadXml(xmlStructure); } } XmlNode body = xml.DocumentElement.SelectSingleNode("ttml:body", nsmgr); string defaultStyle = Guid.NewGuid().ToString(); if (body.Attributes["style"] != null) { defaultStyle = body.Attributes["style"].InnerText; } XmlNode div = xml.DocumentElement.SelectSingleNode("//ttml:body", nsmgr).SelectSingleNode("ttml:div", nsmgr); if (div == null) { div = xml.DocumentElement.SelectSingleNode("//ttml:body", nsmgr).FirstChild; } int no = 0; var headerStyles = GetStylesFromHeader(subtitle.Header); var regions = GetRegionsFromHeader(subtitle.Header); var languages = GetUsedLanguages(subtitle); if (languages.Count > 0) { var divParentNode = div.ParentNode; foreach (Paragraph p in subtitle.Paragraphs) { if (p.Language == null) { if (p.NewSection) { div = xml.CreateElement("div", "http://www.w3.org/ns/ttml"); divParentNode.AppendChild(div); } XmlNode paragraph = MakeParagraph(subtitle, xml, defaultStyle, no, headerStyles, regions, p); div.AppendChild(paragraph); no++; } } foreach (string language in languages) { div = xml.CreateElement("div", "http://www.w3.org/ns/ttml"); XmlAttribute attr = xml.CreateAttribute("xml:lang", "http://www.w3.org/XML/1998/namespace"); attr.Value = language; div.Attributes.Append(attr); divParentNode.AppendChild(div); bool firstParagraph = true; foreach (Paragraph p in subtitle.Paragraphs) { if (p.Language == language) { if (p.NewSection && !firstParagraph) { div = xml.CreateElement("div", "http://www.w3.org/ns/ttml"); attr = xml.CreateAttribute("xml:lang", "http://www.w3.org/XML/1998/namespace"); attr.Value = language; div.Attributes.Append(attr); divParentNode.AppendChild(div); } firstParagraph = false; XmlNode paragraph = MakeParagraph(subtitle, xml, defaultStyle, no, headerStyles, regions, p); div.AppendChild(paragraph); no++; } } } if (divParentNode != null && divParentNode.HasChildNodes && !divParentNode.FirstChild.HasChildNodes) { divParentNode.RemoveChild(divParentNode.FirstChild); } } else { var divParentNode = div.ParentNode; foreach (Paragraph p in subtitle.Paragraphs) { if (p.NewSection) { div = xml.CreateElement("div", "http://www.w3.org/ns/ttml"); divParentNode.AppendChild(div); } XmlNode paragraph = MakeParagraph(subtitle, xml, defaultStyle, no, headerStyles, regions, p); div.AppendChild(paragraph); no++; } if (divParentNode != null && divParentNode.HasChildNodes && !divParentNode.FirstChild.HasChildNodes) { divParentNode.RemoveChild(divParentNode.FirstChild); } } return(ToUtf8XmlString(xml).Replace(" xmlns=\"\"", string.Empty).Replace(" xmlns:tts=\"http://www.w3.org/ns/10/ttml#style\">", ">")); }
private void buttonOK_Click(object sender, EventArgs e) { buttonOK.Enabled = false; using (var saveDialog = new SaveFileDialog { FileName = string.Empty, Filter = "MP4|*.mp4|Matroska|*.mkv|WebM|*.webm" }) { if (saveDialog.ShowDialog(this) != DialogResult.OK) { return; } VideoFileName = saveDialog.FileName; } if (File.Exists(VideoFileName)) { File.Delete(VideoFileName); } if (numericUpDownFontSize.Visible) { var fontSize = (int)numericUpDownFontSize.Value; var style = AdvancedSubStationAlpha.GetSsaStyle("Default", _assaSubtitle.Header); style.FontSize = fontSize; var styleLine = style.ToRawAss(); _assaSubtitle.Header = AdvancedSubStationAlpha.AddTagToHeader("Style", styleLine, "[V4+ Styles]", _assaSubtitle.Header); } if (Configuration.Settings.General.RightToLeftMode && LanguageAutoDetect.CouldBeRightToLeftLanguage(_assaSubtitle)) { for (var index = 0; index < _assaSubtitle.Paragraphs.Count; index++) { var paragraph = _assaSubtitle.Paragraphs[index]; if (LanguageAutoDetect.ContainsRightToLeftLetter(paragraph.Text)) { paragraph.Text = Utilities.FixRtlViaUnicodeChars(paragraph.Text); } } } SubtitleFormat format = new AdvancedSubStationAlpha(); var assaTempFileName = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".ass"); File.WriteAllText(assaTempFileName, format.ToText(_assaSubtitle, null)); progressBar1.Style = ProgressBarStyle.Marquee; progressBar1.Visible = true; labelPleaseWait.Visible = true; var process = VideoPreviewGenerator.GenerateHardcodedVideoFile( _inputVideoFileName, assaTempFileName, VideoFileName); process.Start(); while (!process.HasExited) { System.Threading.Thread.Sleep(100); Application.DoEvents(); if (_abort) { process.Kill(); } } progressBar1.Visible = false; labelPleaseWait.Visible = false; try { File.Delete(assaTempFileName); } catch { // ignore } DialogResult = _abort ? DialogResult.Cancel : DialogResult.OK; }
private void SortAndLoad() { JoinedFormat = new SubRip(); // default subtitle format string header = null; SubtitleFormat lastFormat = null; var subtitles = new List <Subtitle>(); for (var k = 0; k < _fileNamesToJoin.Count; k++) { var fileName = _fileNamesToJoin[k]; try { var sub = new Subtitle(); SubtitleFormat format = null; if (fileName.EndsWith(".ismt", StringComparison.InvariantCultureIgnoreCase) || fileName.EndsWith(".mp4", StringComparison.InvariantCultureIgnoreCase) || fileName.EndsWith(".m4v", StringComparison.InvariantCultureIgnoreCase) || fileName.EndsWith(".3gp", StringComparison.InvariantCultureIgnoreCase)) { format = new IsmtDfxp(); if (format.IsMine(null, fileName)) { var s = new Subtitle(); format.LoadSubtitle(s, null, fileName); if (s.Paragraphs.Count > 0) { lastFormat = format; } } } var lines = FileUtil.ReadAllLinesShared(fileName, LanguageAutoDetect.GetEncodingFromFile(fileName)); if (lastFormat != null && lastFormat.IsMine(lines, fileName)) { format = lastFormat; format.LoadSubtitle(sub, lines, fileName); } if (sub.Paragraphs.Count == 0 || format == null) { format = sub.LoadSubtitle(fileName, out _, null); } if (format == null && lines.Count > 0 && lines.Count < 10 && lines[0].Trim() == "WEBVTT") { format = new WebVTT(); // empty WebVTT } if (format == null) { foreach (var binaryFormat in SubtitleFormat.GetBinaryFormats(true)) { if (binaryFormat.IsMine(null, fileName)) { binaryFormat.LoadSubtitle(sub, null, fileName); format = binaryFormat; break; } } } if (format == null) { foreach (var f in SubtitleFormat.GetTextOtherFormats()) { if (f.IsMine(lines, fileName)) { f.LoadSubtitle(sub, lines, fileName); format = f; break; } } } if (format == null) { Revert(k, LanguageSettings.Current.UnknownSubtitle.Title + Environment.NewLine + fileName); break; } if (sub.Header != null) { if (format.Name == AdvancedSubStationAlpha.NameOfFormat) { sub.Header = sub.Header.Replace("*Default", "Default"); foreach (var subParagraph in sub.Paragraphs) { if (subParagraph.Extra == "*Default") { subParagraph.Extra = "Default"; } } } if (format.Name == AdvancedSubStationAlpha.NameOfFormat && header != null) { var oldPlayResX = AdvancedSubStationAlpha.GetTagFromHeader("PlayResX", "[Script Info]", header); var oldPlayResY = AdvancedSubStationAlpha.GetTagFromHeader("PlayResY", "[Script Info]", header); var newPlayResX = AdvancedSubStationAlpha.GetTagFromHeader("PlayResX", "[Script Info]", sub.Header); var newPlayResY = AdvancedSubStationAlpha.GetTagFromHeader("PlayResY", "[Script Info]", sub.Header); var stylesInHeader = AdvancedSubStationAlpha.GetStylesFromHeader(header); var styles = new List <SsaStyle>(); foreach (var styleName in stylesInHeader) { styles.Add(AdvancedSubStationAlpha.GetSsaStyle(styleName, header)); } foreach (var newStyle in AdvancedSubStationAlpha.GetStylesFromHeader(sub.Header)) { if (stylesInHeader.Any(p => p == newStyle)) { if (IsStyleDifferent(newStyle, sub, header)) { var styleToBeRenamed = AdvancedSubStationAlpha.GetSsaStyle(newStyle, sub.Header); var newName = styleToBeRenamed.Name + "_" + Guid.NewGuid(); foreach (var p in sub.Paragraphs.Where(p => p.Extra == styleToBeRenamed.Name)) { p.Extra = newName; } styleToBeRenamed.Name = newName; styles.Add(styleToBeRenamed); } } else { styles.Add(AdvancedSubStationAlpha.GetSsaStyle(newStyle, sub.Header)); } } header = AdvancedSubStationAlpha.GetHeaderAndStylesFromAdvancedSubStationAlpha(header, styles); if (!string.IsNullOrEmpty(oldPlayResX) && string.IsNullOrEmpty(newPlayResX)) { header = AdvancedSubStationAlpha.AddTagToHeader("PlayResX", oldPlayResX, "[Script Info]", header); } if (!string.IsNullOrEmpty(oldPlayResY) && string.IsNullOrEmpty(newPlayResY)) { header = AdvancedSubStationAlpha.AddTagToHeader("PlayResY", oldPlayResY, "[Script Info]", header); } } else { header = sub.Header; } } lastFormat = lastFormat == null || lastFormat.FriendlyName == format.FriendlyName ? format : new SubRip(); subtitles.Add(sub); } catch (Exception exception) { Revert(k, exception.Message); return; } } JoinedFormat = lastFormat; if (!radioButtonJoinAddTime.Checked) { for (int outer = 0; outer < subtitles.Count; outer++) { for (int inner = 1; inner < subtitles.Count; inner++) { var a = subtitles[inner - 1]; var b = subtitles[inner]; if (a.Paragraphs.Count > 0 && b.Paragraphs.Count > 0 && a.Paragraphs[0].StartTime.TotalMilliseconds > b.Paragraphs[0].StartTime.TotalMilliseconds) { var t1 = _fileNamesToJoin[inner - 1]; _fileNamesToJoin[inner - 1] = _fileNamesToJoin[inner]; _fileNamesToJoin[inner] = t1; var t2 = subtitles[inner - 1]; subtitles[inner - 1] = subtitles[inner]; subtitles[inner] = t2; } } } } listViewParts.BeginUpdate(); listViewParts.Items.Clear(); int i = 0; foreach (var fileName in _fileNamesToJoin) { var sub = subtitles[i]; var lvi = new ListViewItem($"{sub.Paragraphs.Count:#,###,###}"); if (sub.Paragraphs.Count > 0) { lvi.SubItems.Add(sub.Paragraphs[0].StartTime.ToString()); lvi.SubItems.Add(sub.Paragraphs[sub.Paragraphs.Count - 1].StartTime.ToString()); } else { lvi.SubItems.Add("-"); lvi.SubItems.Add("-"); } lvi.SubItems.Add(fileName); listViewParts.Items.Add(lvi); i++; } listViewParts.EndUpdate(); JoinedSubtitle = new Subtitle(); if (JoinedFormat != null && JoinedFormat.FriendlyName != SubRip.NameOfFormat) { JoinedSubtitle.Header = header; } var addTime = radioButtonJoinAddTime.Checked; foreach (var sub in subtitles) { double addMs = 0; if (addTime && JoinedSubtitle.Paragraphs.Count > 0) { addMs = JoinedSubtitle.Paragraphs.Last().EndTime.TotalMilliseconds + Convert.ToDouble(numericUpDownAddMs.Value); } foreach (var p in sub.Paragraphs) { p.StartTime.TotalMilliseconds += addMs; p.EndTime.TotalMilliseconds += addMs; JoinedSubtitle.Paragraphs.Add(p); } } JoinedSubtitle.Renumber(); labelTotalLines.Text = string.Format(LanguageSettings.Current.JoinSubtitles.TotalNumberOfLinesX, JoinedSubtitle.Paragraphs.Count); }