Added new subtitle format

This commit is contained in:
niksedk 2014-03-21 22:06:21 +01:00
parent 4d0eb40cd2
commit ce42e01756
4 changed files with 180 additions and 2 deletions

View File

@ -0,0 +1,176 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
namespace Nikse.SubtitleEdit.Logic.SubtitleFormats
{
public class FilmEditXml : SubtitleFormat
{
public override string Extension
{
get { return ".xml"; }
}
public override string Name
{
get { return "Film Edit xml"; }
}
public override bool IsTimeBased
{
get { return true; }
}
public override bool IsMine(List<string> lines, string fileName)
{
var sb = new StringBuilder();
lines.ForEach(line => sb.AppendLine(line));
string xmlAsString = sb.ToString().Trim();
if (xmlAsString.Contains("</filmeditxml>") && xmlAsString.Contains("</subtitle>"))
{
var xml = new XmlDocument();
try
{
xml.LoadXml(xmlAsString);
var paragraphs = xml.DocumentElement.SelectNodes("subtitle");
return paragraphs != null && paragraphs.Count > 0 && xml.DocumentElement.Name == "filmeditxml";
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}
return false;
}
public override string ToText(Subtitle subtitle, string title)
{
string xmlStructure =
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + Environment.NewLine +
"<filmeditxml>" + Environment.NewLine +
"<font>Arial</font>" + Environment.NewLine +
"<points>22</points>" + Environment.NewLine +
"<width>720</width>" + Environment.NewLine +
"<height>576</height>" + Environment.NewLine +
"<virtualwidth>586</virtualwidth>" + Environment.NewLine +
"<virtualheight>330</virtualheight>" + Environment.NewLine +
"<par>1420</par>" + Environment.NewLine +
"<fps>25</fps>" + Environment.NewLine +
"<dropped>False</dropped>" + Environment.NewLine +
"</filmeditxml>";
var xml = new XmlDocument();
xml.LoadXml(xmlStructure);
XmlNode div = xml.DocumentElement;
int no = 0;
foreach (Paragraph p in subtitle.Paragraphs)
{
XmlNode paragraph = xml.CreateElement("subtitle");
string text = Utilities.RemoveHtmlTags(p.Text);
XmlNode num = xml.CreateElement("num");
num.InnerText = no.ToString();
paragraph.AppendChild(num);
XmlNode dur = xml.CreateElement("dur");
num.InnerText = EncodeDuration(p.Duration);
paragraph.AppendChild(num);
XmlNode textNode = xml.CreateElement("text");
textNode.InnerText = p.Text.Replace(Environment.NewLine, "\\N");
paragraph.AppendChild(textNode);
XmlNode timeIn = xml.CreateElement("in");
timeIn.InnerText = EncodeTimeCode(p.StartTime);
paragraph.AppendChild(timeIn);
XmlNode timeOut = xml.CreateElement("out");
timeOut.InnerText = EncodeTimeCode(p.EndTime);
paragraph.AppendChild(timeOut);
XmlNode align = xml.CreateElement("align");
align.InnerText = "C";
paragraph.AppendChild(align);
XmlNode posx = xml.CreateElement("posx");
posx.InnerText = "0";
paragraph.AppendChild(posx);
XmlNode post = xml.CreateElement("posy");
post.InnerText = "308";
paragraph.AppendChild(post);
XmlNode memo = xml.CreateElement("memo");
paragraph.AppendChild(memo);
div.AppendChild(paragraph);
no++;
}
return ToUtf8XmlString(xml);
}
private string EncodeDuration(TimeCode timeCode)
{
return string.Format("{0:00}:{1:00}", timeCode.Seconds, MillisecondsToFramesMaxFrameRate(timeCode.Milliseconds));
}
private string EncodeTimeCode(TimeCode timeCode)
{
return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", timeCode.Hours, timeCode.Minutes, timeCode.Seconds, MillisecondsToFramesMaxFrameRate(timeCode.Milliseconds));
}
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
{
_errorCount = 0;
var sb = new StringBuilder();
lines.ForEach(line => sb.AppendLine(line));
var xml = new XmlDocument();
xml.LoadXml(sb.ToString().Trim());
string lastKey = string.Empty;
foreach (XmlNode node in xml.DocumentElement.SelectNodes("subtitle"))
{
try
{
var p = new Paragraph();
foreach (XmlNode innerNode in node.ChildNodes)
{
switch (innerNode.Name.ToString())
{
case "text":
p.Text = innerNode.InnerText.Replace("\\N", Environment.NewLine);
break;
case "in":
p.StartTime = DecodeTime(innerNode.InnerText);
break;
case "out":
p.EndTime = DecodeTime(innerNode.InnerText);
break;
}
}
if (p.StartTime.TotalSeconds >= 0 && p.EndTime.TotalMilliseconds > 0 && !string.IsNullOrEmpty(p.Text))
subtitle.Paragraphs.Add(p);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
_errorCount++;
}
}
subtitle.Renumber(1);
}
private TimeCode DecodeTime(string s)
{
var arr = s.Split(':');
if (arr.Length == 4)
{
return new TimeCode(int.Parse(arr[0]), int.Parse(arr[1]), int.Parse(arr[2]), FramesToMillisecondsMax999(int.Parse(arr[3])));
}
return new TimeCode(0, 0, 0, 0);
}
}
}

View File

@ -55,6 +55,7 @@ namespace Nikse.SubtitleEdit.Logic.SubtitleFormats
new F4Rtf(), new F4Rtf(),
new F4Xml(), new F4Xml(),
new FabSubtitler(), new FabSubtitler(),
new FilmEditXml(),
new FinalCutProXml(), new FinalCutProXml(),
new FinalCutProXXml(), new FinalCutProXXml(),
new FinalCutProXmlGap(), new FinalCutProXmlGap(),

View File

@ -882,6 +882,7 @@
<Compile Include="Logic\SubtitleFormats\CaraokeXml.cs" /> <Compile Include="Logic\SubtitleFormats\CaraokeXml.cs" />
<Compile Include="Logic\SubtitleFormats\Cavena890.cs" /> <Compile Include="Logic\SubtitleFormats\Cavena890.cs" />
<Compile Include="Logic\SubtitleFormats\CheetahCaption.cs" /> <Compile Include="Logic\SubtitleFormats\CheetahCaption.cs" />
<Compile Include="Logic\SubtitleFormats\FilmEditXml.cs" />
<Compile Include="Logic\SubtitleFormats\SwiftTextLineNoAndDur .cs" /> <Compile Include="Logic\SubtitleFormats\SwiftTextLineNoAndDur .cs" />
<Compile Include="Logic\SubtitleFormats\UnknownSubtitle70.cs" /> <Compile Include="Logic\SubtitleFormats\UnknownSubtitle70.cs" />
<Compile Include="Logic\SubtitleFormats\TimeXml2.cs" /> <Compile Include="Logic\SubtitleFormats\TimeXml2.cs" />

View File

@ -11,7 +11,7 @@ namespace Test
public void AutoBreakLine1() public void AutoBreakLine1()
{ {
const int maxLength = 43; const int maxLength = 43;
var s = Utilities.AutoBreakLine("You have a private health insurance and life insurance." + Environment.NewLine + "A digital clone included.", 5, maxLength, 33); var s = Utilities.AutoBreakLine("You have a private health insurance and life insurance." + Environment.NewLine + "A digital clone included.", 5, maxLength, 33, string.Empty);
var arr = s.Replace(Environment.NewLine, "\n").Split('\n'); var arr = s.Replace(Environment.NewLine, "\n").Split('\n');
Assert.AreEqual(2, arr.Length); Assert.AreEqual(2, arr.Length);
Assert.IsFalse(arr[0].Length > maxLength); Assert.IsFalse(arr[0].Length > maxLength);
@ -22,7 +22,7 @@ namespace Test
public void AutoBreakLine2() public void AutoBreakLine2()
{ {
const int maxLength = 43; const int maxLength = 43;
var s = Utilities.AutoBreakLine("We're gonna lose him." + Environment.NewLine + "He's left him four signals in the last week.", 5, maxLength, 33); var s = Utilities.AutoBreakLine("We're gonna lose him." + Environment.NewLine + "He's left him four signals in the last week.", 5, maxLength, 33, string.Empty);
Assert.IsFalse(s == "We're gonna lose him." + Environment.NewLine + "He's left him four signals in the last week."); Assert.IsFalse(s == "We're gonna lose him." + Environment.NewLine + "He's left him four signals in the last week.");
} }