using System; using System.Collections.Generic; using System.Text; using System.Xml; namespace Nikse.SubtitleEdit.Core.SubtitleFormats { public class UniversalSubtitleFormat : SubtitleFormat { public override string Extension { get { return ".usf"; } } public override string Name { get { return "Universal Subtitle Format"; } } public override bool IsTimeBased { get { return true; } } public override bool IsMine(List lines, string fileName) { var subtitle = new Subtitle(); LoadSubtitle(subtitle, lines, fileName); return subtitle.Paragraphs.Count > 0; } public override string ToText(Subtitle subtitle, string title) { string xmlStructure = "" + Environment.NewLine + "" + Environment.NewLine + @" Universal Subtitle Format SubtitleEdit nikse.dk@gmail.com http://www.nikse.dk/ " + Environment.NewLine + " English" + Environment.NewLine + @" [DATE] This is a USF file " + Environment.NewLine + " "; xmlStructure = xmlStructure.Replace("[DATE]", DateTime.Now.ToString("yyyy-MM-dd")); var xml = new XmlDocument(); xml.LoadXml(xmlStructure); xml.DocumentElement.SelectSingleNode("metadata/title").InnerText = title; var subtitlesNode = xml.DocumentElement.SelectSingleNode("subtitles"); foreach (Paragraph p in subtitle.Paragraphs) { XmlNode paragraph = xml.CreateElement("subtitle"); XmlAttribute start = xml.CreateAttribute("start"); start.InnerText = p.StartTime.ToString().Replace(",", "."); paragraph.Attributes.Prepend(start); XmlAttribute stop = xml.CreateAttribute("stop"); stop.InnerText = p.EndTime.ToString().Replace(",", "."); paragraph.Attributes.Append(stop); XmlNode text = xml.CreateElement("text"); text.InnerText = HtmlUtil.RemoveHtmlTags(p.Text); paragraph.AppendChild(text); XmlAttribute style = xml.CreateAttribute("style"); style.InnerText = "Default"; text.Attributes.Append(style); subtitlesNode.AppendChild(paragraph); } return ToUtf8XmlString(xml); } private static TimeCode DecodeTimeCode(string code) { string[] parts = code.Split(new[] { ':', '.', ',' }, StringSplitOptions.RemoveEmptyEntries); //00:00:07:12 string hour = parts[0]; string minutes = parts[1]; string seconds = parts[2]; string frames = parts[3]; return new TimeCode(int.Parse(hour), int.Parse(minutes), int.Parse(seconds), FramesToMillisecondsMax999(int.Parse(frames))); } public override void LoadSubtitle(Subtitle subtitle, List lines, string fileName) { _errorCount = 0; var sb = new StringBuilder(); lines.ForEach(line => sb.AppendLine(line)); string xmlString = sb.ToString(); if (!xmlString.Contains("")) return; var xml = new XmlDocument { XmlResolver = null }; try { xml.LoadXml(xmlString); } catch { _errorCount = 1; return; } foreach (XmlNode node in xml.DocumentElement.SelectNodes("subtitles/subtitle")) { try { string start = node.Attributes["start"].InnerText; string stop = node.Attributes["stop"].InnerText; string text = node.SelectSingleNode("text").InnerText; subtitle.Paragraphs.Add(new Paragraph(DecodeTimeCode(start), DecodeTimeCode(stop), text)); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); _errorCount++; } } subtitle.Renumber(); } } }