mirror of
https://github.com/SubtitleEdit/subtitleedit.git
synced 2024-10-27 22:42:38 +01:00
Add some support for ismt dfxp
This commit is contained in:
parent
4173a4b382
commit
d1212c005e
@ -2,6 +2,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.ContainerFormats.Mp4
|
||||
{
|
||||
@ -164,5 +165,40 @@ namespace Nikse.SubtitleEdit.Core.ContainerFormats.Mp4
|
||||
}
|
||||
}
|
||||
|
||||
public List<string> GetMdatsAsStrings()
|
||||
{
|
||||
var list = new List<string>();
|
||||
using (var fs = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
Position = 0;
|
||||
fs.Seek(0, SeekOrigin.Begin);
|
||||
bool moreBytes = true;
|
||||
while (moreBytes)
|
||||
{
|
||||
moreBytes = InitializeSizeAndName(fs);
|
||||
if (Size < 8)
|
||||
return list;
|
||||
|
||||
if (Name == "mdat")
|
||||
{
|
||||
var before = (long)fs.Position;
|
||||
var readLength = ((long)Position) - before;
|
||||
if (readLength > 10)
|
||||
{
|
||||
var buffer = new byte[readLength];
|
||||
fs.Read(buffer, 0, (int)readLength);
|
||||
list.Add(Encoding.UTF8.GetString(buffer));
|
||||
}
|
||||
}
|
||||
|
||||
if (Position > (ulong)fs.Length)
|
||||
break;
|
||||
fs.Seek((long)Position, SeekOrigin.Begin);
|
||||
}
|
||||
fs.Close();
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
100
libse/Forms/MergeLinesWithSameTimeCodes.cs
Normal file
100
libse/Forms/MergeLinesWithSameTimeCodes.cs
Normal file
@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.Forms
|
||||
{
|
||||
public static class MergeLinesWithSameTimeCodes
|
||||
{
|
||||
public static Subtitle Merge(Subtitle subtitle, List<int> mergedIndexes, out int numberOfMerges, bool clearFixes, bool reBreak, int maxMsBetween, string language, List<int> removed, Dictionary<int, bool> isFixAllowedList, Subtitle info)
|
||||
{
|
||||
numberOfMerges = 0;
|
||||
var mergedSubtitle = new Subtitle();
|
||||
bool lastMerged = false;
|
||||
Paragraph p = null;
|
||||
var lineNumbers = new StringBuilder();
|
||||
for (int i = 1; i < subtitle.Paragraphs.Count; i++)
|
||||
{
|
||||
if (!lastMerged)
|
||||
{
|
||||
p = new Paragraph(subtitle.GetParagraphOrDefault(i - 1));
|
||||
mergedSubtitle.Paragraphs.Add(p);
|
||||
}
|
||||
Paragraph next = subtitle.GetParagraphOrDefault(i);
|
||||
if (next != null)
|
||||
{
|
||||
if (QualifiesForMerge(p, next, maxMsBetween) && IsFixAllowed(p, isFixAllowedList))
|
||||
{
|
||||
if (p.Text.StartsWith("<i>", StringComparison.Ordinal) && p.Text.EndsWith("</i>", StringComparison.Ordinal) && next.Text.StartsWith("<i>", StringComparison.Ordinal) && next.Text.EndsWith("</i>", StringComparison.Ordinal))
|
||||
{
|
||||
p.Text = p.Text.Remove(p.Text.Length - 4) + Environment.NewLine + next.Text.Remove(0, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
p.Text = p.Text + Environment.NewLine + next.Text;
|
||||
}
|
||||
if (reBreak)
|
||||
p.Text = Utilities.AutoBreakLine(p.Text, language);
|
||||
lastMerged = true;
|
||||
removed.Add(i);
|
||||
numberOfMerges++;
|
||||
if (!mergedIndexes.Contains(i))
|
||||
mergedIndexes.Add(i);
|
||||
if (!mergedIndexes.Contains(i - 1))
|
||||
mergedIndexes.Add(i - 1);
|
||||
|
||||
if (!("," + lineNumbers).Contains("," + p.Number + ","))
|
||||
{
|
||||
lineNumbers.Append(p.Number);
|
||||
lineNumbers.Append(',');
|
||||
}
|
||||
if (!("," + lineNumbers).Contains("," + next.Number + ","))
|
||||
{
|
||||
lineNumbers.Append(next.Number);
|
||||
lineNumbers.Append(',');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lastMerged = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lastMerged = false;
|
||||
}
|
||||
|
||||
if (!removed.Contains(i) && lineNumbers.Length > 0 && clearFixes)
|
||||
{
|
||||
info.Paragraphs.Add(new Paragraph(p) { Extra = lineNumbers.ToString() });
|
||||
lineNumbers.Clear();
|
||||
}
|
||||
}
|
||||
if (lineNumbers.Length > 0 && clearFixes && p != null)
|
||||
{
|
||||
info.Paragraphs.Add(new Paragraph(p) { Extra = lineNumbers.ToString() });
|
||||
}
|
||||
if (!lastMerged)
|
||||
mergedSubtitle.Paragraphs.Add(new Paragraph(subtitle.GetParagraphOrDefault(subtitle.Paragraphs.Count - 1)));
|
||||
|
||||
mergedSubtitle.Renumber();
|
||||
return mergedSubtitle;
|
||||
}
|
||||
|
||||
private static bool QualifiesForMerge(Paragraph p, Paragraph next, int maxMsBetween)
|
||||
{
|
||||
if (p == null || next == null)
|
||||
return false;
|
||||
|
||||
return Math.Abs(next.StartTime.TotalMilliseconds - p.StartTime.TotalMilliseconds) <= maxMsBetween &&
|
||||
Math.Abs(next.EndTime.TotalMilliseconds - p.EndTime.TotalMilliseconds) <= maxMsBetween;
|
||||
}
|
||||
|
||||
private static bool IsFixAllowed(Paragraph p, Dictionary<int, bool> isFixAllowedList)
|
||||
{
|
||||
if (isFixAllowedList.ContainsKey(p.Number))
|
||||
return isFixAllowedList[p.Number];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -169,6 +169,7 @@
|
||||
<Compile Include="Forms\FixCommonErrors\FixUnneededSpaces.cs" />
|
||||
<Compile Include="Forms\FixCommonErrors\FixUppercaseIInsideWords.cs" />
|
||||
<Compile Include="Forms\FixCommonErrors\Helper.cs" />
|
||||
<Compile Include="Forms\MergeLinesWithSameTimeCodes.cs" />
|
||||
<Compile Include="Interfaces\IBinaryPersistableSubtitle.cs" />
|
||||
<Compile Include="Interfaces\IFixCallbacks.cs" />
|
||||
<Compile Include="Interfaces\IFixCommonError.cs" />
|
||||
@ -233,6 +234,7 @@
|
||||
<Compile Include="SubtitleFormats\Csv5.cs" />
|
||||
<Compile Include="SubtitleFormats\DvdStudioProSpaceOneSemicolon.cs" />
|
||||
<Compile Include="SubtitleFormats\FinalCutProXml15.cs" />
|
||||
<Compile Include="SubtitleFormats\IsmtDfxp.cs" />
|
||||
<Compile Include="SubtitleFormats\JsonType12.cs" />
|
||||
<Compile Include="SubtitleFormats\TimeCodesOnly2.cs" />
|
||||
<Compile Include="SubtitleFormats\Rtf1.cs" />
|
||||
|
72
libse/SubtitleFormats/IsmtDfxp.cs
Normal file
72
libse/SubtitleFormats/IsmtDfxp.cs
Normal file
@ -0,0 +1,72 @@
|
||||
using Nikse.SubtitleEdit.Core.ContainerFormats.Mp4;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
|
||||
{
|
||||
public class IsmtDfxp : SubtitleFormat
|
||||
{
|
||||
public override string Extension => ".ismt";
|
||||
|
||||
public override string Name => "HBO GO";
|
||||
|
||||
public override bool IsMine(List<string> lines, string fileName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(fileName))
|
||||
return false;
|
||||
|
||||
using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
var buffer = new byte[12];
|
||||
int l = fs.Read(buffer, 0, buffer.Length);
|
||||
if (l != buffer.Length)
|
||||
return false;
|
||||
var str = Encoding.ASCII.GetString(buffer, 4, 8);
|
||||
if (str != "ftypisml")
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
|
||||
{
|
||||
_errorCount = 0;
|
||||
var mp4Parser = new MP4Parser(fileName);
|
||||
var dfxpStrings = mp4Parser.GetMdatsAsStrings();
|
||||
foreach (var xmlAsString in dfxpStrings)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sub = new Subtitle();
|
||||
var format = new TimedText();
|
||||
sub.ReloadLoadSubtitle(xmlAsString.SplitToLines().ToList(), null, format);
|
||||
|
||||
if (sub.Paragraphs.Count == 0)
|
||||
continue;
|
||||
|
||||
// merge lines with same time codes
|
||||
int numberOfMerges;
|
||||
sub = Forms.MergeLinesWithSameTimeCodes.Merge(sub, new List<int>(), out numberOfMerges, true, false, 1000, "en", new List<int>(), new Dictionary<int, bool>(), new Subtitle());
|
||||
|
||||
// adjust to last exisiting sub
|
||||
var lastSub = subtitle.GetParagraphOrDefault(subtitle.Paragraphs.Count - 1);
|
||||
if (lastSub != null)
|
||||
sub.AddTimeToAllParagraphs(lastSub.EndTime.TimeSpan);
|
||||
|
||||
subtitle.Paragraphs.AddRange(sub.Paragraphs);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToText(Subtitle subtitle, string title)
|
||||
{
|
||||
return "Not supported";
|
||||
}
|
||||
}
|
||||
}
|
@ -1929,9 +1929,12 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
|
||||
if ((ext == ".mp4" || ext == ".m4v" || ext == ".3gp") && file.Length > 10000)
|
||||
{
|
||||
if (ImportSubtitleFromMp4(fileName) && !Configuration.Settings.General.DisableVideoAutoLoading)
|
||||
OpenVideo(fileName);
|
||||
return;
|
||||
if (!new IsmtDfxp().IsMine(null, fileName))
|
||||
{
|
||||
if (ImportSubtitleFromMp4(fileName) && !Configuration.Settings.General.DisableVideoAutoLoading)
|
||||
OpenVideo(fileName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ext == ".mxf" && FileUtil.IsMaterialExchangeFormat(fileName))
|
||||
@ -2692,6 +2695,20 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
}
|
||||
}
|
||||
|
||||
if (format == null)
|
||||
{
|
||||
var f = new IsmtDfxp();
|
||||
if (f.IsMine(null, fileName))
|
||||
{
|
||||
f.LoadSubtitle(_subtitle, null, fileName);
|
||||
_oldSubtitleFormat = f;
|
||||
SetCurrentFormat(Configuration.Settings.General.DefaultSubtitleFormat);
|
||||
SetEncoding(Configuration.Settings.General.DefaultEncoding);
|
||||
encoding = GetCurrentEncoding();
|
||||
justConverted = true;
|
||||
format = GetCurrentSubtitleFormat();
|
||||
}
|
||||
}
|
||||
|
||||
// retry vobsub (file with wrong extension)
|
||||
if (format == null && file.Length > 500 && IsVobSubFile(fileName, false))
|
||||
|
@ -96,7 +96,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
SubtitleListview1.Items.Clear();
|
||||
SubtitleListview1.BeginUpdate();
|
||||
int count;
|
||||
_mergedSubtitle = MergeLinesWithSameTimeCodes(_subtitle, mergedIndexes, out count, true, checkBoxAutoBreakOn.Checked, (int)numericUpDownMaxMillisecondsBetweenLines.Value);
|
||||
_mergedSubtitle = MergeLinesWithSameTimeCodes(_subtitle, mergedIndexes, out count, true, checkBoxAutoBreakOn.Checked, (int)numericUpDownMaxMillisecondsBetweenLines.Value, _language);
|
||||
NumberOfMerges = count;
|
||||
|
||||
SubtitleListview1.Fill(_subtitle);
|
||||
@ -108,13 +108,6 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
groupBoxLinesFound.Text = string.Format(Configuration.Settings.Language.MergeTextWithSameTimeCodes.NumberOfMergesX, NumberOfMerges);
|
||||
}
|
||||
|
||||
private bool IsFixAllowed(Paragraph p)
|
||||
{
|
||||
if (_isFixAllowedList.ContainsKey(p.Number))
|
||||
return _isFixAllowedList[p.Number];
|
||||
return true;
|
||||
}
|
||||
|
||||
private void listViewFixes_ItemChecked(object sender, ItemCheckedEventArgs e)
|
||||
{
|
||||
if (_loading)
|
||||
@ -134,7 +127,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
SubtitleListview1.Items.Clear();
|
||||
SubtitleListview1.BeginUpdate();
|
||||
int count;
|
||||
_mergedSubtitle = MergeLinesWithSameTimeCodes(_subtitle, mergedIndexes, out count, false, checkBoxAutoBreakOn.Checked, (int)numericUpDownMaxMillisecondsBetweenLines.Value);
|
||||
_mergedSubtitle = MergeLinesWithSameTimeCodes(_subtitle, mergedIndexes, out count, false, checkBoxAutoBreakOn.Checked, (int)numericUpDownMaxMillisecondsBetweenLines.Value, _language);
|
||||
NumberOfMerges = count;
|
||||
SubtitleListview1.Fill(_subtitle);
|
||||
foreach (var index in mergedIndexes)
|
||||
@ -146,7 +139,7 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
groupBoxLinesFound.Text = string.Format(Configuration.Settings.Language.MergeTextWithSameTimeCodes.NumberOfMergesX, NumberOfMerges);
|
||||
}
|
||||
|
||||
public Subtitle MergeLinesWithSameTimeCodes(Subtitle subtitle, List<int> mergedIndexes, out int numberOfMerges, bool clearFixes, bool reBreak, int maxMsBetween)
|
||||
public Subtitle MergeLinesWithSameTimeCodes(Subtitle subtitle, List<int> mergedIndexes, out int numberOfMerges, bool clearFixes, bool reBreak, int maxMsBetween, string language)
|
||||
{
|
||||
listViewFixes.BeginUpdate();
|
||||
var removed = new List<int>();
|
||||
@ -157,90 +150,16 @@ namespace Nikse.SubtitleEdit.Forms
|
||||
listViewFixes.Items.Clear();
|
||||
_isFixAllowedList = new Dictionary<int, bool>();
|
||||
}
|
||||
numberOfMerges = 0;
|
||||
var mergedSubtitle = new Subtitle();
|
||||
bool lastMerged = false;
|
||||
Paragraph p = null;
|
||||
var lineNumbers = new StringBuilder();
|
||||
for (int i = 1; i < subtitle.Paragraphs.Count; i++)
|
||||
var info = new Subtitle();
|
||||
var mergedSub = Core.Forms.MergeLinesWithSameTimeCodes.Merge(subtitle, mergedIndexes, out numberOfMerges, clearFixes, reBreak, maxMsBetween, language, removed, _isFixAllowedList, info);
|
||||
foreach (var p in info.Paragraphs)
|
||||
{
|
||||
if (!lastMerged)
|
||||
{
|
||||
p = new Paragraph(subtitle.GetParagraphOrDefault(i - 1));
|
||||
mergedSubtitle.Paragraphs.Add(p);
|
||||
}
|
||||
Paragraph next = subtitle.GetParagraphOrDefault(i);
|
||||
if (next != null)
|
||||
{
|
||||
if (QualifiesForMerge(p, next, maxMsBetween) && IsFixAllowed(p))
|
||||
{
|
||||
if (p.Text.StartsWith("<i>", StringComparison.Ordinal) && p.Text.EndsWith("</i>", StringComparison.Ordinal) && next.Text.StartsWith("<i>", StringComparison.Ordinal) && next.Text.EndsWith("</i>", StringComparison.Ordinal))
|
||||
{
|
||||
p.Text = p.Text.Remove(p.Text.Length - 4) + Environment.NewLine + next.Text.Remove(0, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
p.Text = p.Text + Environment.NewLine + next.Text;
|
||||
}
|
||||
if (reBreak)
|
||||
p.Text = Utilities.AutoBreakLine(p.Text, _language);
|
||||
lastMerged = true;
|
||||
removed.Add(i);
|
||||
numberOfMerges++;
|
||||
if (!mergedIndexes.Contains(i))
|
||||
mergedIndexes.Add(i);
|
||||
if (!mergedIndexes.Contains(i - 1))
|
||||
mergedIndexes.Add(i - 1);
|
||||
|
||||
if (!("," + lineNumbers).Contains("," + p.Number + ","))
|
||||
{
|
||||
lineNumbers.Append(p.Number);
|
||||
lineNumbers.Append(',');
|
||||
}
|
||||
if (!("," + lineNumbers).Contains("," + next.Number + ","))
|
||||
{
|
||||
lineNumbers.Append(next.Number);
|
||||
lineNumbers.Append(',');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lastMerged = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lastMerged = false;
|
||||
}
|
||||
|
||||
if (!removed.Contains(i) && lineNumbers.Length > 0 && clearFixes)
|
||||
{
|
||||
AddToListView(p, lineNumbers.ToString(), p.Text);
|
||||
lineNumbers.Clear();
|
||||
}
|
||||
AddToListView(p, p.Extra, p.Text);
|
||||
}
|
||||
if (lineNumbers.Length > 0 && clearFixes && p != null)
|
||||
{
|
||||
AddToListView(p, lineNumbers.ToString(), p.Text);
|
||||
}
|
||||
if (!lastMerged)
|
||||
mergedSubtitle.Paragraphs.Add(new Paragraph(subtitle.GetParagraphOrDefault(subtitle.Paragraphs.Count - 1)));
|
||||
|
||||
listViewFixes.EndUpdate();
|
||||
if (!_loading)
|
||||
listViewFixes.ItemChecked += listViewFixes_ItemChecked;
|
||||
|
||||
mergedSubtitle.Renumber();
|
||||
return mergedSubtitle;
|
||||
}
|
||||
|
||||
private static bool QualifiesForMerge(Paragraph p, Paragraph next, int maxMsBetween)
|
||||
{
|
||||
if (p == null || next == null)
|
||||
return false;
|
||||
|
||||
return Math.Abs(next.StartTime.TotalMilliseconds - p.StartTime.TotalMilliseconds) <= maxMsBetween &&
|
||||
Math.Abs(next.EndTime.TotalMilliseconds - p.EndTime.TotalMilliseconds) <= maxMsBetween;
|
||||
return mergedSub;
|
||||
}
|
||||
|
||||
private void MergeTextWithSameTimeCodes_KeyDown(object sender, KeyEventArgs e)
|
||||
|
Loading…
Reference in New Issue
Block a user