SubtitleEdit/libse/SubtitleFormats/SonyDVDArchitectLineAndDuration.cs

132 lines
5.7 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
{
public class SonyDVDArchitectLineAndDuration : SubtitleFormat
{
private static readonly Regex Regex = new Regex(@"^\d+\t\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d\t\d\d:\d\d:\d\d:\d\d$", RegexOptions.Compiled);
public override string Extension
{
get { return ".txt"; }
}
public override string Name
{
get { return "Sony DVDArchitect line/duration"; }
}
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("Title: " + title);
sb.AppendLine("Translator: No Author");
sb.AppendLine("Date: " + DateTime.Now.ToString("dd-MM-yyyy").Replace("-", ".")); // 25.08.2011
double milliseconds = 0;
if (subtitle.Paragraphs.Count > 0)
milliseconds = subtitle.Paragraphs[subtitle.Paragraphs.Count - 1].EndTime.TotalMilliseconds;
var tc = new TimeCode(milliseconds);
sb.AppendLine(string.Format("Duration: {0:00}:{1:00}:{2:00}:{3:00}", tc.Hours, tc.Minutes, tc.Seconds, MillisecondsToFramesMaxFrameRate(tc.Milliseconds))); // 01:20:49:12
sb.AppendLine("Program start: 00:00:00:00");
sb.AppendLine("Title count: " + subtitle.Paragraphs.Count);
sb.AppendLine();
sb.AppendLine("#\tIn\tOut\tDuration");
sb.AppendLine();
int count = 0;
const string writeFormat = "{13}\t{0:00}:{1:00}:{2:00}:{3:00}\t{4:00}:{5:00}:{6:00}:{7:00}\t{8:00}:{9:00}:{10:00}:{11:00}\r\n{12}";
foreach (Paragraph p in subtitle.Paragraphs)
{
count++;
var text = HtmlUtil.RemoveHtmlTags(p.Text, true);
// to avoid rounding errors in duration
var startFrame = MillisecondsToFramesMaxFrameRate(p.StartTime.Milliseconds);
var endFrame = MillisecondsToFramesMaxFrameRate(p.EndTime.Milliseconds);
var durationCalc = new Paragraph(
new TimeCode(p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, FramesToMillisecondsMax999(startFrame)),
new TimeCode(p.EndTime.Hours, p.EndTime.Minutes, p.EndTime.Seconds, FramesToMillisecondsMax999(endFrame)),
string.Empty);
sb.AppendLine(string.Format(writeFormat + Environment.NewLine,
p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, startFrame,
p.EndTime.Hours, p.EndTime.Minutes, p.EndTime.Seconds, endFrame,
durationCalc.Duration.Hours, durationCalc.Duration.Minutes, durationCalc.Duration.Seconds, MillisecondsToFramesMaxFrameRate(durationCalc.Duration.Milliseconds),
text, count));
}
return sb.ToString().Trim() + Environment.NewLine + Environment.NewLine + Environment.NewLine;
}
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
{ //22 00:04:19:12 00:04:21:09 00:00:01:21
_errorCount = 0;
Paragraph lastParagraph = null;
int count = 0;
foreach (string line in lines)
{
bool isTimeCode = false;
if (line.Length > 0)
{
bool success = false;
if (line.Length > 31 && line.IndexOf(':') > 1)
{
var match = Regex.Match(line);
if (match.Success)
{
isTimeCode = true;
if (lastParagraph != null)
subtitle.Paragraphs.Add(lastParagraph);
var arr = line.Split('\t');
TimeCode start = DecodeTimeCode(arr[1]);
TimeCode end = DecodeTimeCode(arr[2]);
lastParagraph = new Paragraph(start, end, string.Empty);
success = true;
}
}
if (!isTimeCode && !string.IsNullOrWhiteSpace(line) && lastParagraph != null && Utilities.GetNumberOfLines(lastParagraph.Text) < 5)
{
lastParagraph.Text = (lastParagraph.Text + Environment.NewLine + line).Trim();
success = true;
}
if (!success && count > 9)
_errorCount++;
}
count++;
}
if (lastParagraph != null)
subtitle.Paragraphs.Add(lastParagraph);
subtitle.Renumber();
}
private static TimeCode DecodeTimeCode(string s)
{
var parts = s.Split(':');
//00:00:07:12
string hour = parts[0];
string minutes = parts[1];
string seconds = parts[2];
string frames = parts[3];
TimeCode tc = new TimeCode(int.Parse(hour), int.Parse(minutes), int.Parse(seconds), FramesToMillisecondsMax999(int.Parse(frames)));
return tc;
}
}
}