mirror of
https://github.com/SubtitleEdit/subtitleedit.git
synced 2024-11-22 03:02:35 +01:00
Added new subtitle format - thx Leandro :)
This commit is contained in:
parent
d3387de958
commit
3c9995daa9
@ -2,7 +2,7 @@
|
||||
|
||||
3.4.13 (xth May 2016) BETA
|
||||
* NEW:
|
||||
* Added new subtitle formats - thx Oli/Mauricio
|
||||
* Added new subtitle formats - thx Oli/Mauricio/Leandro
|
||||
* It's now possible to use "video offset" via "Video" menu
|
||||
* Added support for spu/png OCR - thx claunia
|
||||
* IMPROVED:
|
||||
@ -18,7 +18,7 @@
|
||||
* Some minor improvements for OCR via "Binary image compare"
|
||||
* FIXED:
|
||||
* Fix updating of main list view after "Remove text for HI" + "Apply" - thx Henry
|
||||
* Spell check "change" / "change all" issue regarding brackets/dash - thx jc
|
||||
* Spell check "Change" / "Change all" issue regarding brackets/dash - thx jc
|
||||
* Fixed issue where current frame rate was lost when loading new sub - thx Elad
|
||||
* Remove bad chars when saving TTML 1.0
|
||||
* Minor fix for "Toggle dashes" inside italic tag - thx Bryan
|
||||
|
@ -364,6 +364,7 @@
|
||||
<Compile Include="SubtitleFormats\UnknownSubtitle25.cs" />
|
||||
<Compile Include="SubtitleFormats\UnknownSubtitle26.cs" />
|
||||
<Compile Include="SubtitleFormats\UnknownSubtitle27.cs" />
|
||||
<Compile Include="SubtitleFormats\Cappella.cs" />
|
||||
<Compile Include="SubtitleFormats\UnknownSubtitle28.cs" />
|
||||
<Compile Include="SubtitleFormats\UnknownSubtitle29.cs" />
|
||||
<Compile Include="SubtitleFormats\UnknownSubtitle3.cs" />
|
||||
|
170
libse/SubtitleFormats/Cappella.cs
Normal file
170
libse/SubtitleFormats/Cappella.cs
Normal file
@ -0,0 +1,170 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class Cappella : SubtitleFormat
|
||||
{
|
||||
public override string Extension
|
||||
{
|
||||
get { return ".detx"; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "Cappella"; }
|
||||
}
|
||||
|
||||
public override bool IsTimeBased
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool IsMine(List<string> 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 = @"<?xml version='1.0' encoding='utf-8'?>
|
||||
<detx copyright='Chinkel S.A., 2007 - 2016'>
|
||||
<header>
|
||||
<cappella version='3.7.0'/>
|
||||
<last_position timecode='[LAST]' track='0'/>
|
||||
</header>
|
||||
<roles>
|
||||
<role color='#000000' description='subtitle' id='sub' name='sub'/>
|
||||
</roles>
|
||||
<body />
|
||||
</detx>".Replace('\"', '\'');
|
||||
if (subtitle.Paragraphs.Count > 0)
|
||||
{
|
||||
xmlStructure = xmlStructure.Replace("[LAST]", ToTimeCode(subtitle.Paragraphs[subtitle.Paragraphs.Count -1].EndTime));
|
||||
}
|
||||
|
||||
var xml = new XmlDocument();
|
||||
xml.LoadXml(xmlStructure);
|
||||
foreach (Paragraph p in subtitle.Paragraphs)
|
||||
{
|
||||
XmlNode paragraph = xml.CreateElement("line");
|
||||
XmlAttribute roleAttr = xml.CreateAttribute("role");
|
||||
roleAttr.InnerText = "sub";
|
||||
paragraph.Attributes.Append(roleAttr);
|
||||
XmlAttribute trackAttr = xml.CreateAttribute("track");
|
||||
trackAttr.InnerText = "0";
|
||||
paragraph.Attributes.Append(trackAttr);
|
||||
|
||||
XmlNode time = xml.CreateElement("lipsync");
|
||||
XmlAttribute start = xml.CreateAttribute("timecode");
|
||||
start.InnerText = ToTimeCode(p.StartTime);
|
||||
time.Attributes.Append(start);
|
||||
XmlAttribute type = xml.CreateAttribute("type");
|
||||
type.InnerText = "in_open";
|
||||
time.Attributes.Append(type);
|
||||
paragraph.AppendChild(time);
|
||||
|
||||
XmlNode text = xml.CreateElement("text");
|
||||
text.InnerText = HtmlUtil.RemoveHtmlTags(Utilities.UnbreakLine(p.Text), true);
|
||||
paragraph.AppendChild(text);
|
||||
|
||||
time = xml.CreateElement("lipsync");
|
||||
start = xml.CreateAttribute("timecode");
|
||||
start.InnerText = ToTimeCode(p.EndTime);
|
||||
time.Attributes.Append(start);
|
||||
type = xml.CreateAttribute("type");
|
||||
type.InnerText = "out_open";
|
||||
time.Attributes.Append(type);
|
||||
paragraph.AppendChild(time);
|
||||
|
||||
xml.DocumentElement.SelectSingleNode("body").AppendChild(paragraph);
|
||||
}
|
||||
|
||||
return ToUtf8XmlString(xml);
|
||||
}
|
||||
|
||||
private static string ToTimeCode(TimeCode tc)
|
||||
{
|
||||
return tc.ToHHMMSSFF();
|
||||
}
|
||||
|
||||
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("<detx") || !xmlString.Contains("<lipsync "))
|
||||
return;
|
||||
|
||||
var xml = new XmlDocument { XmlResolver = null };
|
||||
try
|
||||
{
|
||||
xml.LoadXml(xmlString);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (XmlNode node in xml.DocumentElement.SelectNodes("body/line"))
|
||||
{
|
||||
try
|
||||
{
|
||||
Paragraph p = new Paragraph();
|
||||
foreach (XmlNode innerNode in node.ChildNodes)
|
||||
{
|
||||
if (innerNode.Name == "text")
|
||||
{
|
||||
p.Text = (p.Text + Environment.NewLine + innerNode.InnerText).Trim();
|
||||
}
|
||||
else if (innerNode.Name == "lipsync")
|
||||
{
|
||||
var typeNode = innerNode.Attributes["type"];
|
||||
var timeCodeNode = innerNode.Attributes["timecode"];
|
||||
if (typeNode != null && timeCodeNode != null)
|
||||
{
|
||||
if (typeNode.InnerText == "in_open")
|
||||
{
|
||||
p.StartTime.TotalMilliseconds = TimeCode.ParseHHMMSSFFToMilliseconds(timeCodeNode.InnerText);
|
||||
}
|
||||
else if (typeNode.InnerText == "mpb")
|
||||
{
|
||||
p.EndTime.TotalMilliseconds = TimeCode.ParseHHMMSSFFToMilliseconds(timeCodeNode.InnerText);
|
||||
if (!string.IsNullOrWhiteSpace(p.Text))
|
||||
{
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
|
||||
p = new Paragraph();
|
||||
p.StartTime.TotalMilliseconds = TimeCode.ParseHHMMSSFFToMilliseconds(timeCodeNode.InnerText) + Configuration.Settings.General.MinimumMillisecondsBetweenLines;
|
||||
}
|
||||
else if (typeNode.InnerText == "out_open")
|
||||
{
|
||||
p.EndTime.TotalMilliseconds = TimeCode.ParseHHMMSSFFToMilliseconds(timeCodeNode.InnerText);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(p.Text))
|
||||
{
|
||||
subtitle.Paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
subtitle.Renumber();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -37,6 +37,7 @@ namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
new AvidCaption(),
|
||||
new AvidDvd(),
|
||||
new BelleNuitSubtitler(),
|
||||
new Cappella(),
|
||||
new CaptionAssistant(),
|
||||
new Captionate(),
|
||||
new CaptionateMs(),
|
||||
|
Loading…
Reference in New Issue
Block a user