Add basic support for ESUB-XF - thx Bernard :)

This commit is contained in:
Nikolaj Olsson 2019-10-12 07:27:08 +02:00
parent 5d4db36928
commit 5eb62dd35e
3 changed files with 119 additions and 28 deletions

View File

@ -204,6 +204,7 @@
<Compile Include="SeJsonParser.cs" />
<Compile Include="SeLogger.cs" />
<Compile Include="RulesProfile.cs" />
<Compile Include="SubtitleFormats\ESubXf.cs" />
<Compile Include="SubtitleFormats\JsonType15.cs" />
<Compile Include="SubtitleFormats\AwsTranscribeJson.cs" />
<Compile Include="SubtitleFormats\JsonType8b.cs" />

View File

@ -0,0 +1,108 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Xml;
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
{
/// <summary>
/// https://www.fab-online.com/pdf/ESUB-XF.pdf
/// </summary>
public class ESubXf : SubtitleFormat
{
public override string Extension => ".xml";
public override string Name => "ESUB-XF";
private const string NameSpaceUri = "urn:esub-xf";
public override string ToText(Subtitle subtitle, string title)
{
string xmlStructure =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + Environment.NewLine +
"<esub-xf xmlns=\"" + NameSpaceUri + "\" framerate=\"" + Configuration.Settings.General.CurrentFrameRate.ToString(CultureInfo.InvariantCulture) + "\" timebase=\"smpte\">" + Environment.NewLine +
" <subtitlelist language=\"eng\" langname=\"English\" type=\"translation\">" + Environment.NewLine +
" </subtitlelist>" + Environment.NewLine +
"</esub-xf>";
var xml = new XmlDocument { XmlResolver = null };
xml.LoadXml(xmlStructure);
var ns = new XmlNamespaceManager(xml.NameTable);
ns.AddNamespace("esub-xf", NameSpaceUri);
var subtitleList = xml.DocumentElement.SelectSingleNode("//esub-xf:subtitlelist", ns);
foreach (var p in subtitle.Paragraphs)
{
var paragraph = xml.CreateElement("subtitle", NameSpaceUri);
var start = xml.CreateAttribute("display");
start.InnerText = p.StartTime.ToHHMMSSFF();
paragraph.Attributes.Append(start);
var end = xml.CreateAttribute("clear");
end.InnerText = p.EndTime.ToHHMMSSFF();
paragraph.Attributes.Append(end);
var hRegion = xml.CreateElement("hregion", NameSpaceUri);
paragraph.AppendChild(hRegion);
foreach (var line in p.Text.SplitToLines())
{
var lineNode = xml.CreateElement("line", NameSpaceUri);
hRegion.AppendChild(lineNode);
lineNode.InnerText = line;
}
subtitleList.AppendChild(paragraph);
}
return ToUtf8XmlString(xml);
}
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
{
_errorCount = 0;
var sb = new StringBuilder();
lines.ForEach(line => sb.AppendLine(line));
string xmlString = sb.ToString();
if (!xmlString.Contains("<subtitlelist"))
{
return;
}
var xml = new XmlDocument { XmlResolver = null };
try
{
xml.LoadXml(xmlString);
}
catch
{
_errorCount = 1;
return;
}
char[] timeCodeSeparators = new[] { ':' };
var ns = new XmlNamespaceManager(xml.NameTable);
ns.AddNamespace("esub-xf", NameSpaceUri);
foreach (XmlNode node in xml.DocumentElement.SelectNodes("//esub-xf:subtitlelist/esub-xf:subtitle", ns))
{
try
{
string start = node.Attributes["display"].InnerText;
string end = node.Attributes["clear"].InnerText;
sb = new StringBuilder();
foreach (XmlNode lineNode in node.SelectNodes("esub-xf:hregion/esub-xf:line", ns))
{
sb.AppendLine(lineNode.InnerText);
}
subtitle.Paragraphs.Add(new Paragraph(DecodeTimeCodeFrames(start, timeCodeSeparators), DecodeTimeCodeFrames(end, timeCodeSeparators), sb.ToString().TrimEnd()));
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
_errorCount++;
}
}
subtitle.Renumber();
}
}
}

View File

@ -65,6 +65,7 @@ namespace Nikse.SubtitleEdit.Core.SubtitleFormats
new Edl(),
new Eeg708(),
new ElrPrint(),
new ESubXf(),
new F4Text(),
new F4Rtf(),
new F4Xml(),
@ -297,24 +298,20 @@ namespace Nikse.SubtitleEdit.Core.SubtitleFormats
try
{
var assembly = System.Reflection.Assembly.Load(FileUtil.ReadAllBytesShared(pluginFileName));
if (assembly != null)
foreach (var exportedType in assembly.GetExportedTypes())
{
foreach (var exportedType in assembly.GetExportedTypes())
try
{
try
object pluginObject = Activator.CreateInstance(exportedType);
if (pluginObject is SubtitleFormat po)
{
object pluginObject = Activator.CreateInstance(exportedType);
var po = pluginObject as SubtitleFormat;
if (po != null)
{
_allSubtitleFormats.Insert(1, po);
}
}
catch
{
// ignored
_allSubtitleFormats.Insert(1, po);
}
}
catch
{
// ignored
}
}
}
catch
@ -435,21 +432,6 @@ namespace Nikse.SubtitleEdit.Core.SubtitleFormats
return new TimeCode(0, 0, int.Parse(tokens[0]), FramesToMillisecondsMax999(int.Parse(tokens[1])));
}
protected static TimeCode DecodeTimeCodeFramesThreeParts(string[] tokens)
{
if (tokens == null)
{
return new TimeCode();
}
if (tokens.Length != 3)
{
throw new InvalidOperationException();
}
return new TimeCode(0, int.Parse(tokens[0]), int.Parse(tokens[1]), FramesToMillisecondsMax999(int.Parse(tokens[2])));
}
protected static TimeCode DecodeTimeCodeFramesFourParts(string[] tokens)
{
if (tokens == null)