Added a few new subtitle formats + fixed some settings + updated change log

git-svn-id: https://subtitleedit.googlecode.com/svn/trunk@821 99eadd0c-20b8-1223-b5c4-2a2b2df33de2
This commit is contained in:
niksedk 2011-11-28 12:33:38 +00:00
parent 17b7873666
commit 46a3ae3d98
10 changed files with 610 additions and 21 deletions

View File

@ -3,14 +3,16 @@ Subtitle Edit Changelog
3.2.3 (xth November 2011)
* NEW:
* Added Japanese language file - thx Nardog
* Added Spanish language file - thx m2s
* Support for subtitle format AvidCaption - thx Laszlo
* Export to Blu-ray sup format
* IMPROVED:
* Updated Tesseract to 3.01
Now includes italic + adds support for Arabic, Hebrew, Hindi, and Thai
* OCR tweaked a bit + BluRay sup files is processed faster
* OCR tweaked a bit + BluRay sup files are processed faster
* Subtitle format PAC much improved
* Subtitle format FCP Xml improved - thx Ulrik
* Splitting of lines - Thx Trottel
* FIXED:
* Fixed crash when setting Options - thx karmazyn
* Fixed crash in set color (or set font) - thx LEO33
@ -20,6 +22,7 @@ Subtitle Edit Changelog
* Fixed possible crash in spell check + German dictionary should work
* Fixed missing save/load of a fix common errors setting - thx menes
* Removed Microsoft translate as it's useless with new quotas
* Fixed milliseconds in timed text - thx Calle
3.2.2 (19th October 2011)

View File

