示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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));
            }
        }
示例#4
0
        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));
 }
示例#7
0
        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;
        }
示例#9
0
        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);
        }