From 45fbd944ebbd7eab3dc897d7de3beae66ca8c03b Mon Sep 17 00:00:00 2001 From: Nikolaj Olsson Date: Sun, 23 Aug 2020 10:43:43 +0200 Subject: [PATCH] Add new subtitle (dv) format - thx George :) --- Changelog.txt | 1 + libse/SubtitleFormats/DvSubtitle.cs | 123 ++++++++++++++++++++++++ libse/SubtitleFormats/SubtitleFormat.cs | 1 + 3 files changed, 125 insertions(+) create mode 100644 libse/SubtitleFormats/DvSubtitle.cs diff --git a/Changelog.txt b/Changelog.txt index a76002f27..3a4a21607 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -6,6 +6,7 @@ * Add new subtitle (Excel) format - thx Jecy * Add new subtitle (json) format - thx Maksim * Add new subtitle format FCP Xml 1.8 - thx Maria + * Add new subtitle (dv) format - thx George * Add shortcuts for Tools menu items Split/Append/Join - thx z3us * Add shortcuts for "Merge line with same text/time-code" - thx Mike * Add shortcuts "Set end and pause" + "Export to PAC" - thx Milenko diff --git a/libse/SubtitleFormats/DvSubtitle.cs b/libse/SubtitleFormats/DvSubtitle.cs new file mode 100644 index 000000000..c6b45edf3 --- /dev/null +++ b/libse/SubtitleFormats/DvSubtitle.cs @@ -0,0 +1,123 @@ +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; + +namespace Nikse.SubtitleEdit.Core.SubtitleFormats +{ + public class DvSubtitle : SubtitleFormat + { + private static readonly Regex LinePattern = new Regex(@"^c 1 \d{8} \d{8} .+", RegexOptions.Compiled); + + public override string Extension => ".dv"; + + public override string Name => "DV Subtitle"; + + public override bool IsTimeBased => false; + + public override bool IsMine(List lines, string fileName) + { + var okCount = 0; + var errors = 0; + foreach (var line in lines) + { + if (!string.IsNullOrWhiteSpace(line) && line.StartsWith('c') && LinePattern.IsMatch(line)) + { + okCount++; + } + else + { + errors++; + } + } + return okCount > errors; + } + + public override string ToText(Subtitle subtitle, string title) + { + var sb = new StringBuilder(); + foreach (var p in subtitle.Paragraphs) + { + sb.AppendLine($"c 1 {MillisecondsToFrames(p.StartTime.TotalMilliseconds):00000000} {MillisecondsToFrames(p.EndTime.TotalMilliseconds):00000000} {WriteText(p.Text)} 0"); + } + return sb.ToString().Trim(); + } + + private static string WriteText(string text) + { + var sb = new StringBuilder(); + var lines = text.SplitToLines(); + foreach (var line in lines) + { + if (sb.Length > 0) + { + sb.Append(' '); + } + + sb.Append('\''); + sb.Append(line); + sb.Append('\''); + } + + if (lines.Count == 1) + { + sb.Append(" ''"); + } + + return sb.ToString(); + } + + public override void LoadSubtitle(Subtitle subtitle, List lines, string fileName) + { + _errorCount = 0; + foreach (var line in lines) + { + if (!string.IsNullOrWhiteSpace(line) && line.StartsWith('c') && LinePattern.IsMatch(line)) + { + var arr = line.Split(); + if (long.TryParse(arr[2], out var start) && long.TryParse(arr[3], out var end)) + { + var text = ReadText(line.Remove(0, 22)); + subtitle.Paragraphs.Add(new Paragraph(text, FramesToMilliseconds(start), FramesToMilliseconds(end))); + } + else + { + _errorCount++; + } + } + else + { + _errorCount++; + } + + if (_errorCount > 25) + { + return; + } + } + + subtitle.Renumber(); + } + + private string ReadText(string input) + { + var arr = input.TrimEnd('0').Replace("' '", "\n").SplitToLines(); + var sb = new StringBuilder(); + for (var index = 0; index < arr.Count; index++) + { + var line = arr[index].Trim(); + if (index == 0 && line.StartsWith('\'')) + { + line = line.Remove(0, 1); + } + else if (index == arr.Count - 1 && line.EndsWith('\'')) + { + line = line.Remove(line.Length - 1); + } + + sb.AppendLine(line); + } + + return sb.ToString().Trim(); + } + } +} diff --git a/libse/SubtitleFormats/SubtitleFormat.cs b/libse/SubtitleFormats/SubtitleFormat.cs index d8e4faf2b..fd6734419 100644 --- a/libse/SubtitleFormats/SubtitleFormat.cs +++ b/libse/SubtitleFormats/SubtitleFormat.cs @@ -64,6 +64,7 @@ namespace Nikse.SubtitleEdit.Core.SubtitleFormats new DvdStudioProSpace(), new DvdSubtitle(), new DvdSubtitleSystem(), + new DvSubtitle(), new Ebu(), new Edl(), new Eeg708(),