@ -1451,10 +1451,22 @@ namespace Nikse.SubtitleEdit.Forms
}
}
if (Path.GetExtension(fileName).ToLower() == ".mkv")
if (Path.GetExtension(fileName).ToLower() == ".mkv" || Path.GetExtension(fileName).ToLower() == ".mks")
{
ImportSubtitleFromMatroskaFile();
return;
Matroska mkv = new Matroska();
bool isValid = false;
bool hasConstantFrameRate = false;
double frameRate = 0;
int width = 0;
int height = 0;
double milliseconds = 0;
string videoCodec = string.Empty;
mkv.GetMatroskaInfo(fileName, ref isValid, ref hasConstantFrameRate, ref frameRate, ref width, ref height, ref milliseconds, ref videoCodec);
if (isValid)
{
ImportSubtitleFromMatroskaFile();
return;
}
}
var fi = new FileInfo(fileName);
@ -9928,6 +9940,7 @@ namespace Nikse.SubtitleEdit.Forms
{
StringBuilder log = new StringBuilder();
var subtitles = BluRaySupParser.ParseBluRaySup(fileName, log);
subtitles = SplitBitmaps(subtitles);
if (subtitles.Count > 0)
{
var vobSubOcr = new VobSubOcr();
@ -9962,6 +9975,44 @@ namespace Nikse.SubtitleEdit.Forms
}
}
private List<BluRaySupPicture> SplitBitmaps(List<BluRaySupPicture> subtitles)
{
return subtitles;
var list = new List<BluRaySupPicture>();
int lastCompositionNumber = -1;
foreach (var sub in subtitles)
{
for (int i=0; i<sub.ImageObjects.Count; i++)
{
var s = new BluRaySupPicture(sub);
s.ObjectId = i;
if (s.CompositionNumber >= lastCompositionNumber)
{
int start = list.Count - 20;
if (start < 0)
start = 0;
bool found = false;
if (sub.ImageObjects.Count > 1)
{
for (int k = start; k < list.Count; k++)
{
if (list[k].ObjectIdImage.Width == sub.ObjectIdImage.Width && list[k].ObjectIdImage.Height == sub.ObjectIdImage.Height &&
list[k].ObjectIdImage.XOffset == sub.ObjectIdImage.XOffset && list[k].ObjectIdImage.YOffset == sub.ObjectIdImage.YOffset)
found = true;
}
}
if (!found)
list.Add(s);
}
lastCompositionNumber = s.CompositionNumber;
}
}
return list;
}
private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
{
if (textBoxListViewTextAlternate.Focused)

View File

@ -134,7 +134,7 @@ namespace Nikse.SubtitleEdit.Logic.BluRaySup
switch (segment.Type)
{
case 0x14: // Palette
log.AppendLine(string.Format("0x14 - Palette - PDS offset={0} size={1}", position, segment.Size));
log.Append(string.Format("0x14 - Palette - PDS offset={0} size={1}", position, segment.Size));
if (compNum != compNumOld)
{
@ -167,7 +167,7 @@ namespace Nikse.SubtitleEdit.Logic.BluRaySup
break;
case 0x15: // Image bitmap data
log.AppendLine(string.Format("0x15 - bitmap data - ODS offset={0} size={1}", position, segment.Size));
log.Append(string.Format("0x15 - bitmap data - ODS offset={0} size={1}", position, segment.Size));
if (compNum != compNumOld)
{
@ -201,7 +201,7 @@ namespace Nikse.SubtitleEdit.Logic.BluRaySup
break;
case 0x16:
log.AppendLine(string.Format("0x16 - Time codes, offset={0} size={1}", position, segment.Size));
log.Append(string.Format("0x16 - Time codes, offset={0} size={1}", position, segment.Size));
compNum = BigEndianInt16(buffer, 5);
cs = GetCompositionState(buffer[7]);
@ -234,7 +234,7 @@ namespace Nikse.SubtitleEdit.Logic.BluRaySup
pic = new BluRaySupPicture();
subPictures.Add(pic); // add to list
pic.StartTime = segment.PtsTimestamp;
log.AppendLine("#> " + (subPictures.Count) + " (" + ToolBox.PtsToTimeString(pic.StartTime) + ")");
log.Append("#> " + (subPictures.Count) + " (" + ToolBox.PtsToTimeString(pic.StartTime) + ")");
so[0] = null;
ParsePcs(segment, pic, so, buffer);
@ -243,10 +243,8 @@ namespace Nikse.SubtitleEdit.Logic.BluRaySup
picLast.EndTime = pic.StartTime;
if (so[0] != null)
log.AppendLine(", " + so[0]);
else
log.AppendLine();
log.Append(Environment.NewLine + "PTS start: " + ToolBox.PtsToTimeString(pic.StartTime));
log.Append(", " + so[0]);
log.Append(", PTS start: " + ToolBox.PtsToTimeString(pic.StartTime));
log.AppendLine(", screen size: " + pic.Width + "*" + pic.Height);
odsCtr = 0;
pdsCtr = 0;
@ -274,7 +272,7 @@ namespace Nikse.SubtitleEdit.Logic.BluRaySup
log.AppendLine(" NORM, ");
break;
}
log.AppendLine("size: " + segment.Size + ", comp#: " + compNum + ", forced: " + pic.IsForced);
log.Append("size: " + segment.Size + ", comp#: " + compNum + ", forced: " + pic.IsForced);
if (compNum != compNumOld)
{
so[0] = null;
@ -285,25 +283,25 @@ namespace Nikse.SubtitleEdit.Logic.BluRaySup
ParsePcs(segment, pic, so, buffer);
}
if (so[0] != null)
log.AppendLine(", " + so[0]);
log.Append(", " + so[0]);
log.AppendLine(", pal update: " + paletteUpdate);
log.AppendLine("PTS: " + ToolBox.PtsToTimeString(segment.PtsTimestamp));
}
break;
case 0x17:
log.AppendLine(string.Format("0x17 - WDS offset={0} size={1}", position, segment.Size));
log.Append(string.Format("0x17 - WDS offset={0} size={1}", position, segment.Size));
int x = BigEndianInt16(buffer, 2);
int y = BigEndianInt16(buffer, 4);
int width = BigEndianInt16(buffer, 6);
int height = BigEndianInt16(buffer, 8);
log.AppendLine(string.Format("width:{0}, height:{1}", width, height));
log.AppendLine(string.Format(", width:{0}, height:{1} x,y={2},{3}", width, height, x, y));
break;
case 0x80:
log.AppendLine(string.Format("0x18 - END offset={0} size={1}", position, segment.Size));
log.Append(string.Format("0x80 - END offset={0} size={1}", position, segment.Size));
// decide whether to store this last composition section as caption or merge it
if (cs == CompositionState.EpochStart)
@ -373,6 +371,7 @@ namespace Nikse.SubtitleEdit.Logic.BluRaySup
position += segment.Size;
i++;
}
// File.WriteAllText(@"C:\Users\Nikse\Desktop\Blu-Ray Sup\log.txt", log.ToString());
return subPictures;
}

View File

@ -300,7 +300,7 @@ namespace Nikse.SubtitleEdit.Logic
SubtitleFontColor = System.Drawing.Color.Black;
SubtitleBackgroundColor = System.Drawing.Color.White;
DefaultEncoding = "UTF-8";
AutoGuessAnsiEncoding = false;
AutoGuessAnsiEncoding = true;
ShowRecentFiles = true;
RememberSelectedLine = true;
StartLoadLastFile = true;
@ -480,7 +480,7 @@ namespace Nikse.SubtitleEdit.Logic
MainTextBoxItalic = "Control+I";
MainAdjustSetStartAndOffsetTheRest = "Control+Space";
MainAdjustSetEndAndGotoNext = "Shift+Space";
MainAdjustViaEndAutoStartAndGoToNext = "Shift+End";
MainAdjustViaEndAutoStartAndGoToNext = string.Empty;
MainAdjustSetStartAutoDurationAndGoToNext = string.Empty;
MainInsertAfter = "Alt+Ins";
MainInsertBefore = "Control+Shift+Ins";
@ -1528,7 +1528,7 @@ namespace Nikse.SubtitleEdit.Logic
textWriter.WriteElementString("MainAdjustSetStartAndOffsetTheRest", settings.Shortcuts.MainAdjustSetStartAndOffsetTheRest);
textWriter.WriteElementString("MainAdjustSetEndAndGotoNext", settings.Shortcuts.MainAdjustSetEndAndGotoNext);
textWriter.WriteElementString("MainAdjustViaEndAutoStartAndGoToNext", settings.Shortcuts.MainAdjustViaEndAutoStartAndGoToNext);
textWriter.WriteElementString("MainAdjustSetStartAutoDurationAndGoToNext", settings.Shortcuts.MainAdjustViaEndAutoStartAndGoToNext);
textWriter.WriteElementString("MainAdjustSetStartAutoDurationAndGoToNext", settings.Shortcuts.MainAdjustSetStartAutoDurationAndGoToNext);
textWriter.WriteElementString("MainInsertAfter", settings.Shortcuts.MainInsertAfter);
textWriter.WriteElementString("MainInsertBefore", settings.Shortcuts.MainInsertBefore);
textWriter.WriteElementString("MainGoToNext", settings.Shortcuts.MainGoToNext);

View File

@ -60,9 +60,11 @@ namespace Nikse.SubtitleEdit.Logic.SubtitleFormats
new TimedText(),
new TimedText10(),
new TimeXml(),
new TmpegEncText(),
new TmpegEncXml(),
new TMPlayer(),
new TranscriberXml(),
new TurboTitler(),
new TMPlayer(),
// new Idx(),
new UleadSubtitleFormat(),
new UnknownSubtitle1(),
@ -74,6 +76,7 @@ namespace Nikse.SubtitleEdit.Logic.SubtitleFormats
new UnknownSubtitle7(),
new UnknownSubtitle8(),
new UnknownSubtitle9(),
new UnknownSubtitle10(),
new UTSubtitleXml(),
new Utx(),
new UtxFrames(),

View File

@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Nikse.SubtitleEdit.Logic.SubtitleFormats
{
public class TmpegEncText : SubtitleFormat
{
public override string Extension
{
get { return ".subtitle"; }
}
public override string Name
{
get { return "Tmpeg Encoder Text"; }
}
public override bool HasLineNumber
{
get { return true; }
}
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 > _errorCount;
}
public override string ToText(Subtitle subtitle, string title)
{
var sb = new StringBuilder();
sb.AppendLine(@"[LayoutData]
'Picture bottom layout',4,Tahoma,0.069,17588159451135,0,0,0,0,1,2,0,1,0.00345,0
'Picture top layout',4,Tahoma,0.1,17588159451135,0,0,0,0,1,0,0,1,0.005,0
'Picture left layout',4,Tahoma,0.1,17588159451135,0,0,0,0,0,1,1,1,0.005,0
'Picture right layout',4,Tahoma,0.1,17588159451135,0,0,0,0,2,1,1,1,0.005,0
[LayoutDataEx]
1,0
1,0
1,0
1,1
[ItemData]").Replace("'", "\"");
int i = 0;
foreach (Paragraph p in subtitle.Paragraphs)
{
i++;
sb.AppendLine(string.Format("{0},1,\"{1}\",\"{2}\",0,\"{3}\"", i, p.StartTime, p.EndTime, p.Text.Replace(Environment.NewLine, "\\n").Replace("\"",string.Empty)));
}
return sb.ToString().Trim() + Environment.NewLine;
}
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
{
//1,1,"00:01:57,269","00:01:59,169",0,"These hills here are full of Apaches."
StringBuilder temp = new StringBuilder();
foreach (string l in lines)
temp.Append(l);
string all = temp.ToString();
if (!all.Contains("[ItemData]"))
return;
Paragraph paragraph = new Paragraph();
_errorCount = 0;
subtitle.Paragraphs.Clear();
for (int i = 0; i < lines.Count; i++)
{
string line = lines[i].Trim();
var arr = line.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
if (arr.Length >= 8 && Utilities.IsInteger(arr[0]) && Utilities.IsInteger(arr[1]))
{
Paragraph p = new Paragraph();
try
{
p.StartTime = GetTimeCode(arr[2] + "," + arr[3]);
p.EndTime = GetTimeCode(arr[4] + "," + arr[5]);
p.Text = line.Trim().TrimEnd('"');
p.Text = p.Text.Substring(p.Text.LastIndexOf('"')).TrimStart('"');
p.Text = p.Text.Replace("\\n", Environment.NewLine);
subtitle.Paragraphs.Add(p);
}
catch (Exception exception)
{
System.Diagnostics.Debug.WriteLine(exception.Message);
_errorCount++;
}
}
}
subtitle.Renumber(1);
}
private TimeCode GetTimeCode(string code)
{
code = code.Trim().Trim('"');
var arr = code.Split(":.,".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
int h = int.Parse(arr[0]);
int m = int.Parse(arr[1]);
int s = int.Parse(arr[2]);
int ms = int.Parse(arr[3]);
TimeSpan ts = new TimeSpan(0, h, m, s, ms);
return new TimeCode(ts);
}
}
}

View File

@ -0,0 +1,288 @@
using System.Text;
using System.Xml;
using System;
using System.IO;
using System.Collections.Generic;
namespace Nikse.SubtitleEdit.Logic.SubtitleFormats
{
//<TMPGEncVMESubtitleTextFormat>
// ...
// <Subtitle>
// <SubtitleItem layoutindex="0" enable="1" starttime="00:01:57,269" endtime="00:01:59,169">
// <Text>
// <![CDATA[These hills here are full of Apaches.]]>
// </Text>
// </SubtitleItem>
// ...
class TmpegEncXml : SubtitleFormat
{
public override string Extension
{
get { return ".xsubtitle"; }
}
public override string Name
{
get { return "TMPGEnc VME"; }
}
public override bool HasLineNumber
{
get { return false; }
}
public override bool IsTimeBased
{
get { return true; }
}
public override bool IsMine(List<string> lines, string fileName)
{
StringBuilder sb = new StringBuilder();
lines.ForEach(line => sb.AppendLine(line));
string xmlAsString = sb.ToString().Trim();
if ((xmlAsString.Contains("<TMPGEncVMESubtitleTextFormat>") || xmlAsString.Contains("<SubtitleItem ")) && (xmlAsString.Contains("<Subtitle")))
{
var xml = new XmlDocument();
try
{
xml.LoadXml(xmlAsString);
var paragraphs = xml.DocumentElement.SelectNodes("Subtitle/SubtitleItem");
return paragraphs != null && paragraphs.Count > 0 && xml.DocumentElement.Name == "TMPGEncVMESubtitleTextFormat";
}
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' ?>
<TMPGEncVMESubtitleTextFormat>
<Layout>
<LayoutItem index='0'>
<Name>
<![CDATA[Picture bottom layout]]>
</Name>
<Position>4</Position>
<FontName>
<![CDATA[Tahoma]]>
</FontName>
<FontHeight>0.069</FontHeight>
<FontColor>17588159451135</FontColor>
<FontBold>0</FontBold>
<FontItalic>0</FontItalic>
<FontUnderline>0</FontUnderline>
<FontStrikeOut>0</FontStrikeOut>
<HorizonAlign>1</HorizonAlign>
<VerticalAlign>2</VerticalAlign>
<DirectionVertical>0</DirectionVertical>
<BorderActive>1</BorderActive>
<BorderSize>0.00345</BorderSize>
<BorderColor>0</BorderColor>
<TextAlign>1</TextAlign>
<DirectionRightToLeft>0</DirectionRightToLeft>
</LayoutItem>
<LayoutItem index='1'>
<Name>
<![CDATA[Picture top layout]]>
</Name>
<Position>4</Position>
<FontName>
<![CDATA[Tahoma]]>
</FontName>
<FontHeight>0.1</FontHeight>
<FontColor>17588159451135</FontColor>
<FontBold>0</FontBold>
<FontItalic>0</FontItalic>
<FontUnderline>0</FontUnderline>
<FontStrikeOut>0</FontStrikeOut>
<HorizonAlign>1</HorizonAlign>
<VerticalAlign>0</VerticalAlign>
<DirectionVertical>0</DirectionVertical>
<BorderActive>1</BorderActive>
<BorderSize>0.005</BorderSize>
<BorderColor>0</BorderColor>
<TextAlign>1</TextAlign>
<DirectionRightToLeft>0</DirectionRightToLeft>
</LayoutItem>
<LayoutItem index='2'>
<Name>
<![CDATA[Picture left layout]]>
</Name>
<Position>4</Position>
<FontName>
<![CDATA[Tahoma]]>
</FontName>
<FontHeight>0.1</FontHeight>
<FontColor>17588159451135</FontColor>
<FontBold>0</FontBold>
<FontItalic>0</FontItalic>
<FontUnderline>0</FontUnderline>
<FontStrikeOut>0</FontStrikeOut>
<HorizonAlign>0</HorizonAlign>
<VerticalAlign>1</VerticalAlign>
<DirectionVertical>1</DirectionVertical>
<BorderActive>1</BorderActive>
<BorderSize>0.005</BorderSize>
<BorderColor>0</BorderColor>
<TextAlign>1</TextAlign>
<DirectionRightToLeft>0</DirectionRightToLeft>
</LayoutItem>
<LayoutItem index='3'>
<Name>
<![CDATA[Picture right layout]]>
</Name>
<Position>4</Position>
<FontName>
<![CDATA[Tahoma]]>
</FontName>
<FontHeight>0.1</FontHeight>
<FontColor>17588159451135</FontColor>
<FontBold>0</FontBold>
<FontItalic>0</FontItalic>
<FontUnderline>0</FontUnderline>
<FontStrikeOut>0</FontStrikeOut>
<HorizonAlign>2</HorizonAlign>
<VerticalAlign>1</VerticalAlign>
<DirectionVertical>1</DirectionVertical>
<BorderActive>1</BorderActive>
<BorderSize>0.005</BorderSize>
<BorderColor>0</BorderColor>
<TextAlign>1</TextAlign>
<DirectionRightToLeft>1</DirectionRightToLeft>
</LayoutItem>
</Layout>
<Subtitle>
</Subtitle>
</TMPGEncVMESubtitleTextFormat>".Replace("'", "\"");
var xml = new XmlDocument();
xml.LoadXml(xmlStructure);
XmlNode div = xml.DocumentElement.SelectSingleNode("Subtitle");
int no = 0;
foreach (Paragraph p in subtitle.Paragraphs)
{
XmlNode paragraph = xml.CreateElement("SubtitleItem");
string text = Utilities.RemoveHtmlTags(p.Text);
paragraph.InnerXml = "<Text><![CDATA[" + text.Replace(Environment.NewLine, "\\n") + "]]></Text>";
XmlAttribute layoutIndex = xml.CreateAttribute("layoutindex");
layoutIndex.InnerText = "0";
paragraph.Attributes.Append(layoutIndex);
XmlAttribute enable = xml.CreateAttribute("enable");
enable.InnerText = "1";
paragraph.Attributes.Append(enable);
XmlAttribute start = xml.CreateAttribute("starttime");
start.InnerText = p.StartTime.ToString();
paragraph.Attributes.Append(start);
XmlAttribute end = xml.CreateAttribute("endtime");
end.InnerText = p.EndTime.ToString();
paragraph.Attributes.Append(end);
div.AppendChild(paragraph);
no++;
}
MemoryStream ms = new MemoryStream();
XmlTextWriter writer = new XmlTextWriter(ms, Encoding.UTF8);
writer.Formatting = Formatting.Indented;
xml.Save(writer);
return Encoding.UTF8.GetString(ms.ToArray()).Trim();
}
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
{
_errorCount = 0;
double startSeconds = 0;
StringBuilder sb = new StringBuilder();
lines.ForEach(line => sb.AppendLine(line));
XmlDocument xml = new XmlDocument();
xml.LoadXml(sb.ToString());
foreach (XmlNode node in xml.DocumentElement.SelectNodes("Subtitle/SubtitleItem"))
{
try
{
StringBuilder pText = new StringBuilder();
foreach (XmlNode innerNode in node.SelectSingleNode("Text").ChildNodes)
{
switch (innerNode.Name.ToString())
{
case "br":
pText.AppendLine();
break;
default:
pText.Append(innerNode.InnerText.Trim());
break;
}
}
string start = string.Empty;
if (node.Attributes["starttime"] != null)
{
start = node.Attributes["starttime"].InnerText;
}
string end = string.Empty;
if (node.Attributes["endtime"] != null)
{
end = node.Attributes["endtime"].InnerText;
}
TimeCode startCode = new TimeCode(TimeSpan.FromSeconds(startSeconds));
if (start != string.Empty)
{
startCode = GetTimeCode(start);
}
TimeCode endCode;
if (end != string.Empty)
{
endCode = GetTimeCode(end);
}
else
{
endCode = new TimeCode(TimeSpan.FromMilliseconds(startCode.TotalMilliseconds + 3000));
}
startSeconds = endCode.TotalSeconds;
subtitle.Paragraphs.Add(new Paragraph(startCode, endCode, pText.ToString().Trim().Replace("<Text>", string.Empty).Replace("</Text>", string.Empty).Replace("\\n", Environment.NewLine)));
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
_errorCount++;
}
}
subtitle.Renumber(1);
}
private static TimeCode GetTimeCode(string s)
{
if (s.EndsWith("s"))
{
s = s.TrimEnd('s');
TimeSpan ts = TimeSpan.FromSeconds(double.Parse(s));
return new TimeCode(ts);
}
else
{
string[] parts = s.Split(new char[] { ':', '.', ',' });
TimeSpan ts = new TimeSpan(0, int.Parse(parts[0]), int.Parse(parts[1]), int.Parse(parts[2]), int.Parse(parts[3]));
return new TimeCode(ts);
}
}
}
}

View File

@ -0,0 +1,127 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace Nikse.SubtitleEdit.Logic.SubtitleFormats
{
public class UnknownSubtitle10 : SubtitleFormat
{
public override string Extension
{
get { return ".txt"; }
}
public override string Name
{
get { return "Unknown 10"; }
}
public override bool HasLineNumber
{
get { return false; }
}
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 > _errorCount;
}
public override string ToText(Subtitle subtitle, string title)
{
var sb = new StringBuilder();
sb.Append("{\"language_code\":\"en\",\"subtitles\":[");
int i = 0;
foreach (Paragraph p in subtitle.Paragraphs)
{
if (i > 0)
sb.Append(",");
sb.Append("{");
sb.Append(string.Format("\"content\":\"{0}\",\"start_time\":{1},\"end_time\":{2}", p.Text.Replace(Environment.NewLine, " <br> "), p.StartTime.TotalMilliseconds, p.EndTime.TotalMilliseconds));
sb.Append("}");
i++;
}
sb.Append("]}");
return sb.ToString().Trim();
}
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
{
StringBuilder temp = new StringBuilder();
foreach (string l in lines)
temp.Append(l);
string all = temp.ToString();
if (!all.Contains("{\"content\":\""))
return;
var arr = all.Replace("\n", string.Empty).Replace("{\"content\":\"", "\n").Split("\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
_errorCount = 0;
subtitle.Paragraphs.Clear();
// {"content":"La ce se gandeste Oh Ha Ni a noastra <br> de la inceputul dimineti?","start_time":314071,"end_time":317833},
for (int i = 0; i < arr.Length; i++)
{
string line = arr[i].Trim();
int indexStartTime = line.IndexOf("\"start_time\":");
int indexEndTime = line.IndexOf("\"end_time\":");
if (indexStartTime > 0 && indexEndTime > 0)
{
int indexEndText = indexStartTime;
if (indexStartTime > indexEndTime)
indexEndText = indexEndTime;
string text = line.Substring(0, indexEndText - 1).Trim().TrimEnd('\"');
text = text.Replace("<br>", Environment.NewLine).Replace("<BR>", Environment.NewLine);
text = text.Replace("<br/>", Environment.NewLine).Replace("<BR/>", Environment.NewLine);
text = text.Replace(Environment.NewLine + " ", Environment.NewLine);
text = text.Replace(Environment.NewLine + " ", Environment.NewLine);
text = text.Replace(Environment.NewLine + " ", Environment.NewLine);
text = text.Replace(" " + Environment.NewLine, Environment.NewLine);
text = text.Replace(" " + Environment.NewLine, Environment.NewLine);
text = text.Replace(" " + Environment.NewLine, Environment.NewLine);
try
{
string start = line.Substring(indexStartTime);
string end = line.Substring(indexEndTime);
Paragraph paragraph = new Paragraph();
paragraph.Text = text;
paragraph.StartTime.TotalMilliseconds = GetMilliseconds(start);
paragraph.EndTime.TotalMilliseconds = GetMilliseconds(end);
subtitle.Paragraphs.Add(paragraph);
}
catch (Exception exception)
{
System.Diagnostics.Debug.WriteLine(exception.Message);
_errorCount++;
}
}
}
subtitle.Renumber(1);
}
private double GetMilliseconds(string start)
{
while (start.Length > 1 && !start.StartsWith(":"))
start = start.Remove(0, 1);
start = start.Trim().Trim(':').Trim('"').Trim();
int i = 0;
while (i < start.Length && "0123456789".Contains(start[i].ToString()))
i++;
return int.Parse(start.Substring(0, i));
}
}
}

View File

@ -1113,6 +1113,7 @@ namespace Nikse.SubtitleEdit.Logic
sb.Append("*.mp4;"); // mp4 video files (can contain subtitles)
sb.Append("*.m4v;"); // mp4 video files (can contain subtitles)
sb.Append("*.mkv;"); // matroska files (can contain subtitles)
sb.Append("*.mks;"); // matroska subtitlefiles (normally contain subtitles)
sb.Append("*.sup;"); // blu-ray sup
sb.Append("*.son"); // SON text/tif
sb.Append("|" + Configuration.Settings.Language.General.AllFiles + "|*.*");

View File

@ -612,9 +612,12 @@
<Compile Include="Logic\SubtitleFormats\StructuredTitles.cs" />
<Compile Include="Logic\SubtitleFormats\SubtitleEditorProject.cs" />
<Compile Include="Logic\SubtitleFormats\TimedText10.cs" />
<Compile Include="Logic\SubtitleFormats\TmpegEncText.cs" />
<Compile Include="Logic\SubtitleFormats\TmpegEncXml.cs" />
<Compile Include="Logic\SubtitleFormats\TranscriberXml.cs" />
<Compile Include="Logic\SubtitleFormats\TurboTitler.cs" />
<Compile Include="Logic\SubtitleFormats\UleadSubtitleFormat.cs" />
<Compile Include="Logic\SubtitleFormats\UnknownSubtitle10.cs" />
<Compile Include="Logic\SubtitleFormats\UnknownSubtitle5.cs" />
<Compile Include="Logic\SubtitleFormats\OpenDvt.cs" />
<Compile Include="Logic\SubtitleFormats\AbcIViewer.cs" />