diff --git a/Changelog.txt b/Changelog.txt index 97eba352a..72397e323 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -4,6 +4,9 @@ * NEW: * Add "Text To Speech" - thx darnn/cvrle77/msjsc001 * Add burn-in batch mode - thx Leon/David + * Add new LRC with milliseconds format - thx eadmaster + * Add new subtitle format (Whisper output) - thx lererledd + * Add CPS option to modify selection - thx uckthis * IMPROVED: * Update Portuguese translation - thx hugok79 * Update Bulgarian translation - thx Калин @@ -20,6 +23,8 @@ * Fix possible crash in teletext reading - thx yellobyte * Fix unwanted text boxes background color change - thx Leon * Fix Whisper on selection in waveform in "translation mode" - thx rRobis + * Fix image export shadow when border is zero - thx pixelhunterX + * Fix crash in traslate with empty API key - thx lambdacore12 4.0.5 (13th April 2024) diff --git a/Dictionaries/hrv_OCRFixReplaceList.xml b/Dictionaries/hrv_OCRFixReplaceList.xml index a50ec1b95..32dba5b8a 100644 --- a/Dictionaries/hrv_OCRFixReplaceList.xml +++ b/Dictionaries/hrv_OCRFixReplaceList.xml @@ -417,6 +417,7 @@ + @@ -2041,6 +2042,8 @@ + + @@ -4055,6 +4058,7 @@ + diff --git a/LanguageBaseEnglish.xml b/LanguageBaseEnglish.xml index 7543a0b61..cd9b66f98 100644 --- a/LanguageBaseEnglish.xml +++ b/LanguageBaseEnglish.xml @@ -1610,6 +1610,7 @@ To use an API key, go to "Options -> Settings -> Auto-translate" to enter Go to source view Go to list view Extract audio... + Media information @@ -2129,6 +2130,8 @@ Download and continue? Even-numbered lines Duration less than Duration greater than + CPS less than + CPS greater than Exactly one line Exactly two lines More than two lines @@ -3166,6 +3169,11 @@ Continue? Adjusting speed: {0} / {1}... Merging audio track: {0} / {1}... Generating speech from text: {0} / {1}... + Review audio clips + Review and edit/remove audio clips + Play + Auto-continue + Regenerate SMPTE timing diff --git a/build.sh b/build.sh index 1b7640037..720e379b8 100644 --- a/build.sh +++ b/build.sh @@ -1,4 +1,4 @@ -#!bin/bash +#!/bin/bash function ShowHelp() { diff --git a/src/Test/Core/SeJsonParserTest.cs b/src/Test/Core/SeJsonParserTest.cs index aacef6e02..5def62a18 100644 --- a/src/Test/Core/SeJsonParserTest.cs +++ b/src/Test/Core/SeJsonParserTest.cs @@ -192,5 +192,50 @@ namespace Test.Core }".Replace('\'', '"'), "items"); Assert.AreEqual(4, result.Count); } + + [TestMethod] + public void GetRootElements_Simple_Value() + { + var parser = new SeJsonParser(); + var result = parser.GetRootElements("{ \"tag\": \"hi there!\" }"); + Assert.AreEqual(1, result.Count); + Assert.AreEqual("tag", result[0].Name); + Assert.AreEqual("hi there!", result[0].Json); + } + + [TestMethod] + public void GetRootElements_Simple_Object() + { + var parser = new SeJsonParser(); + var result = parser.GetRootElements("{ \"tag\": { \"name\" : \"Joe\" } }"); + Assert.AreEqual(1, result.Count); + Assert.AreEqual("tag", result[0].Name); + Assert.AreEqual("{ \"name\" : \"Joe\" }", result[0].Json); + } + + + [TestMethod] + public void GetRootElements_Simple_Value_And_Object() + { + var parser = new SeJsonParser(); + var result = parser.GetRootElements("{ \"tag1\": \"hi there!\", \"tag2\": { \"name\" : \"Joe\" } }"); + Assert.AreEqual(2, result.Count); + Assert.AreEqual("tag1", result[0].Name); + Assert.AreEqual("hi there!", result[0].Json); + Assert.AreEqual("tag2", result[1].Name); + Assert.AreEqual("{ \"name\" : \"Joe\" }", result[1].Json); + } + + [TestMethod] + public void GetRootElements_Two_Simple_Value() + { + var parser = new SeJsonParser(); + var result = parser.GetRootElements("{ \"tag\": \"hi there!\",\"tag2\": \"hi!\", }"); + Assert.AreEqual(2, result.Count); + Assert.AreEqual("tag", result[0].Name); + Assert.AreEqual("hi there!", result[0].Json); + Assert.AreEqual("tag2", result[1].Name); + Assert.AreEqual("hi!", result[1].Json); + } } } \ No newline at end of file diff --git a/src/libse/Common/FfmpegMediaInfo.cs b/src/libse/Common/FfmpegMediaInfo.cs index 1ded83ab0..d4ff98e53 100644 --- a/src/libse/Common/FfmpegMediaInfo.cs +++ b/src/libse/Common/FfmpegMediaInfo.cs @@ -4,12 +4,17 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Text; +using System.Text.RegularExpressions; namespace Nikse.SubtitleEdit.Core.Common { public class FfmpegMediaInfo { public List Tracks { get; set; } + public int VideoWidth { get; set; } + public int VideoHeight { get; set; } + + private static readonly Regex ResolutionRegex = new Regex(@"\d\d+x\d\d+", RegexOptions.Compiled); private FfmpegMediaInfo() { @@ -19,7 +24,7 @@ namespace Nikse.SubtitleEdit.Core.Common public static FfmpegMediaInfo Parse(string videoFileName) { if (string.IsNullOrEmpty(Configuration.Settings.General.FFmpegLocation) || - !File.Exists(Configuration.Settings.General.FFmpegLocation)) + !File.Exists(Configuration.Settings.General.FFmpegLocation)) { return new FfmpegMediaInfo(); } @@ -56,6 +61,20 @@ namespace Nikse.SubtitleEdit.Core.Common var s = line.Trim(); if (s.StartsWith("Stream #", StringComparison.Ordinal)) { + var resolutionMatch = ResolutionRegex.Match(s); + if (resolutionMatch.Success) + { + var parts = resolutionMatch.Value.Split('x'); + if (info.VideoWidth == 0 && + parts.Length == 2 && + int.TryParse(parts[0], out var w) && + int.TryParse(parts[1], out var h)) + { + info.VideoWidth = w; + info.VideoHeight = h; + } + } + var arr = s.Replace(": ", "¤").Split('¤'); if (arr.Length == 3) { @@ -123,7 +142,7 @@ namespace Nikse.SubtitleEdit.Core.Common StartInfo = { FileName = ffmpegLocation, - Arguments = $"-i \"{inputFileName}\" - hide_banner", + Arguments = $"-i \"{inputFileName}\" -hide_banner", UseShellExecute = false, CreateNoWindow = true } diff --git a/src/libse/Common/SeJsonParser.cs b/src/libse/Common/SeJsonParser.cs index 04d4cc3a2..c633a8bc3 100644 --- a/src/libse/Common/SeJsonParser.cs +++ b/src/libse/Common/SeJsonParser.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using Nikse.SubtitleEdit.Core.ContainerFormats.Ebml; +using System.Collections.Generic; using System.Text; namespace Nikse.SubtitleEdit.Core.Common @@ -1300,5 +1301,389 @@ namespace Nikse.SubtitleEdit.Core.Common } return string.Empty; } + + public class RootElement + { + public string Name { get; set; } + public string Json { get; set; } + } + + public List GetRootElements(string content) + { + Errors = new List(); + var list = new List(); + var i = 0; + var max = content.Length; + var state = new Stack(); + var objectName = string.Empty; + var start = -1; + while (i < max) + { + var ch = content[i]; + if (_whiteSpace.Contains(ch)) // ignore white space + { + i++; + } + + else if (state.Count == 0) // root + { + if (ch == '{') + { + state.Push(new StateElement + { + Name = "Root", + State = SeJsonState.Object + }); + i++; + } + else if (ch == '[') + { + state.Push(new StateElement + { + Name = "Root", + State = SeJsonState.Array + }); + i++; + } + else + { + Errors.Add($"Unexpected char {ch} at position {i}"); + return list; + } + } + + else if (state.Peek().State == SeJsonState.Object) // after '{' + { + if (ch == '"') + { + i++; + int end = content.IndexOf('"', i); + objectName = content.Substring(i, end - i).Trim(); + int colon = content.IndexOf(':', end); + if (colon < 0) + { + Errors.Add($"Fatal - expected char : after position {end}"); + return list; + } + + i += colon - i + 1; + state.Push(new StateElement + { + Name = objectName, + State = SeJsonState.Value + }); + + if (state.Count == 2) + { + start = i; // element in root + } + } + else if (ch == '}') + { + i++; + state.Pop(); + + if (state.Count == 2 && start >= 0) + { + var str = content.Substring(start, i - start).Trim(); + list.Add(new RootElement() + { + Name = state.Peek().Name, + Json = str, + }); + + start = -1; + } + } + else if (ch == ',') // next object + { + if (state.Count == 1 && start >= 0) + { + var str = content.Substring(start, i - start).Trim(); + list.Add(new RootElement() + { + Name = state.Peek().Name, + Json = str, + }); + + start = i + 1; + } + + i++; + if (state.Peek().Count > 0) + { + state.Peek().Count++; + } + else + { + Errors.Add($"Unexpected char {ch} at position {i}"); + return list; + } + } + else if (ch == ']') // next object + { + i++; + if (state.Peek().Count > 0) + { + state.Pop(); + } + else + { + Errors.Add($"Unexpected char {ch} at position {i}"); + return list; + } + } + else + { + Errors.Add($"Unexpected char {ch} at position {i}"); + return list; + } + } + + else if (state.Peek().State == SeJsonState.Value) // value - string/ number / object / array / true / false / null + "," + "}" + { + if (ch == '"') // string + { + i++; + var skip = true; + int end = 0; + var endSeek = i; + while (skip) + { + end = content.IndexOf('"', endSeek); + if (end < 0) + { + Errors.Add($"Fatal - expected char \" after position {endSeek}"); + return list; + } + skip = content[end - 1] == '\\'; + if (skip) + { + endSeek = end + 1; + } + if (endSeek >= max) + { + Errors.Add($"Fatal - expected end tag after position {endSeek}"); + return list; + } + } + + if (state.Count == 2) + { + var objectValue = content.Substring(i, end - i).Trim(); + var x = state.Peek(); + list.Add(new RootElement(){ Name = x.Name, Json = objectValue }); + start = -1; + } + + i += end - i + 1; + state.Pop(); + if (state.Count > 0) + { + state.Peek().Count++; + } + } + else if (ch == '}') // empty value + { + i++; + var value = state.Pop(); + if (state.Count > 0) + { + if (value.State == SeJsonState.Value) + { + var st = state.Pop(); + + if (state.Count == 2) + { + var str = content.Substring(start, i - start).Trim(); + list.Add(new RootElement() + { + Name = state.Peek().Name, + Json = str, + }); + + start = -1; + } + } + else + { + state.Peek().Count++; + } + } + } + else if (ch == ',') // next object + { + i++; + state.Pop(); + if (state.Count > 0 && state.Peek().Count > 0) + { + state.Peek().Count++; + } + else + { + Errors.Add($"Unexpected char {ch} at position {i}"); + return list; + } + } + else if (ch == 'n' && max > i + 3 && content[i + 1] == 'u' && content[i + 2] == 'l' && content[i + 3] == 'l') + { + i += 4; + state.Pop(); + if (state.Count > 0) + { + state.Peek().Count++; + } + //if (objectName == name) + //{ + // list.Add(null); + //} + + } + else if (ch == 't' && max > i + 3 && content[i + 1] == 'r' && content[i + 2] == 'u' && content[i + 3] == 'e') + { + i += 4; + state.Pop(); + if (state.Count > 0) + { + state.Peek().Count++; + } + //if (objectName == name) + //{ + // list.Add("true"); + //} + } + else if (ch == 'f' && max > i + 4 && content[i + 1] == 'a' && content[i + 2] == 'l' && content[i + 3] == 's' && content[i + 4] == 'e') + { + i += 5; + state.Pop(); + if (state.Count > 0) + { + state.Peek().Count++; + } + //if (objectName == name) + //{ + // list.Add("false"); + //} + } + else if ("+-0123456789".IndexOf(ch) >= 0) + { + var sb = new StringBuilder(); + while (i < max && "+-0123456789.Ee".IndexOf(content[i]) >= 0) + { + sb.Append(content[i]); + i++; + } + state.Pop(); + if (state.Count > 0) + { + state.Peek().Count++; + } + //if (objectName == name) + //{ + // list.Add(sb.ToString()); + //} + } + else if (ch == '{') + { + if (state.Count > 1) + { + var value = state.Pop(); + state.Peek().Count++; + state.Push(value); + } + state.Push(new StateElement + { + State = SeJsonState.Object, + Name = objectName + }); + i++; + } + else if (ch == '[') + { + if (state.Count > 1) + { + var value = state.Pop(); + state.Peek().Count++; + state.Push(value); + } + state.Push(new StateElement + { + State = SeJsonState.Array, + Name = objectName + }); + i++; + //if (start < 0 && objectName == name) + //{ + // start = i; + //} + } + else + { + Errors.Add($"Unexpected char {ch} at position {i}"); + return list; + } + } + + else if (state.Peek().State == SeJsonState.Array) // array, after '[' + { + if (ch == ']') + { + state.Pop(); + i++; + //if (state.Count > 0 && state.Peek().Name == name && start > -1) + //{ + // list.Add(content.Substring(start, i - start - 1).Trim()); + // start = -1; + //} + } + else if (ch == ',' && state.Peek().Count > 0) + { + //if (start >= 0 && state.Peek().State == SeJsonState.Array && state.Peek().Name == name) + //{ + // list.Add(content.Substring(start, i - start).Trim()); + // start = i + 1; + //} + if (state.Count > 0 && state.Peek().Count > 0) + { + state.Peek().Count++; + } + else + { + Errors.Add($"Unexpected char {ch} at position {i}"); + return list; + } + i++; + } + else if (ch == '{') + { + if (state.Count > 0) + { + state.Peek().Count++; + } + state.Push(new StateElement + { + Name = objectName, + State = SeJsonState.Object + }); + i++; + } + else + { + if (state.Count > 0) + { + state.Peek().Count++; + } + state.Push(new StateElement + { + Name = objectName + "_array_value", + State = SeJsonState.Value + }); + } + } + + } + + return list; + } } } diff --git a/src/libse/Common/Settings.cs b/src/libse/Common/Settings.cs index ec7164c0f..b0fbad13d 100644 --- a/src/libse/Common/Settings.cs +++ b/src/libse/Common/Settings.cs @@ -193,7 +193,10 @@ namespace Nikse.SubtitleEdit.Core.Common public string TextToSpeechEngine { get; set; } public string TextToSpeechLastVoice { get; set; } public string TextToSpeechElevenLabsApiKey { get; set; } - public bool DisableVidoInfoViaLabel { get; set; } + public string TextToSpeechAzureApiKey { get; set; } + public string TextToSpeechAzureRegion { get; set; } + public bool TextToSpeechPreview { get; set; } + public bool TextToSpeechAddToVideoFile { get; set; } public bool ListViewSyntaxColorDurationSmall { get; set; } public bool ListViewSyntaxColorDurationBig { get; set; } public bool ListViewSyntaxColorOverlap { get; set; } @@ -557,6 +560,8 @@ namespace Nikse.SubtitleEdit.Core.Common AnthropicApiUrl = "https://api.anthropic.com/v1/messages"; AnthropicPrompt = "Translate from {0} to {1}, keep sentences in {1} as they are, do not censor the translation, give only the output without commenting on what you read:"; AnthropicApiModel = "claude-3-opus-20240229"; + TextToSpeechAzureRegion = "westeurope"; + TextToSpeechAddToVideoFile = true; TranslateAllowSplit = true; TranslateViaCopyPasteAutoCopyToClipboard = true; TranslateViaCopyPasteMaxSize = 5000; @@ -5481,16 +5486,34 @@ $HorzAlign = Center settings.Tools.TextToSpeechElevenLabsApiKey = subNode.InnerText; } + subNode = node.SelectSingleNode("TextToSpeechAzureApiKey"); + if (subNode != null) + { + settings.Tools.TextToSpeechAzureApiKey = subNode.InnerText; + } + + subNode = node.SelectSingleNode("TextToSpeechAzureRegion"); + if (subNode != null) + { + settings.Tools.TextToSpeechAzureRegion = subNode.InnerText; + } + subNode = node.SelectSingleNode("TranslateViaCopyPasteAutoCopyToClipboard"); if (subNode != null) { settings.Tools.TranslateViaCopyPasteAutoCopyToClipboard = Convert.ToBoolean(subNode.InnerText, CultureInfo.InvariantCulture); } - subNode = node.SelectSingleNode("DisableVidoInfoViaLabel"); + subNode = node.SelectSingleNode("TextToSpeechPreview"); if (subNode != null) { - settings.Tools.DisableVidoInfoViaLabel = Convert.ToBoolean(subNode.InnerText, CultureInfo.InvariantCulture); + settings.Tools.TextToSpeechPreview = Convert.ToBoolean(subNode.InnerText, CultureInfo.InvariantCulture); + } + + subNode = node.SelectSingleNode("TextToSpeechAddToVideoFile"); + if (subNode != null) + { + settings.Tools.TextToSpeechAddToVideoFile = Convert.ToBoolean(subNode.InnerText, CultureInfo.InvariantCulture); } subNode = node.SelectSingleNode("ListViewSyntaxColorDurationSmall"); @@ -12023,7 +12046,10 @@ $HorzAlign = Center textWriter.WriteElementString("TextToSpeechEngine", settings.Tools.TextToSpeechEngine); textWriter.WriteElementString("TextToSpeechLastVoice", settings.Tools.TextToSpeechLastVoice); textWriter.WriteElementString("TextToSpeechElevenLabsApiKey", settings.Tools.TextToSpeechElevenLabsApiKey); - textWriter.WriteElementString("DisableVidoInfoViaLabel", settings.Tools.DisableVidoInfoViaLabel.ToString(CultureInfo.InvariantCulture)); + textWriter.WriteElementString("TextToSpeechAzureApiKey", settings.Tools.TextToSpeechAzureApiKey); + textWriter.WriteElementString("TextToSpeechAzureRegion", settings.Tools.TextToSpeechAzureRegion); + textWriter.WriteElementString("TextToSpeechPreview", settings.Tools.TextToSpeechPreview.ToString(CultureInfo.InvariantCulture)); + textWriter.WriteElementString("TextToSpeechAddToVideoFile", settings.Tools.TextToSpeechAddToVideoFile.ToString(CultureInfo.InvariantCulture)); textWriter.WriteElementString("ListViewSyntaxColorDurationSmall", settings.Tools.ListViewSyntaxColorDurationSmall.ToString(CultureInfo.InvariantCulture)); textWriter.WriteElementString("ListViewSyntaxColorDurationBig", settings.Tools.ListViewSyntaxColorDurationBig.ToString(CultureInfo.InvariantCulture)); textWriter.WriteElementString("ListViewSyntaxColorLongLines", settings.Tools.ListViewSyntaxColorLongLines.ToString(CultureInfo.InvariantCulture)); diff --git a/src/libse/SubtitleFormats/Lrc3DigitsMs.cs b/src/libse/SubtitleFormats/Lrc3DigitsMs.cs new file mode 100644 index 000000000..f1aafe172 --- /dev/null +++ b/src/libse/SubtitleFormats/Lrc3DigitsMs.cs @@ -0,0 +1,339 @@ +using Nikse.SubtitleEdit.Core.Common; +using Nikse.SubtitleEdit.Core.Enums; +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; + +namespace Nikse.SubtitleEdit.Core.SubtitleFormats +{ + /// + /// LRC is a format that synchronizes song lyrics with an audio/video file, [mm:ss.xxx] where mm is minutes, ss is seconds and xx is milliseconds. + /// + /// https://wiki.nicksoft.info/specifications:lrc-file + /// + /// Tags: + /// [al:''Album where the song is from''] + /// [ar:''Lyrics artist''] + /// [by:''Creator of the LRC file''] + /// [offset:''+/- Overall timestamp adjustment in milliseconds, + shifts time up, - shifts down''] + /// [re:''The player or editor that creates LRC file''] + /// [ti:''Lyrics(song) title''] + /// [ve:''version of program''] + /// + public class Lrc3DigitsMs : SubtitleFormat + { + private static readonly Regex RegexTimeCodes = new Regex(@"^\[\d+:\d\d\.\d\d\d\].*$", RegexOptions.Compiled); + + public override string Extension => ".lrc"; + + public override string Name => "LRC Lyrics ms"; + + public override bool IsMine(List lines, string fileName) + { + var subtitle = new Subtitle(); + LoadSubtitle(subtitle, lines, fileName); + + if (subtitle.Paragraphs.Count > 4) + { + var allStartWithNumber = true; + foreach (var p in subtitle.Paragraphs) + { + if (p.Text.Length > 1 && !Utilities.IsInteger(p.Text.Substring(0, 2))) + { + allStartWithNumber = false; + break; + } + } + if (allStartWithNumber) + { + return false; + } + } + + if (subtitle.Paragraphs.Count > _errorCount) + { + return !new UnknownSubtitle33().IsMine(lines, fileName) && + !new UnknownSubtitle36().IsMine(lines, fileName) && + !new TMPlayer().IsMine(lines, fileName) && + !new Lrc().IsMine(lines, fileName) && + !new LrcNoEndTime().IsMine(lines, fileName); + } + + return false; + } + + public override string ToText(Subtitle subtitle, string title) + { + var header = RemoveSoftwareAndVersion(subtitle.Header); + var sb = new StringBuilder(); + if (!string.IsNullOrEmpty(header) && (header.Contains("[ar:") || header.Contains("[ti:") || header.Contains("[by:") || header.Contains("[id:"))) + { + sb.AppendLine(header); + } + else if (!string.IsNullOrEmpty(title)) + { + sb.AppendLine("[ti:" + title.Replace("[", string.Empty).Replace("]", string.Empty) + "]"); + } + + if (!header.Contains("[re:", StringComparison.Ordinal)) + { + sb.AppendLine("[re: Subtitle Edit]"); + } + + if (!header.Contains("[ve:", StringComparison.Ordinal)) + { + sb.AppendLine($"[ve: {Utilities.AssemblyVersion}]"); + } + + const string timeCodeFormat = "[{0:00}:{1:00}.{2:000}]{3}"; + for (var i = 0; i < subtitle.Paragraphs.Count; i++) + { + var p = subtitle.Paragraphs[i]; + var next = subtitle.GetParagraphOrDefault(i + 1); + + var text = HtmlUtil.RemoveHtmlTags(p.Text); + text = text.Replace(Environment.NewLine, " "); + var fraction = p.StartTime.Milliseconds; + if (fraction >= 100) + { + var ms = new TimeCode(p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, 0).TotalMilliseconds; + ms += 1000; + p = new Paragraph(p.Text, ms, p.EndTime.TotalMilliseconds); + fraction = 0; + } + + sb.AppendLine(string.Format(timeCodeFormat, p.StartTime.Hours * 60 + p.StartTime.Minutes, p.StartTime.Seconds, fraction, text)); + + if (next == null || next.StartTime.TotalMilliseconds - p.EndTime.TotalMilliseconds > 100) + { + var tc = new TimeCode(p.EndTime.TotalMilliseconds); + sb.AppendLine(string.Format(timeCodeFormat, tc.Hours * 60 + tc.Minutes, tc.Seconds, tc.Milliseconds, string.Empty)); + } + } + + return sb.ToString().Trim(); + } + + public static string RemoveSoftwareAndVersion(string s) + { + if (string.IsNullOrEmpty(s)) + { + return string.Empty; + } + + var sb = new StringBuilder(); + foreach (var line in s.SplitToLines()) + { + if (line.Trim().StartsWith("[re:") || line.Trim().StartsWith("[ve:")) + { + continue; + } + + sb.AppendLine(line.Trim()); + } + + return sb.ToString().Trim(); + } + + public override void LoadSubtitle(Subtitle subtitle, List lines, string fileName) + { //[01:05.999]I've been walking in the same way as I do + _errorCount = 0; + var offsetInMilliseconds = 0.0d; + var header = new StringBuilder(); + char[] splitChars = { ':', '.' }; + foreach (var line in lines) + { + if (line.StartsWith('[') && RegexTimeCodes.Match(line).Success) + { + var s = line.Substring(1, 8); + var parts = s.Split(splitChars, StringSplitOptions.RemoveEmptyEntries); + if (parts.Length == 3) + { + try + { + var minutes = int.Parse(parts[0]); + var seconds = int.Parse(parts[1]); + var milliseconds = int.Parse(parts[2]); + var text = line.Remove(0, 10).Trim().TrimStart(']').Trim(); + var start = new TimeCode(0, minutes, seconds, milliseconds); + var p = new Paragraph(start, new TimeCode(), text); + subtitle.Paragraphs.Add(p); + } + catch + { + _errorCount++; + } + } + else + { + _errorCount++; + } + } + else if (line.StartsWith("[ar:", StringComparison.Ordinal)) // [ar:Lyrics artist] + { + if (subtitle.Paragraphs.Count < 1) + { + header.AppendLine(line); + } + } + else if (line.StartsWith("[id:", StringComparison.Ordinal)) // [ar:Lyrics artist] + { + if (subtitle.Paragraphs.Count < 1) + { + header.AppendLine(line); + } + } + else if (line.StartsWith("[al:", StringComparison.Ordinal)) // [al:Album where the song is from] + { + if (subtitle.Paragraphs.Count < 1) + { + header.AppendLine(line); + } + } + else if (line.StartsWith("[ti:", StringComparison.Ordinal)) // [ti:Lyrics (song) title] + { + if (subtitle.Paragraphs.Count < 1) + { + header.AppendLine(line); + } + } + else if (line.StartsWith("[au:", StringComparison.Ordinal)) // [au:Creator of the song text] + { + if (subtitle.Paragraphs.Count < 1) + { + header.AppendLine(line); + } + } + else if (line.StartsWith("[length:", StringComparison.Ordinal)) // [length:How long the song is] + { + if (subtitle.Paragraphs.Count < 1) + { + header.AppendLine(line); + } + } + else if (line.StartsWith("[offset:", StringComparison.Ordinal)) // [length:How long the song is] + { + var temp = line.Replace("[offset:", string.Empty).Replace("]", string.Empty).Replace("'", string.Empty).RemoveChar(' ').TrimEnd(); + if (double.TryParse(temp, out var d)) + { + offsetInMilliseconds = d; + } + } + else if (line.StartsWith("[by:", StringComparison.Ordinal)) // [by:Creator of the LRC file] + { + if (subtitle.Paragraphs.Count < 1) + { + header.AppendLine(line); + } + } + else if (!string.IsNullOrWhiteSpace(line)) + { + if (subtitle.Paragraphs.Count < 1) + { + header.AppendLine(line); + } + + _errorCount++; + } + else if (subtitle.Paragraphs.Count < 1) + { + header.AppendLine(line); + } + } + + header = new StringBuilder(Lrc.RemoveSoftwareAndVersion(header.ToString())); + header.AppendLine(); + + if (!header.ToString().Contains("[re:", StringComparison.Ordinal)) + { + header.AppendLine("[re: Subtitle Edit]"); + } + + if (!header.ToString().Contains("[ve:", StringComparison.Ordinal)) + { + header.AppendLine($"[ve: {Utilities.AssemblyVersion}]"); + } + + subtitle.Header = header.ToString(); + + var max = subtitle.Paragraphs.Count; + for (var i = 0; i < max; i++) + { + var p = subtitle.Paragraphs[i]; + while (RegexTimeCodes.Match(p.Text).Success) + { + var s = p.Text.Substring(1, 9); + p.Text = p.Text.Remove(0, 11).Trim(); + var parts = s.Split(splitChars, StringSplitOptions.RemoveEmptyEntries); + try + { + var minutes = int.Parse(parts[0]); + var seconds = int.Parse(parts[1]); + var milliseconds = int.Parse(parts[2]) * 10; + var text = GetTextAfterTimeCodes(p.Text); + var start = new TimeCode(0, minutes, seconds, milliseconds); + var newParagraph = new Paragraph(start, new TimeCode(), text); + subtitle.Paragraphs.Add(newParagraph); + } + catch + { + _errorCount++; + } + } + } + + subtitle.Sort(SubtitleSortCriteria.StartTime); + + var index = 0; + foreach (var p in subtitle.Paragraphs) + { + p.Text = Utilities.AutoBreakLine(p.Text); + var next = subtitle.GetParagraphOrDefault(index + 1); + if (next != null) + { + if (string.IsNullOrEmpty(next.Text)) + { + p.EndTime = new TimeCode(next.StartTime.TotalMilliseconds); + } + else + { + p.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines; + } + if (p.DurationTotalMilliseconds > Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds) + { + double duration = Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds; + p.EndTime = new TimeCode(p.StartTime.TotalMilliseconds + duration); + } + } + else + { + var duration = Utilities.GetOptimalDisplayMilliseconds(p.Text, 16) + 1500; + p.EndTime = new TimeCode(p.StartTime.TotalMilliseconds + duration); + } + index++; + } + + subtitle.RemoveEmptyLines(); + subtitle.Renumber(); + if (Math.Abs(offsetInMilliseconds) > 0.01) + { + foreach (var paragraph in subtitle.Paragraphs) + { + paragraph.StartTime.TotalMilliseconds += offsetInMilliseconds; + paragraph.EndTime.TotalMilliseconds += offsetInMilliseconds; + } + } + } + + private static string GetTextAfterTimeCodes(string s) + { + while (RegexTimeCodes.IsMatch(s)) + { + s = s.Remove(0, 11).Trim(); + } + + return s; + } + } +} diff --git a/src/libse/SubtitleFormats/SubtitleFormat.cs b/src/libse/SubtitleFormats/SubtitleFormat.cs index 4bb3a2569..ba1cc59f5 100644 --- a/src/libse/SubtitleFormats/SubtitleFormat.cs +++ b/src/libse/SubtitleFormats/SubtitleFormat.cs @@ -154,6 +154,7 @@ namespace Nikse.SubtitleEdit.Core.SubtitleFormats new KanopyHtml(), new LambdaCap(), new Lrc(), + new Lrc3DigitsMs(), new LrcNoEndTime(), new MacSub(), new MagicVideoTitler(), @@ -247,6 +248,7 @@ namespace Nikse.SubtitleEdit.Core.SubtitleFormats new WebVTT(), new WebVTTFileWithLineNumber(), new WhisperRaw(), + new WhisperRaw2(), new Xif(), new Xmp(), new YouTubeAnnotations(), diff --git a/src/libse/SubtitleFormats/WhisperRaw2.cs b/src/libse/SubtitleFormats/WhisperRaw2.cs new file mode 100644 index 000000000..044de86ab --- /dev/null +++ b/src/libse/SubtitleFormats/WhisperRaw2.cs @@ -0,0 +1,71 @@ +using Nikse.SubtitleEdit.Core.Common; +using Nikse.SubtitleEdit.Core.Enums; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using System.Text.RegularExpressions; + +namespace Nikse.SubtitleEdit.Core.SubtitleFormats +{ + public class WhisperRaw2 : SubtitleFormat + { + private readonly Regex _timeRegex = new Regex(@"^\[\d+.\d+s -> \d+.\d+s\]", RegexOptions.Compiled); + public override string Extension => ".txt"; + public override string Name => "Whisper Raw 2"; + + public override string ToText(Subtitle subtitle, string title) + { + var sb = new StringBuilder(); + const string writeFormat = "[{0} -> {1}] {2}"; + foreach (var p in subtitle.Paragraphs) + { + sb.AppendLine(string.Format(writeFormat, EncodeEndTimeCode(p.StartTime), EncodeEndTimeCode(p.EndTime), HtmlUtil.RemoveHtmlTags(p.Text.Replace(Environment.NewLine, " "), true))); + sb.AppendLine(); + } + + return sb.ToString(); + } + + private static string EncodeEndTimeCode(TimeCode time) + { + return $"{time.TotalSeconds:0.00}s"; + } + + public override void LoadSubtitle(Subtitle subtitle, List lines, string fileName) + { + subtitle.Paragraphs.Clear(); + _errorCount = 0; + foreach (var line in lines) + { + var trimmedLine = line.Trim(); + if (trimmedLine.StartsWith('[')) + { + var match = _timeRegex.Match(trimmedLine); + if (match.Success) + { + var timeString = trimmedLine.Substring(0, match.Length).Trim('[', ']'); + var splitPos = timeString.IndexOf('>'); + if (splitPos > 1 && splitPos < timeString.Length - 3) + { + var start = timeString.Substring(0, splitPos -1).Trim().TrimEnd('s'); + var end = timeString.Substring(splitPos +1).Trim().TrimEnd('s'); + var text = trimmedLine.Remove(0, match.Length).Trim(); + if (!string.IsNullOrEmpty(text)) + { + if (double.TryParse(start, NumberStyles.Any, CultureInfo.InvariantCulture, out var dStart) && + double.TryParse(end, NumberStyles.Any, CultureInfo.InvariantCulture, out var dEnd)) + { + subtitle.Paragraphs.Add(new Paragraph(text, dStart * 1000.0, dEnd * 1000.0)); + } + } + } + } + } + } + + subtitle.Sort(SubtitleSortCriteria.StartTime); + subtitle.Renumber(); + } + } +} diff --git a/src/libse/TextToSpeech/PiperModel.cs b/src/libse/TextToSpeech/PiperModel.cs new file mode 100644 index 000000000..005771548 --- /dev/null +++ b/src/libse/TextToSpeech/PiperModel.cs @@ -0,0 +1,30 @@ +using System.Linq; + +namespace Nikse.SubtitleEdit.Core.TextToSpeech +{ + public class PiperModel + { + public string Voice { get; set; } + public string Language { get; set; } + public string Quality { get; set; } + public string Model { get; set; } + public string ModelShort => Model.Split('/').Last(); + + public string Config { get; set; } + public string ConfigShort => Config.Split('/').Last(); + + public override string ToString() + { + return $"{Language} - {Voice} ({Quality})"; + } + + public PiperModel(string voice, string language, string quality, string model, string config) + { + Voice = voice; + Language = language; + Quality = quality; + Model = model; + Config = config; + } + } +} diff --git a/src/libse/TextToSpeech/PiperModels.cs b/src/libse/TextToSpeech/PiperModels.cs deleted file mode 100644 index 7e4841601..000000000 --- a/src/libse/TextToSpeech/PiperModels.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System.Collections.Generic; -using System.Linq; - -namespace Nikse.SubtitleEdit.Core.TextToSpeech -{ - public class PiperModels - { - public string Voice { get; set; } - public string Language { get; set; } - public string Quality { get; set; } - public string Model { get; set; } - public string ModelShort => Model.Split('/').Last(); - - public string Config { get; set; } - public string ConfigShort => Config.Split('/').Last(); - - public override string ToString() - { - return $"{Language} - {Voice} ({Quality})"; - } - - public PiperModels(string voice, string language, string quality, string model, string config) - { - Voice = voice; - Language = language; - Quality = quality; - Model = model; - Config = config; - } - - public static List GetVoices() - { - var models = new List - { - new PiperModels("kareem", "Arabic", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ar/ar_JO/kareem/medium/ar_JO-kareem-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ar/ar_JO/kareem/medium/ar_JO-kareem-medium.onnx.json"), - new PiperModels("upc_ona", "Catalan", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ca/ca_ES/upc_ona/medium/ca_ES-upc_ona-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ca/ca_ES/upc_ona/medium/ca_ES-upc_ona-medium.onnx.json"), - new PiperModels("jirka", "Czech", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/cs/cs_CZ/jirka/medium/cs_CZ-jirka-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/cs/cs_CZ/jirka/medium/cs_CZ-jirka-medium.onnx.json"), - new PiperModels("talesyntese", "Danish", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/da/da_DK/talesyntese/medium/da_DK-talesyntese-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/da/da_DK/talesyntese/medium/da_DK-talesyntese-medium.onnx.json"), - new PiperModels("eva_k", "German", "low", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/de/de_DE/eva_k/x_low/de_DE-eva_k-x_low.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/de/de_DE/eva_k/x_low/de_DE-eva_k-x_low.onnx.json"), - new PiperModels("rapunzelina", "Greek", "low", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/el/el_GR/rapunzelina/low/el_GR-rapunzelina-low.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/el/el_GR/rapunzelina/low/el_GR-rapunzelina-low.onnx.json"), - new PiperModels("alan", "English GB", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_GB/alan/medium/en_GB-alan-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_GB/alan/medium/en_GB-alan-medium.onnx.json"), - new PiperModels("alba", "English GB", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_GB/alba/medium/en_GB-alba-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_GB/alba/medium/en_GB-alba-medium.onnx.json"), - new PiperModels("cori", "English GB", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_GB/cori/high/en_GB-cori-high.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_GB/cori/medium/en_GB-cori-medium.onnx.json"), - new PiperModels("jenny_dioco", "English GB", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_GB/jenny_dioco/medium/en_GB-jenny_dioco-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_GB/jenny_dioco/medium/en_GB-jenny_dioco-medium.onnx.json"), - new PiperModels("northern_english_male", "English GB", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_GB/northern_english_male/medium/en_GB-northern_english_male-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_GB/northern_english_male/medium/en_GB-northern_english_male-medium.onnx.json"), - new PiperModels("semaine", "English GB", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_GB/semaine/medium/en_GB-semaine-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_GB/semaine/medium/en_GB-semaine-medium.onnx.json"), - new PiperModels("amy", "English US", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/amy/medium/en_US-amy-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/amy/medium/en_US-amy-medium.onnx.json"), - new PiperModels("arctic", "English US", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/arctic/medium/en_US-arctic-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/arctic/medium/en_US-arctic-medium.onnx.json"), - new PiperModels("hfc_female", "English US", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/hfc_female/medium/en_US-hfc_female-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/hfc_female/medium/en_US-hfc_female-medium.onnx.json"), - new PiperModels("hfc_male", "English US", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/hfc_male/medium/en_US-hfc_male-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/hfc_male/medium/en_US-hfc_male-medium.onnx.json"), - new PiperModels("joe", "English US", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/joe/medium/en_US-joe-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/joe/medium/en_US-joe-medium.onnx.json"), - new PiperModels("kristin", "English US", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/kristin/medium/en_US-kristin-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/kristin/medium/en_US-kristin-medium.onnx.json"), - new PiperModels("kusal", "English US", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/kusal/medium/en_US-kusal-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/kusal/medium/en_US-kusal-medium.onnx.json"), - new PiperModels("l2arctic", "English US", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/l2arctic/medium/en_US-l2arctic-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/l2arctic/medium/en_US-l2arctic-medium.onnx.json"), - new PiperModels("lessac", "English US", "high", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/lessac/high/en_US-lessac-high.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/lessac/high/en_US-lessac-high.onnx.json"), - new PiperModels("libritts", "English US", "high", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/libritts/high/en_US-libritts-high.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/libritts/high/en_US-libritts-high.onnx.json"), - new PiperModels("ljspeech", "English US", "high", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/ljspeech/high/en_US-ljspeech-high.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/ljspeech/high/en_US-ljspeech-high.onnx.json"), - new PiperModels("ryan", "English US", "high", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/ryan/high/en_US-ryan-high.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/ryan/high/en_US-ryan-high.onnx.json"), - new PiperModels("davefx", "Spanish ES", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/es/es_ES/davefx/medium/es_ES-davefx-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/es/es_ES/davefx/medium/es_ES-davefx-medium.onnx.json"), - new PiperModels("claude", "Spanish MX", "high", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/es/es_MX/claude/high/es_MX-claude-high.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/es/es_MX/claude/high/es_MX-claude-high.onnx.json"), - new PiperModels("amir", "Farsi", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/fa/fa_IR/amir/medium/fa_IR-amir-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/fa/fa_IR/amir/medium/fa_IR-amir-medium.onnx.json"), - new PiperModels("gyro", "Farsi", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/fa/fa_IR/gyro/medium/fa_IR-gyro-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/fa/fa_IR/gyro/medium/fa_IR-gyro-medium.onnx.json"), - new PiperModels("harri", "Finnish", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/fi/fi_FI/harri/medium/fi_FI-harri-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/fi/fi_FI/harri/medium/fi_FI-harri-medium.onnx.json"), - new PiperModels("mls", "French", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/fr/fr_FR/mls/medium/fr_FR-mls-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/fr/fr_FR/mls/medium/fr_FR-mls-medium.onnx.json"), - new PiperModels("siwis", "French", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/fr/fr_FR/siwis/medium/fr_FR-siwis-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/fr/fr_FR/siwis/medium/fr_FR-siwis-medium.onnx.json"), - new PiperModels("tom", "French", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/fr/fr_FR/tom/medium/fr_FR-tom-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/fr/fr_FR/tom/medium/fr_FR-tom-medium.onnx.json"), - new PiperModels("upmc", "French", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/fr/fr_FR/upmc/medium/fr_FR-upmc-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/fr/fr_FR/upmc/medium/fr_FR-upmc-medium.onnx.json?"), - new PiperModels("berta", "Hungarian", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/hu/hu_HU/berta/medium/hu_HU-berta-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/hu/hu_HU/berta/medium/hu_HU-berta-medium.onnx.json"), - new PiperModels("imre", "Hungarian", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/hu/hu_HU/imre/medium/hu_HU-imre-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/hu/hu_HU/imre/medium/hu_HU-imre-medium.onnx.json"), - new PiperModels("bui", "Icelandic", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/is/is_IS/bui/medium/is_IS-bui-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/is/is_IS/bui/medium/is_IS-bui-medium.onnx.json"), - new PiperModels("salka", "Icelandic", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/is/is_IS/salka/medium/is_IS-salka-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/is/is_IS/salka/medium/is_IS-salka-medium.onnx.json"), - new PiperModels("steinn", "Icelandic", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/is/is_IS/steinn/medium/is_IS-steinn-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/is/is_IS/steinn/medium/is_IS-steinn-medium.onnx.json"), - new PiperModels("ugla", "Icelandic", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/is/is_IS/ugla/medium/is_IS-ugla-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/is/is_IS/ugla/medium/is_IS-ugla-medium.onnx.json"), - new PiperModels("riccardo", "Italian", "low", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/it/it_IT/riccardo/x_low/it_IT-riccardo-x_low.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/it/it_IT/riccardo/x_low/it_IT-riccardo-x_low.onnx.json"), - new PiperModels("natia", "Georgian", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ka/ka_GE/natia/medium/ka_GE-natia-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ka/ka_GE/natia/medium/ka_GE-natia-medium.onnx.json"), - new PiperModels("issai", "Kazakh", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/kk/kk_KZ/issai/high/kk_KZ-issai-high.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/kk/kk_KZ/issai/high/kk_KZ-issai-high.onnx.json"), - new PiperModels("marylux", "Luxembourgish", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/lb/lb_LU/marylux/medium/lb_LU-marylux-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/lb/lb_LU/marylux/medium/lb_LU-marylux-medium.onnx.json"), - new PiperModels("google", "Nepali", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ne/ne_NP/google/medium/ne_NP-google-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ne/ne_NP/google/medium/ne_NP-google-medium.onnx.json"), - new PiperModels("nathalie", "Dutch BE", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/nl/nl_BE/nathalie/medium/nl_BE-nathalie-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/nl/nl_BE/nathalie/medium/nl_BE-nathalie-medium.onnx.json"), - new PiperModels("rdh", "Dutch BE", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/nl/nl_BE/rdh/medium/nl_BE-rdh-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/nl/nl_BE/rdh/medium/nl_BE-rdh-medium.onnx.json"), - new PiperModels("mls", "Dutch NL", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/nl/nl_NL/mls/medium/nl_NL-mls-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/nl/nl_NL/mls/medium/nl_NL-mls-medium.onnx.json"), - new PiperModels("talesyntese", "Norwegian", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/no/no_NO/talesyntese/medium/no_NO-talesyntese-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/no/no_NO/talesyntese/medium/no_NO-talesyntese-medium.onnx.json"), - new PiperModels("darkman", "Polish", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/pl/pl_PL/darkman/medium/pl_PL-darkman-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/pl/pl_PL/darkman/medium/pl_PL-darkman-medium.onnx.json"), - new PiperModels("gosia", "Polish", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/pl/pl_PL/gosia/medium/pl_PL-gosia-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/pl/pl_PL/gosia/medium/pl_PL-gosia-medium.onnx.json"), - new PiperModels("mc_speech", "Polish", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/pl/pl_PL/mc_speech/medium/pl_PL-mc_speech-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/pl/pl_PL/mc_speech/medium/pl_PL-mc_speech-medium.onnx.json"), - new PiperModels("faber", "Portuguese BR", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/pt/pt_BR/faber/medium/pt_BR-faber-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/pt/pt_BR/faber/medium/pt_BR-faber-medium.onnx.json"), - new PiperModels("tugão", "Portuguese PT", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/pt/pt_PT/tug%C3%A3o/medium/pt_PT-tug%C3%A3o-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/pt/pt_PT/tug%C3%A3o/medium/pt_PT-tug%C3%A3o-medium.onnx.json"), - new PiperModels("mihai", "Romanian", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ro/ro_RO/mihai/medium/ro_RO-mihai-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ro/ro_RO/mihai/medium/ro_RO-mihai-medium.onnx.json"), - new PiperModels("dmitri", "Russian", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ru/ru_RU/dmitri/medium/ru_RU-dmitri-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ru/ru_RU/dmitri/medium/ru_RU-dmitri-medium.onnx.json"), - new PiperModels("irina", "Serbian", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ru/ru_RU/irina/medium/ru_RU-irina-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/ru/ru_RU/irina/medium/ru_RU-irina-medium.onnx.json"), - new PiperModels("lili", "Slovak ", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/sr/sr_RS/serbski_institut/medium/sr_RS-serbski_institut-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/sk/sk_SK/lili/medium/sk_SK-lili-medium.onnx.json"), - new PiperModels("artur", "Slovenian ", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/sl/sl_SI/artur/medium/sl_SI-artur-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/sl/sl_SI/artur/medium/sl_SI-artur-medium.onnx.json"), - new PiperModels("serbski_institut", "Serbian ", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/sr/sr_RS/serbski_institut/medium/sr_RS-serbski_institut-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/sr/sr_RS/serbski_institut/medium/sr_RS-serbski_institut-medium.onnx.json"), - new PiperModels("nst", "Swedish", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/sv/sv_SE/nst/medium/sv_SE-nst-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/sv/sv_SE/nst/medium/sv_SE-nst-medium.onnx.json"), - new PiperModels("lanfrica", "Swahili", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/sw/sw_CD/lanfrica/medium/sw_CD-lanfrica-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/sw/sw_CD/lanfrica/medium/sw_CD-lanfrica-medium.onnx.json"), - new PiperModels("fettah", "Turkish", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/tr/tr_TR/fettah/medium/tr_TR-fettah-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/tr/tr_TR/fettah/medium/tr_TR-fettah-medium.onnx.json"), - new PiperModels("ukrainian_tts", "Ukrainian", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/uk/uk_UA/ukrainian_tts/medium/uk_UA-ukrainian_tts-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/uk/uk_UA/ukrainian_tts/medium/uk_UA-ukrainian_tts-medium.onnx.json"), - new PiperModels("vais1000", "Vietnamese", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/vi/vi_VN/vais1000/medium/vi_VN-vais1000-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/vi/vi_VN/vais1000/medium/vi_VN-vais1000-medium.onnx.json"), - new PiperModels("huayan", "Chinese", "medium", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/zh/zh_CN/huayan/medium/zh_CN-huayan-medium.onnx", "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/zh/zh_CN/huayan/medium/zh_CN-huayan-medium.onnx.json"), - }; - - return models.OrderBy(p=>p.ToString()).ToList(); - } - } -} diff --git a/src/ui/Controls/NikseComboBoxCollection.cs b/src/ui/Controls/NikseComboBoxCollection.cs index 1bc96d4ee..43b4f011c 100644 --- a/src/ui/Controls/NikseComboBoxCollection.cs +++ b/src/ui/Controls/NikseComboBoxCollection.cs @@ -23,6 +23,11 @@ namespace Nikse.SubtitleEdit.Controls _items.AddRange(items); } + public void AddRange(string[] items) + { + _items.AddRange(items); + } + public IEnumerator GetEnumerator() { return _items.GetEnumerator(); diff --git a/src/ui/Forms/ApplyDurationLimits.cs b/src/ui/Forms/ApplyDurationLimits.cs index e0beff8c3..efb6d40b6 100644 --- a/src/ui/Forms/ApplyDurationLimits.cs +++ b/src/ui/Forms/ApplyDurationLimits.cs @@ -338,21 +338,9 @@ namespace Nikse.SubtitleEdit.Forms } } - private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) - { - foreach (ListViewItem item in listViewFixes.Items) - { - item.Checked = true; - } - } + private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) => listViewFixes.CheckAll(); - private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) - { - foreach (ListViewItem item in listViewFixes.Items) - { - item.Checked = !item.Checked; - } - } + private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) => listViewFixes.InvertCheck(); private void checkBoxCheckShotChanges_CheckedChanged(object sender, EventArgs e) { diff --git a/src/ui/Forms/Assa/SubStationAlphaStylesCategoriesImportExport.cs b/src/ui/Forms/Assa/SubStationAlphaStylesCategoriesImportExport.cs index 5b0e01072..2f8664d93 100644 --- a/src/ui/Forms/Assa/SubStationAlphaStylesCategoriesImportExport.cs +++ b/src/ui/Forms/Assa/SubStationAlphaStylesCategoriesImportExport.cs @@ -125,20 +125,8 @@ namespace Nikse.SubtitleEdit.Forms.Assa } } - private void ToolStripMenuItemSelectAll_Click(object sender, EventArgs e) - { - foreach (ListViewItem item in listViewCategories.Items) - { - item.Checked = true; - } - } + private void ToolStripMenuItemSelectAll_Click(object sender, EventArgs e) => listViewCategories.CheckAll(); - private void ToolStripMenuItemInverseSelection_Click(object sender, EventArgs e) - { - foreach (ListViewItem item in listViewCategories.Items) - { - item.Checked = !item.Checked; - } - } + private void ToolStripMenuItemInverseSelection_Click(object sender, EventArgs e) => listViewCategories.InvertCheck(); } } diff --git a/src/ui/Forms/AutoBreakUnbreakLines.cs b/src/ui/Forms/AutoBreakUnbreakLines.cs index 430b6f3fa..08a185aa7 100644 --- a/src/ui/Forms/AutoBreakUnbreakLines.cs +++ b/src/ui/Forms/AutoBreakUnbreakLines.cs @@ -251,18 +251,12 @@ namespace Nikse.SubtitleEdit.Forms private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewFixes.Items) - { - item.Checked = true; - } + listViewFixes.CheckAll(); } private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewFixes.Items) - { - item.Checked = !item.Checked; - } + listViewFixes.InvertCheck(); } private void AutoBreakUnbreakLines_FormClosing(object sender, FormClosingEventArgs e) diff --git a/src/ui/Forms/BatchConvert.cs b/src/ui/Forms/BatchConvert.cs index 6fefb758c..71e77afee 100644 --- a/src/ui/Forms/BatchConvert.cs +++ b/src/ui/Forms/BatchConvert.cs @@ -3977,18 +3977,12 @@ namespace Nikse.SubtitleEdit.Forms private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewConvertOptions.Items) - { - item.Checked = true; - } + listViewConvertOptions.CheckAll(); } private void inverseSelectionToolStripMenuItem_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewConvertOptions.Items) - { - item.Checked = !item.Checked; - } + listViewConvertOptions.InvertCheck(); } private void listViewInputFiles_ColumnClick(object sender, ColumnClickEventArgs e) @@ -3998,6 +3992,11 @@ namespace Nikse.SubtitleEdit.Forms return; } + for (var i = 0; i < listViewInputFiles.Columns.Count; i++) + { + ListViewSorter.SetSortArrow(listViewInputFiles.Columns[i], SortOrder.None); + } + if (!(listViewInputFiles.ListViewItemSorter is ListViewSorter sorter)) { sorter = new ListViewSorter @@ -4020,7 +4019,10 @@ namespace Nikse.SubtitleEdit.Forms sorter.IsNumber = false; sorter.IsDisplayFileSize = e.Column == columnHeaderSize.DisplayIndex; } + listViewInputFiles.Sort(); + + ListViewSorter.SetSortArrow(listViewInputFiles.Columns[e.Column], sorter.Descending ? SortOrder.Descending : SortOrder.Ascending); } private void buttonBrowseEncoding_Click(object sender, EventArgs e) diff --git a/src/ui/Forms/ChangeCasingNames.cs b/src/ui/Forms/ChangeCasingNames.cs index 5fb3da6ed..f796880ce 100644 --- a/src/ui/Forms/ChangeCasingNames.cs +++ b/src/ui/Forms/ChangeCasingNames.cs @@ -335,18 +335,12 @@ namespace Nikse.SubtitleEdit.Forms private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewFixes.Items) - { - item.Checked = true; - } + listViewFixes.CheckAll(); } private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewFixes.Items) - { - item.Checked = !item.Checked; - } + listViewFixes.InvertCheck(); } private void toolStripMenuItem1SelectAll_Click(object sender, EventArgs e) diff --git a/src/ui/Forms/FixCommonErrors.cs b/src/ui/Forms/FixCommonErrors.cs index ea9b2a18f..65d35f812 100644 --- a/src/ui/Forms/FixCommonErrors.cs +++ b/src/ui/Forms/FixCommonErrors.cs @@ -1145,21 +1145,9 @@ namespace Nikse.SubtitleEdit.Forms listViewFixes.Sort(); } - private void ButtonSelectAllClick(object sender, EventArgs e) - { - foreach (ListViewItem item in listView1.Items) - { - item.Checked = true; - } - } + private void ButtonSelectAllClick(object sender, EventArgs e) => listView1.CheckAll(); - private void ButtonInverseSelectionClick(object sender, EventArgs e) - { - foreach (ListViewItem item in listView1.Items) - { - item.Checked = !item.Checked; - } - } + private void ButtonInverseSelectionClick(object sender, EventArgs e) => listView1.InvertCheck(); private void ListViewFixesSelectedIndexChanged(object sender, EventArgs e) { @@ -1370,18 +1358,12 @@ namespace Nikse.SubtitleEdit.Forms private void ButtonFixesSelectAllClick(object sender, EventArgs e) { - foreach (ListViewItem item in listViewFixes.Items) - { - item.Checked = true; - } + listViewFixes.CheckAll(); } private void ButtonFixesInverseClick(object sender, EventArgs e) { - foreach (ListViewItem item in listViewFixes.Items) - { - item.Checked = !item.Checked; - } + listViewFixes.InvertCheck(); } private void ButtonFixesApplyClick(object sender, EventArgs e) @@ -1948,18 +1930,12 @@ namespace Nikse.SubtitleEdit.Forms private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewFixes.Items) - { - item.Checked = true; - } + listViewFixes.CheckAll(); } private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewFixes.Items) - { - item.Checked = !item.Checked; - } + listViewFixes.InvertCheck(); } private void setCurrentFixesAsDefaultToolStripMenuItem_Click(object sender, EventArgs e) diff --git a/src/ui/Forms/GenerateVideoWithHardSubs.Designer.cs b/src/ui/Forms/GenerateVideoWithHardSubs.Designer.cs index 533731909..160dea6aa 100644 --- a/src/ui/Forms/GenerateVideoWithHardSubs.Designer.cs +++ b/src/ui/Forms/GenerateVideoWithHardSubs.Designer.cs @@ -48,17 +48,53 @@ namespace Nikse.SubtitleEdit.Forms this.groupBoxCut = new System.Windows.Forms.GroupBox(); this.buttonCutTo = new System.Windows.Forms.Button(); this.buttonCutFrom = new System.Windows.Forms.Button(); + this.numericUpDownCutToSeconds = new Nikse.SubtitleEdit.Controls.NikseUpDown(); + this.numericUpDownCutToMinutes = new Nikse.SubtitleEdit.Controls.NikseUpDown(); + this.numericUpDownCutToHours = new Nikse.SubtitleEdit.Controls.NikseUpDown(); + this.numericUpDownCutFromSeconds = new Nikse.SubtitleEdit.Controls.NikseUpDown(); + this.numericUpDownCutFromMinutes = new Nikse.SubtitleEdit.Controls.NikseUpDown(); + this.numericUpDownCutFromHours = new Nikse.SubtitleEdit.Controls.NikseUpDown(); + this.labelCutTo = new Nikse.SubtitleEdit.Controls.NikseLabel(); + this.labelCutFrom = new Nikse.SubtitleEdit.Controls.NikseLabel(); this.checkBoxCut = new System.Windows.Forms.CheckBox(); + this.labelVideoBitrate = new Nikse.SubtitleEdit.Controls.NikseLabel(); this.checkBoxBox = new System.Windows.Forms.CheckBox(); this.checkBoxAlignRight = new System.Windows.Forms.CheckBox(); + this.labelInfo = new Nikse.SubtitleEdit.Controls.NikseLabel(); this.checkBoxRightToLeft = new System.Windows.Forms.CheckBox(); + this.comboBoxSubtitleFont = new Nikse.SubtitleEdit.Controls.NikseComboBox(); + this.labelSubtitleFont = new Nikse.SubtitleEdit.Controls.NikseLabel(); this.groupBoxVideo = new System.Windows.Forms.GroupBox(); + this.labelCrfHint = new Nikse.SubtitleEdit.Controls.NikseLabel(); this.buttonVideoChooseStandardRes = new System.Windows.Forms.Button(); + this.labelResolution = new Nikse.SubtitleEdit.Controls.NikseLabel(); + this.numericUpDownWidth = new Nikse.SubtitleEdit.Controls.NikseUpDown(); + this.numericUpDownHeight = new Nikse.SubtitleEdit.Controls.NikseUpDown(); + this.labelX = new Nikse.SubtitleEdit.Controls.NikseLabel(); + this.labelPreset = new Nikse.SubtitleEdit.Controls.NikseLabel(); + this.comboBoxTune = new Nikse.SubtitleEdit.Controls.NikseComboBox(); + this.comboBoxPreset = new Nikse.SubtitleEdit.Controls.NikseComboBox(); + this.labelTune = new Nikse.SubtitleEdit.Controls.NikseLabel(); + this.labelCRF = new Nikse.SubtitleEdit.Controls.NikseLabel(); + this.comboBoxVideoEncoding = new Nikse.SubtitleEdit.Controls.NikseComboBox(); + this.comboBoxCrf = new Nikse.SubtitleEdit.Controls.NikseComboBox(); + this.labelVideoEncoding = new Nikse.SubtitleEdit.Controls.NikseLabel(); this.groupBoxAudio = new System.Windows.Forms.GroupBox(); this.listViewAudioTracks = new System.Windows.Forms.ListView(); this.columnHeaderAudioTrack = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.labelAudioEnc = new Nikse.SubtitleEdit.Controls.NikseLabel(); + this.comboBoxAudioBitRate = new Nikse.SubtitleEdit.Controls.NikseComboBox(); + this.comboBoxAudioEnc = new Nikse.SubtitleEdit.Controls.NikseComboBox(); + this.labelAudioBitRate = new Nikse.SubtitleEdit.Controls.NikseLabel(); this.checkBoxMakeStereo = new System.Windows.Forms.CheckBox(); + this.labelAudioSampleRate = new Nikse.SubtitleEdit.Controls.NikseLabel(); + this.comboBoxAudioSampleRate = new Nikse.SubtitleEdit.Controls.NikseComboBox(); + this.numericUpDownTargetFileSize = new Nikse.SubtitleEdit.Controls.NikseUpDown(); + this.labelFileSize = new Nikse.SubtitleEdit.Controls.NikseLabel(); this.checkBoxTargetFileSize = new System.Windows.Forms.CheckBox(); + this.labelFileName = new Nikse.SubtitleEdit.Controls.NikseLabel(); + this.numericUpDownFontSize = new Nikse.SubtitleEdit.Controls.NikseUpDown(); + this.labelFontSize = new Nikse.SubtitleEdit.Controls.NikseLabel(); this.listViewBatch = new System.Windows.Forms.ListView(); this.columnHeaderVideoFile = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.columnHeaderResolution = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); @@ -73,6 +109,7 @@ namespace Nikse.SubtitleEdit.Forms this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); this.deleteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.clearToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.videoPlayerContainer1 = new Nikse.SubtitleEdit.Controls.VideoPlayerContainer(); this.buttonOutputFileSettings = new System.Windows.Forms.Button(); this.buttonPreview = new System.Windows.Forms.Button(); this.linkLabelHelp = new System.Windows.Forms.LinkLabel(); @@ -94,43 +131,6 @@ namespace Nikse.SubtitleEdit.Forms this.x352ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.x272ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.buttonMode = new System.Windows.Forms.Button(); - this.numericUpDownCutToSeconds = new Nikse.SubtitleEdit.Controls.NikseUpDown(); - this.numericUpDownCutToMinutes = new Nikse.SubtitleEdit.Controls.NikseUpDown(); - this.numericUpDownCutToHours = new Nikse.SubtitleEdit.Controls.NikseUpDown(); - this.numericUpDownCutFromSeconds = new Nikse.SubtitleEdit.Controls.NikseUpDown(); - this.numericUpDownCutFromMinutes = new Nikse.SubtitleEdit.Controls.NikseUpDown(); - this.numericUpDownCutFromHours = new Nikse.SubtitleEdit.Controls.NikseUpDown(); - this.labelCutTo = new Nikse.SubtitleEdit.Controls.NikseLabel(); - this.labelCutFrom = new Nikse.SubtitleEdit.Controls.NikseLabel(); - this.labelVideoBitrate = new Nikse.SubtitleEdit.Controls.NikseLabel(); - this.labelInfo = new Nikse.SubtitleEdit.Controls.NikseLabel(); - this.comboBoxSubtitleFont = new Nikse.SubtitleEdit.Controls.NikseComboBox(); - this.labelSubtitleFont = new Nikse.SubtitleEdit.Controls.NikseLabel(); - this.labelCrfHint = new Nikse.SubtitleEdit.Controls.NikseLabel(); - this.labelResolution = new Nikse.SubtitleEdit.Controls.NikseLabel(); - this.numericUpDownWidth = new Nikse.SubtitleEdit.Controls.NikseUpDown(); - this.numericUpDownHeight = new Nikse.SubtitleEdit.Controls.NikseUpDown(); - this.labelX = new Nikse.SubtitleEdit.Controls.NikseLabel(); - this.labelPreset = new Nikse.SubtitleEdit.Controls.NikseLabel(); - this.comboBoxTune = new Nikse.SubtitleEdit.Controls.NikseComboBox(); - this.comboBoxPreset = new Nikse.SubtitleEdit.Controls.NikseComboBox(); - this.labelTune = new Nikse.SubtitleEdit.Controls.NikseLabel(); - this.labelCRF = new Nikse.SubtitleEdit.Controls.NikseLabel(); - this.comboBoxVideoEncoding = new Nikse.SubtitleEdit.Controls.NikseComboBox(); - this.comboBoxCrf = new Nikse.SubtitleEdit.Controls.NikseComboBox(); - this.labelVideoEncoding = new Nikse.SubtitleEdit.Controls.NikseLabel(); - this.labelAudioEnc = new Nikse.SubtitleEdit.Controls.NikseLabel(); - this.comboBoxAudioBitRate = new Nikse.SubtitleEdit.Controls.NikseComboBox(); - this.comboBoxAudioEnc = new Nikse.SubtitleEdit.Controls.NikseComboBox(); - this.labelAudioBitRate = new Nikse.SubtitleEdit.Controls.NikseLabel(); - this.labelAudioSampleRate = new Nikse.SubtitleEdit.Controls.NikseLabel(); - this.comboBoxAudioSampleRate = new Nikse.SubtitleEdit.Controls.NikseComboBox(); - this.numericUpDownTargetFileSize = new Nikse.SubtitleEdit.Controls.NikseUpDown(); - this.labelFileSize = new Nikse.SubtitleEdit.Controls.NikseLabel(); - this.labelFileName = new Nikse.SubtitleEdit.Controls.NikseLabel(); - this.numericUpDownFontSize = new Nikse.SubtitleEdit.Controls.NikseUpDown(); - this.labelFontSize = new Nikse.SubtitleEdit.Controls.NikseLabel(); - this.videoPlayerContainer1 = new Nikse.SubtitleEdit.Controls.VideoPlayerContainer(); this.labelPreviewPleaseWait = new Nikse.SubtitleEdit.Controls.NikseLabel(); this.labelPass = new Nikse.SubtitleEdit.Controls.NikseLabel(); this.labelProgress = new Nikse.SubtitleEdit.Controls.NikseLabel(); @@ -268,7 +268,6 @@ namespace Nikse.SubtitleEdit.Forms this.nikseLabelOutputFileFolder.Size = new System.Drawing.Size(90, 13); this.nikseLabelOutputFileFolder.TabIndex = 144; this.nikseLabelOutputFileFolder.Text = "Use source folder"; - this.nikseLabelOutputFileFolder.Click += new System.EventHandler(this.nikseLabelOutputFileFolder_Click); // // buttonRemoveFile // @@ -360,437 +359,6 @@ namespace Nikse.SubtitleEdit.Forms this.buttonCutFrom.UseVisualStyleBackColor = true; this.buttonCutFrom.Click += new System.EventHandler(this.buttonCutFrom_Click); // - // checkBoxCut - // - this.checkBoxCut.AutoSize = true; - this.checkBoxCut.Location = new System.Drawing.Point(12, 36); - this.checkBoxCut.Name = "checkBoxCut"; - this.checkBoxCut.Size = new System.Drawing.Size(42, 17); - this.checkBoxCut.TabIndex = 0; - this.checkBoxCut.Text = "Cut"; - this.checkBoxCut.UseVisualStyleBackColor = true; - this.checkBoxCut.CheckedChanged += new System.EventHandler(this.checkBoxCut_CheckedChanged); - // - // checkBoxBox - // - this.checkBoxBox.AutoSize = true; - this.checkBoxBox.Location = new System.Drawing.Point(226, 27); - this.checkBoxBox.Name = "checkBoxBox"; - this.checkBoxBox.Size = new System.Drawing.Size(44, 17); - this.checkBoxBox.TabIndex = 2; - this.checkBoxBox.Text = "Box"; - this.checkBoxBox.UseVisualStyleBackColor = true; - this.checkBoxBox.CheckedChanged += new System.EventHandler(this.checkBoxBox_CheckedChanged); - // - // checkBoxAlignRight - // - this.checkBoxAlignRight.AutoSize = true; - this.checkBoxAlignRight.Location = new System.Drawing.Point(217, 114); - this.checkBoxAlignRight.Name = "checkBoxAlignRight"; - this.checkBoxAlignRight.Size = new System.Drawing.Size(72, 17); - this.checkBoxAlignRight.TabIndex = 10; - this.checkBoxAlignRight.Text = "Align right"; - this.checkBoxAlignRight.UseVisualStyleBackColor = true; - this.checkBoxAlignRight.CheckedChanged += new System.EventHandler(this.checkBoxAlignRight_CheckedChanged); - // - // checkBoxRightToLeft - // - this.checkBoxRightToLeft.AutoSize = true; - this.checkBoxRightToLeft.Location = new System.Drawing.Point(120, 114); - this.checkBoxRightToLeft.Name = "checkBoxRightToLeft"; - this.checkBoxRightToLeft.Size = new System.Drawing.Size(80, 17); - this.checkBoxRightToLeft.TabIndex = 9; - this.checkBoxRightToLeft.Text = "Right to left"; - this.checkBoxRightToLeft.UseVisualStyleBackColor = true; - this.checkBoxRightToLeft.CheckedChanged += new System.EventHandler(this.checkBoxRightToLeft_CheckedChanged); - // - // groupBoxVideo - // - this.groupBoxVideo.Controls.Add(this.labelCrfHint); - this.groupBoxVideo.Controls.Add(this.buttonVideoChooseStandardRes); - this.groupBoxVideo.Controls.Add(this.labelResolution); - this.groupBoxVideo.Controls.Add(this.numericUpDownWidth); - this.groupBoxVideo.Controls.Add(this.numericUpDownHeight); - this.groupBoxVideo.Controls.Add(this.labelX); - this.groupBoxVideo.Controls.Add(this.labelPreset); - this.groupBoxVideo.Controls.Add(this.comboBoxTune); - this.groupBoxVideo.Controls.Add(this.comboBoxPreset); - this.groupBoxVideo.Controls.Add(this.labelTune); - this.groupBoxVideo.Controls.Add(this.labelCRF); - this.groupBoxVideo.Controls.Add(this.comboBoxVideoEncoding); - this.groupBoxVideo.Controls.Add(this.comboBoxCrf); - this.groupBoxVideo.Controls.Add(this.labelVideoEncoding); - this.groupBoxVideo.Location = new System.Drawing.Point(6, 141); - this.groupBoxVideo.Name = "groupBoxVideo"; - this.groupBoxVideo.Size = new System.Drawing.Size(406, 166); - this.groupBoxVideo.TabIndex = 70; - this.groupBoxVideo.TabStop = false; - this.groupBoxVideo.Text = "Video"; - // - // buttonVideoChooseStandardRes - // - this.buttonVideoChooseStandardRes.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.buttonVideoChooseStandardRes.Location = new System.Drawing.Point(257, 15); - this.buttonVideoChooseStandardRes.Name = "buttonVideoChooseStandardRes"; - this.buttonVideoChooseStandardRes.Size = new System.Drawing.Size(69, 23); - this.buttonVideoChooseStandardRes.TabIndex = 3; - this.buttonVideoChooseStandardRes.Text = "..."; - this.buttonVideoChooseStandardRes.UseVisualStyleBackColor = true; - this.buttonVideoChooseStandardRes.Click += new System.EventHandler(this.buttonVideoChooseStandardRes_Click); - // - // groupBoxAudio - // - this.groupBoxAudio.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.groupBoxAudio.Controls.Add(this.listViewAudioTracks); - this.groupBoxAudio.Controls.Add(this.labelAudioEnc); - this.groupBoxAudio.Controls.Add(this.comboBoxAudioBitRate); - this.groupBoxAudio.Controls.Add(this.comboBoxAudioEnc); - this.groupBoxAudio.Controls.Add(this.labelAudioBitRate); - this.groupBoxAudio.Controls.Add(this.checkBoxMakeStereo); - this.groupBoxAudio.Controls.Add(this.labelAudioSampleRate); - this.groupBoxAudio.Controls.Add(this.comboBoxAudioSampleRate); - this.groupBoxAudio.Location = new System.Drawing.Point(430, 141); - this.groupBoxAudio.Name = "groupBoxAudio"; - this.groupBoxAudio.Size = new System.Drawing.Size(425, 166); - this.groupBoxAudio.TabIndex = 90; - this.groupBoxAudio.TabStop = false; - this.groupBoxAudio.Text = "Audio"; - // - // listViewAudioTracks - // - this.listViewAudioTracks.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.listViewAudioTracks.CheckBoxes = true; - this.listViewAudioTracks.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.columnHeaderAudioTrack}); - this.listViewAudioTracks.HideSelection = false; - this.listViewAudioTracks.Location = new System.Drawing.Point(229, 29); - this.listViewAudioTracks.Name = "listViewAudioTracks"; - this.listViewAudioTracks.Size = new System.Drawing.Size(190, 122); - this.listViewAudioTracks.TabIndex = 45; - this.listViewAudioTracks.UseCompatibleStateImageBehavior = false; - this.listViewAudioTracks.View = System.Windows.Forms.View.Details; - // - // columnHeaderAudioTrack - // - this.columnHeaderAudioTrack.Text = "Audio tracks"; - this.columnHeaderAudioTrack.Width = 160; - // - // checkBoxMakeStereo - // - this.checkBoxMakeStereo.AutoSize = true; - this.checkBoxMakeStereo.Checked = true; - this.checkBoxMakeStereo.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBoxMakeStereo.Location = new System.Drawing.Point(91, 58); - this.checkBoxMakeStereo.Name = "checkBoxMakeStereo"; - this.checkBoxMakeStereo.Size = new System.Drawing.Size(57, 17); - this.checkBoxMakeStereo.TabIndex = 2; - this.checkBoxMakeStereo.Text = "Stereo"; - this.checkBoxMakeStereo.UseVisualStyleBackColor = true; - // - // checkBoxTargetFileSize - // - this.checkBoxTargetFileSize.AutoSize = true; - this.checkBoxTargetFileSize.Location = new System.Drawing.Point(22, 327); - this.checkBoxTargetFileSize.Name = "checkBoxTargetFileSize"; - this.checkBoxTargetFileSize.Size = new System.Drawing.Size(192, 17); - this.checkBoxTargetFileSize.TabIndex = 100; - this.checkBoxTargetFileSize.Text = "Target file size (two pass encoding)"; - this.checkBoxTargetFileSize.UseVisualStyleBackColor = true; - this.checkBoxTargetFileSize.CheckedChanged += new System.EventHandler(this.checkBoxTargetFileSize_CheckedChanged); - // - // listViewBatch - // - this.listViewBatch.AllowDrop = true; - this.listViewBatch.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.listViewBatch.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.columnHeaderVideoFile, - this.columnHeaderResolution, - this.columnHeaderSize, - this.columnHeaderSubtitleFile, - this.columnHeaderStatus}); - this.listViewBatch.ContextMenuStrip = this.contextMenuStripBatch; - this.listViewBatch.FullRowSelect = true; - this.listViewBatch.HideSelection = false; - this.listViewBatch.Location = new System.Drawing.Point(6, 316); - this.listViewBatch.Name = "listViewBatch"; - this.listViewBatch.Size = new System.Drawing.Size(852, 191); - this.listViewBatch.TabIndex = 3; - this.listViewBatch.UseCompatibleStateImageBehavior = false; - this.listViewBatch.View = System.Windows.Forms.View.Details; - this.listViewBatch.DragDrop += new System.Windows.Forms.DragEventHandler(this.listViewBatch_DragDrop); - this.listViewBatch.DragEnter += new System.Windows.Forms.DragEventHandler(this.listViewBatch_DragEnter); - this.listViewBatch.KeyDown += new System.Windows.Forms.KeyEventHandler(this.listViewBatch_KeyDown); - // - // columnHeaderVideoFile - // - this.columnHeaderVideoFile.Text = "Video file"; - this.columnHeaderVideoFile.Width = 420; - // - // columnHeaderResolution - // - this.columnHeaderResolution.Text = "Resolution"; - this.columnHeaderResolution.Width = 80; - // - // columnHeaderSize - // - this.columnHeaderSize.Text = "Size"; - this.columnHeaderSize.Width = 80; - // - // columnHeaderSubtitleFile - // - this.columnHeaderSubtitleFile.Text = "Subtitle file"; - this.columnHeaderSubtitleFile.Width = 180; - // - // columnHeaderStatus - // - this.columnHeaderStatus.Text = "Status"; - this.columnHeaderStatus.Width = 80; - // - // contextMenuStripBatch - // - this.contextMenuStripBatch.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.addFilesToolStripMenuItem, - this.toolStripSeparator2, - this.pickSubtitleFileToolStripMenuItem, - this.removeSubtitleFileToolStripMenuItem, - this.toolStripSeparator1, - this.deleteToolStripMenuItem, - this.clearToolStripMenuItem}); - this.contextMenuStripBatch.Name = "contextMenuStripBatch"; - this.contextMenuStripBatch.Size = new System.Drawing.Size(179, 126); - this.contextMenuStripBatch.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuStripBatch_Opening); - // - // addFilesToolStripMenuItem - // - this.addFilesToolStripMenuItem.Name = "addFilesToolStripMenuItem"; - this.addFilesToolStripMenuItem.Size = new System.Drawing.Size(178, 22); - this.addFilesToolStripMenuItem.Text = "Add video files..."; - this.addFilesToolStripMenuItem.Click += new System.EventHandler(this.addFilesToolStripMenuItem_Click); - // - // toolStripSeparator2 - // - this.toolStripSeparator2.Name = "toolStripSeparator2"; - this.toolStripSeparator2.Size = new System.Drawing.Size(175, 6); - // - // pickSubtitleFileToolStripMenuItem - // - this.pickSubtitleFileToolStripMenuItem.Name = "pickSubtitleFileToolStripMenuItem"; - this.pickSubtitleFileToolStripMenuItem.Size = new System.Drawing.Size(178, 22); - this.pickSubtitleFileToolStripMenuItem.Text = "Pick subtitle file..."; - this.pickSubtitleFileToolStripMenuItem.Click += new System.EventHandler(this.pickSubtitleFileToolStripMenuItem_Click); - // - // removeSubtitleFileToolStripMenuItem - // - this.removeSubtitleFileToolStripMenuItem.Name = "removeSubtitleFileToolStripMenuItem"; - this.removeSubtitleFileToolStripMenuItem.Size = new System.Drawing.Size(178, 22); - this.removeSubtitleFileToolStripMenuItem.Text = "Remove subtitle file"; - this.removeSubtitleFileToolStripMenuItem.Click += new System.EventHandler(this.removeSubtitleFileToolStripMenuItem_Click); - // - // toolStripSeparator1 - // - this.toolStripSeparator1.Name = "toolStripSeparator1"; - this.toolStripSeparator1.Size = new System.Drawing.Size(175, 6); - // - // deleteToolStripMenuItem - // - this.deleteToolStripMenuItem.Name = "deleteToolStripMenuItem"; - this.deleteToolStripMenuItem.Size = new System.Drawing.Size(178, 22); - this.deleteToolStripMenuItem.Text = "Delete"; - this.deleteToolStripMenuItem.Click += new System.EventHandler(this.deleteToolStripMenuItem_Click); - // - // clearToolStripMenuItem - // - this.clearToolStripMenuItem.Name = "clearToolStripMenuItem"; - this.clearToolStripMenuItem.Size = new System.Drawing.Size(178, 22); - this.clearToolStripMenuItem.Text = "Clear"; - this.clearToolStripMenuItem.Click += new System.EventHandler(this.clearToolStripMenuItem_Click); - // - // buttonOutputFileSettings - // - this.buttonOutputFileSettings.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.buttonOutputFileSettings.Location = new System.Drawing.Point(255, 513); - this.buttonOutputFileSettings.Name = "buttonOutputFileSettings"; - this.buttonOutputFileSettings.Size = new System.Drawing.Size(167, 23); - this.buttonOutputFileSettings.TabIndex = 148; - this.buttonOutputFileSettings.Text = "Output file/folder..."; - this.buttonOutputFileSettings.UseVisualStyleBackColor = true; - this.buttonOutputFileSettings.Click += new System.EventHandler(this.buttonOutputFileSettings_Click); - // - // buttonPreview - // - this.buttonPreview.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.buttonPreview.Location = new System.Drawing.Point(621, 586); - this.buttonPreview.Name = "buttonPreview"; - this.buttonPreview.Size = new System.Drawing.Size(121, 23); - this.buttonPreview.TabIndex = 130; - this.buttonPreview.Text = "Preview"; - this.buttonPreview.UseVisualStyleBackColor = true; - this.buttonPreview.Click += new System.EventHandler(this.buttonPreview_Click); - // - // linkLabelHelp - // - this.linkLabelHelp.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.linkLabelHelp.AutoSize = true; - this.linkLabelHelp.Location = new System.Drawing.Point(844, 563); - this.linkLabelHelp.Name = "linkLabelHelp"; - this.linkLabelHelp.Size = new System.Drawing.Size(29, 13); - this.linkLabelHelp.TabIndex = 120; - this.linkLabelHelp.TabStop = true; - this.linkLabelHelp.Text = "Help"; - this.linkLabelHelp.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelHelp_LinkClicked); - // - // contextMenuStripRes - // - this.contextMenuStripRes.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.useSourceResolutionToolStripMenuItem, - this.x2160ToolStripMenuItem, - this.uHD3840x2160ToolStripMenuItem, - this.k2048x1080ToolStripMenuItem, - this.dCI2KScope2048x858ToolStripMenuItem, - this.dCI2KFlat1998x1080ToolStripMenuItem, - this.toolStripMenuItemYouTubeShort, - this.p1920x1080ToolStripMenuItem, - this.x1080ToolStripMenuItem, - this.p1280x720ToolStripMenuItem, - this.x720ToolStripMenuItem, - this.p848x480ToolStripMenuItem, - this.pAL720x576ToolStripMenuItem, - this.nTSC720x480ToolStripMenuItem, - this.x352ToolStripMenuItem, - this.x272ToolStripMenuItem}); - this.contextMenuStripRes.Name = "contextMenuStripRes"; - this.contextMenuStripRes.Size = new System.Drawing.Size(221, 356); - this.contextMenuStripRes.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuStripRes_Opening); - // - // useSourceResolutionToolStripMenuItem - // - this.useSourceResolutionToolStripMenuItem.Name = "useSourceResolutionToolStripMenuItem"; - this.useSourceResolutionToolStripMenuItem.Size = new System.Drawing.Size(220, 22); - this.useSourceResolutionToolStripMenuItem.Text = "Use source resoluton"; - this.useSourceResolutionToolStripMenuItem.Click += new System.EventHandler(this.useSourceResolutionToolStripMenuItem_Click); - // - // x2160ToolStripMenuItem - // - this.x2160ToolStripMenuItem.Name = "x2160ToolStripMenuItem"; - this.x2160ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); - this.x2160ToolStripMenuItem.Text = "4K (4096x2160)"; - this.x2160ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); - // - // uHD3840x2160ToolStripMenuItem - // - this.uHD3840x2160ToolStripMenuItem.Name = "uHD3840x2160ToolStripMenuItem"; - this.uHD3840x2160ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); - this.uHD3840x2160ToolStripMenuItem.Text = "UHD (3840x2160)"; - this.uHD3840x2160ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); - // - // k2048x1080ToolStripMenuItem - // - this.k2048x1080ToolStripMenuItem.Name = "k2048x1080ToolStripMenuItem"; - this.k2048x1080ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); - this.k2048x1080ToolStripMenuItem.Text = "2K (2048x1080)"; - this.k2048x1080ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); - // - // dCI2KScope2048x858ToolStripMenuItem - // - this.dCI2KScope2048x858ToolStripMenuItem.Name = "dCI2KScope2048x858ToolStripMenuItem"; - this.dCI2KScope2048x858ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); - this.dCI2KScope2048x858ToolStripMenuItem.Text = "DCI 2K Scope (2048x858)"; - this.dCI2KScope2048x858ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); - // - // dCI2KFlat1998x1080ToolStripMenuItem - // - this.dCI2KFlat1998x1080ToolStripMenuItem.Name = "dCI2KFlat1998x1080ToolStripMenuItem"; - this.dCI2KFlat1998x1080ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); - this.dCI2KFlat1998x1080ToolStripMenuItem.Text = "DCI 2K Flat (1998x1080)"; - this.dCI2KFlat1998x1080ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); - // - // toolStripMenuItemYouTubeShort - // - this.toolStripMenuItemYouTubeShort.Name = "toolStripMenuItemYouTubeShort"; - this.toolStripMenuItemYouTubeShort.Size = new System.Drawing.Size(220, 22); - this.toolStripMenuItemYouTubeShort.Text = "YouTube shorts (1080x1920)"; - this.toolStripMenuItemYouTubeShort.Click += new System.EventHandler(this.ResolutionPickClick); - // - // p1920x1080ToolStripMenuItem - // - this.p1920x1080ToolStripMenuItem.Name = "p1920x1080ToolStripMenuItem"; - this.p1920x1080ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); - this.p1920x1080ToolStripMenuItem.Text = "1080p (1920x1080)"; - this.p1920x1080ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); - // - // x1080ToolStripMenuItem - // - this.x1080ToolStripMenuItem.Name = "x1080ToolStripMenuItem"; - this.x1080ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); - this.x1080ToolStripMenuItem.Text = "1440x1080"; - this.x1080ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); - // - // p1280x720ToolStripMenuItem - // - this.p1280x720ToolStripMenuItem.Name = "p1280x720ToolStripMenuItem"; - this.p1280x720ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); - this.p1280x720ToolStripMenuItem.Text = "720p (1280x720)"; - this.p1280x720ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); - // - // x720ToolStripMenuItem - // - this.x720ToolStripMenuItem.Name = "x720ToolStripMenuItem"; - this.x720ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); - this.x720ToolStripMenuItem.Text = "960x720"; - this.x720ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); - // - // p848x480ToolStripMenuItem - // - this.p848x480ToolStripMenuItem.Name = "p848x480ToolStripMenuItem"; - this.p848x480ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); - this.p848x480ToolStripMenuItem.Text = "480p (848x480)"; - this.p848x480ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); - // - // pAL720x576ToolStripMenuItem - // - this.pAL720x576ToolStripMenuItem.Name = "pAL720x576ToolStripMenuItem"; - this.pAL720x576ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); - this.pAL720x576ToolStripMenuItem.Text = "PAL (720x576)"; - this.pAL720x576ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); - // - // nTSC720x480ToolStripMenuItem - // - this.nTSC720x480ToolStripMenuItem.Name = "nTSC720x480ToolStripMenuItem"; - this.nTSC720x480ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); - this.nTSC720x480ToolStripMenuItem.Text = "NTSC (720x480)"; - this.nTSC720x480ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); - // - // x352ToolStripMenuItem - // - this.x352ToolStripMenuItem.Name = "x352ToolStripMenuItem"; - this.x352ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); - this.x352ToolStripMenuItem.Text = "640x352"; - this.x352ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); - // - // x272ToolStripMenuItem - // - this.x272ToolStripMenuItem.Name = "x272ToolStripMenuItem"; - this.x272ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); - this.x272ToolStripMenuItem.Text = "640x272"; - this.x272ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); - // - // buttonMode - // - this.buttonMode.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.buttonMode.ImeMode = System.Windows.Forms.ImeMode.NoControl; - this.buttonMode.Location = new System.Drawing.Point(748, 586); - this.buttonMode.Name = "buttonMode"; - this.buttonMode.Size = new System.Drawing.Size(125, 23); - this.buttonMode.TabIndex = 143; - this.buttonMode.Text = "Batch mode"; - this.buttonMode.UseVisualStyleBackColor = true; - this.buttonMode.Click += new System.EventHandler(this.buttonMode_Click); - // // numericUpDownCutToSeconds // this.numericUpDownCutToSeconds.BackColor = System.Drawing.SystemColors.Window; @@ -1031,6 +599,17 @@ namespace Nikse.SubtitleEdit.Forms this.labelCutFrom.TabIndex = 14; this.labelCutFrom.Text = "From"; // + // checkBoxCut + // + this.checkBoxCut.AutoSize = true; + this.checkBoxCut.Location = new System.Drawing.Point(12, 36); + this.checkBoxCut.Name = "checkBoxCut"; + this.checkBoxCut.Size = new System.Drawing.Size(42, 17); + this.checkBoxCut.TabIndex = 0; + this.checkBoxCut.Text = "Cut"; + this.checkBoxCut.UseVisualStyleBackColor = true; + this.checkBoxCut.CheckedChanged += new System.EventHandler(this.checkBoxCut_CheckedChanged); + // // labelVideoBitrate // this.labelVideoBitrate.AutoSize = true; @@ -1040,6 +619,28 @@ namespace Nikse.SubtitleEdit.Forms this.labelVideoBitrate.TabIndex = 14; this.labelVideoBitrate.Text = "labelVideoBitrate"; // + // checkBoxBox + // + this.checkBoxBox.AutoSize = true; + this.checkBoxBox.Location = new System.Drawing.Point(226, 27); + this.checkBoxBox.Name = "checkBoxBox"; + this.checkBoxBox.Size = new System.Drawing.Size(44, 17); + this.checkBoxBox.TabIndex = 2; + this.checkBoxBox.Text = "Box"; + this.checkBoxBox.UseVisualStyleBackColor = true; + this.checkBoxBox.CheckedChanged += new System.EventHandler(this.checkBoxBox_CheckedChanged); + // + // checkBoxAlignRight + // + this.checkBoxAlignRight.AutoSize = true; + this.checkBoxAlignRight.Location = new System.Drawing.Point(217, 114); + this.checkBoxAlignRight.Name = "checkBoxAlignRight"; + this.checkBoxAlignRight.Size = new System.Drawing.Size(72, 17); + this.checkBoxAlignRight.TabIndex = 10; + this.checkBoxAlignRight.Text = "Align right"; + this.checkBoxAlignRight.UseVisualStyleBackColor = true; + this.checkBoxAlignRight.CheckedChanged += new System.EventHandler(this.checkBoxAlignRight_CheckedChanged); + // // labelInfo // this.labelInfo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); @@ -1050,6 +651,17 @@ namespace Nikse.SubtitleEdit.Forms this.labelInfo.TabIndex = 1; this.labelInfo.Text = "Info"; // + // checkBoxRightToLeft + // + this.checkBoxRightToLeft.AutoSize = true; + this.checkBoxRightToLeft.Location = new System.Drawing.Point(120, 114); + this.checkBoxRightToLeft.Name = "checkBoxRightToLeft"; + this.checkBoxRightToLeft.Size = new System.Drawing.Size(80, 17); + this.checkBoxRightToLeft.TabIndex = 9; + this.checkBoxRightToLeft.Text = "Right to left"; + this.checkBoxRightToLeft.UseVisualStyleBackColor = true; + this.checkBoxRightToLeft.CheckedChanged += new System.EventHandler(this.checkBoxRightToLeft_CheckedChanged); + // // comboBoxSubtitleFont // this.comboBoxSubtitleFont.BackColor = System.Drawing.SystemColors.Window; @@ -1083,6 +695,29 @@ namespace Nikse.SubtitleEdit.Forms this.labelSubtitleFont.TabIndex = 7; this.labelSubtitleFont.Text = "Subtitle font"; // + // groupBoxVideo + // + this.groupBoxVideo.Controls.Add(this.labelCrfHint); + this.groupBoxVideo.Controls.Add(this.buttonVideoChooseStandardRes); + this.groupBoxVideo.Controls.Add(this.labelResolution); + this.groupBoxVideo.Controls.Add(this.numericUpDownWidth); + this.groupBoxVideo.Controls.Add(this.numericUpDownHeight); + this.groupBoxVideo.Controls.Add(this.labelX); + this.groupBoxVideo.Controls.Add(this.labelPreset); + this.groupBoxVideo.Controls.Add(this.comboBoxTune); + this.groupBoxVideo.Controls.Add(this.comboBoxPreset); + this.groupBoxVideo.Controls.Add(this.labelTune); + this.groupBoxVideo.Controls.Add(this.labelCRF); + this.groupBoxVideo.Controls.Add(this.comboBoxVideoEncoding); + this.groupBoxVideo.Controls.Add(this.comboBoxCrf); + this.groupBoxVideo.Controls.Add(this.labelVideoEncoding); + this.groupBoxVideo.Location = new System.Drawing.Point(6, 141); + this.groupBoxVideo.Name = "groupBoxVideo"; + this.groupBoxVideo.Size = new System.Drawing.Size(406, 166); + this.groupBoxVideo.TabIndex = 70; + this.groupBoxVideo.TabStop = false; + this.groupBoxVideo.Text = "Video"; + // // labelCrfHint // this.labelCrfHint.AutoSize = true; @@ -1094,6 +729,18 @@ namespace Nikse.SubtitleEdit.Forms this.labelCrfHint.TabIndex = 32; this.labelCrfHint.Text = "Hint"; // + // buttonVideoChooseStandardRes + // + this.buttonVideoChooseStandardRes.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.buttonVideoChooseStandardRes.Location = new System.Drawing.Point(257, 15); + this.buttonVideoChooseStandardRes.Name = "buttonVideoChooseStandardRes"; + this.buttonVideoChooseStandardRes.Size = new System.Drawing.Size(69, 23); + this.buttonVideoChooseStandardRes.TabIndex = 3; + this.buttonVideoChooseStandardRes.Text = "..."; + this.buttonVideoChooseStandardRes.UseVisualStyleBackColor = true; + this.buttonVideoChooseStandardRes.Click += new System.EventHandler(this.buttonVideoChooseStandardRes_Click); + // // labelResolution // this.labelResolution.AutoSize = true; @@ -1210,7 +857,7 @@ namespace Nikse.SubtitleEdit.Forms this.comboBoxTune.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBoxTune.DropDownWidth = 121; this.comboBoxTune.FormattingEnabled = true; - this.comboBoxTune.Items.AddRange(new object[] { + this.comboBoxTune.Items.AddRange(new string[] { "", "film", "animation", @@ -1238,7 +885,7 @@ namespace Nikse.SubtitleEdit.Forms this.comboBoxPreset.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBoxPreset.DropDownWidth = 121; this.comboBoxPreset.FormattingEnabled = true; - this.comboBoxPreset.Items.AddRange(new object[] { + this.comboBoxPreset.Items.AddRange(new string[] { "ultrafast", "superfast", "veryfast", @@ -1289,7 +936,7 @@ namespace Nikse.SubtitleEdit.Forms this.comboBoxVideoEncoding.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBoxVideoEncoding.DropDownWidth = 121; this.comboBoxVideoEncoding.FormattingEnabled = true; - this.comboBoxVideoEncoding.Items.AddRange(new object[] { + this.comboBoxVideoEncoding.Items.AddRange(new string[] { "libx264", "libx265", "libvpx-vp9", @@ -1322,7 +969,7 @@ namespace Nikse.SubtitleEdit.Forms this.comboBoxCrf.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBoxCrf.DropDownWidth = 121; this.comboBoxCrf.FormattingEnabled = true; - this.comboBoxCrf.Items.AddRange(new object[] { + this.comboBoxCrf.Items.AddRange(new string[] { "17", "18", "19", @@ -1354,6 +1001,45 @@ namespace Nikse.SubtitleEdit.Forms this.labelVideoEncoding.TabIndex = 3; this.labelVideoEncoding.Text = "Video enc"; // + // groupBoxAudio + // + this.groupBoxAudio.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupBoxAudio.Controls.Add(this.listViewAudioTracks); + this.groupBoxAudio.Controls.Add(this.labelAudioEnc); + this.groupBoxAudio.Controls.Add(this.comboBoxAudioBitRate); + this.groupBoxAudio.Controls.Add(this.comboBoxAudioEnc); + this.groupBoxAudio.Controls.Add(this.labelAudioBitRate); + this.groupBoxAudio.Controls.Add(this.checkBoxMakeStereo); + this.groupBoxAudio.Controls.Add(this.labelAudioSampleRate); + this.groupBoxAudio.Controls.Add(this.comboBoxAudioSampleRate); + this.groupBoxAudio.Location = new System.Drawing.Point(430, 141); + this.groupBoxAudio.Name = "groupBoxAudio"; + this.groupBoxAudio.Size = new System.Drawing.Size(425, 166); + this.groupBoxAudio.TabIndex = 90; + this.groupBoxAudio.TabStop = false; + this.groupBoxAudio.Text = "Audio"; + // + // listViewAudioTracks + // + this.listViewAudioTracks.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.listViewAudioTracks.CheckBoxes = true; + this.listViewAudioTracks.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.columnHeaderAudioTrack}); + this.listViewAudioTracks.HideSelection = false; + this.listViewAudioTracks.Location = new System.Drawing.Point(229, 29); + this.listViewAudioTracks.Name = "listViewAudioTracks"; + this.listViewAudioTracks.Size = new System.Drawing.Size(190, 122); + this.listViewAudioTracks.TabIndex = 45; + this.listViewAudioTracks.UseCompatibleStateImageBehavior = false; + this.listViewAudioTracks.View = System.Windows.Forms.View.Details; + // + // columnHeaderAudioTrack + // + this.columnHeaderAudioTrack.Text = "Audio tracks"; + this.columnHeaderAudioTrack.Width = 160; + // // labelAudioEnc // this.labelAudioEnc.AutoSize = true; @@ -1376,7 +1062,7 @@ namespace Nikse.SubtitleEdit.Forms this.comboBoxAudioBitRate.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBoxAudioBitRate.DropDownWidth = 121; this.comboBoxAudioBitRate.FormattingEnabled = true; - this.comboBoxAudioBitRate.Items.AddRange(new object[] { + this.comboBoxAudioBitRate.Items.AddRange(new string[] { "64k", "128k", "160k", @@ -1406,7 +1092,7 @@ namespace Nikse.SubtitleEdit.Forms this.comboBoxAudioEnc.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBoxAudioEnc.DropDownWidth = 121; this.comboBoxAudioEnc.FormattingEnabled = true; - this.comboBoxAudioEnc.Items.AddRange(new object[] { + this.comboBoxAudioEnc.Items.AddRange(new string[] { "copy", "aac"}); this.comboBoxAudioEnc.Location = new System.Drawing.Point(91, 29); @@ -1429,6 +1115,18 @@ namespace Nikse.SubtitleEdit.Forms this.labelAudioBitRate.TabIndex = 4; this.labelAudioBitRate.Text = "Bit rate"; // + // checkBoxMakeStereo + // + this.checkBoxMakeStereo.AutoSize = true; + this.checkBoxMakeStereo.Checked = true; + this.checkBoxMakeStereo.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBoxMakeStereo.Location = new System.Drawing.Point(91, 58); + this.checkBoxMakeStereo.Name = "checkBoxMakeStereo"; + this.checkBoxMakeStereo.Size = new System.Drawing.Size(57, 17); + this.checkBoxMakeStereo.TabIndex = 2; + this.checkBoxMakeStereo.Text = "Stereo"; + this.checkBoxMakeStereo.UseVisualStyleBackColor = true; + // // labelAudioSampleRate // this.labelAudioSampleRate.AutoSize = true; @@ -1451,7 +1149,7 @@ namespace Nikse.SubtitleEdit.Forms this.comboBoxAudioSampleRate.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBoxAudioSampleRate.DropDownWidth = 121; this.comboBoxAudioSampleRate.FormattingEnabled = true; - this.comboBoxAudioSampleRate.Items.AddRange(new object[] { + this.comboBoxAudioSampleRate.Items.AddRange(new string[] { "44100 Hz", "48000 Hz", "88200 Hz", @@ -1514,6 +1212,17 @@ namespace Nikse.SubtitleEdit.Forms this.labelFileSize.TabIndex = 12; this.labelFileSize.Text = "File size in MB"; // + // checkBoxTargetFileSize + // + this.checkBoxTargetFileSize.AutoSize = true; + this.checkBoxTargetFileSize.Location = new System.Drawing.Point(22, 327); + this.checkBoxTargetFileSize.Name = "checkBoxTargetFileSize"; + this.checkBoxTargetFileSize.Size = new System.Drawing.Size(192, 17); + this.checkBoxTargetFileSize.TabIndex = 100; + this.checkBoxTargetFileSize.Text = "Target file size (two pass encoding)"; + this.checkBoxTargetFileSize.UseVisualStyleBackColor = true; + this.checkBoxTargetFileSize.CheckedChanged += new System.EventHandler(this.checkBoxTargetFileSize_CheckedChanged); + // // labelFileName // this.labelFileName.AutoSize = true; @@ -1570,6 +1279,116 @@ namespace Nikse.SubtitleEdit.Forms this.labelFontSize.TabIndex = 0; this.labelFontSize.Text = "Font size"; // + // listViewBatch + // + this.listViewBatch.AllowDrop = true; + this.listViewBatch.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.listViewBatch.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.columnHeaderVideoFile, + this.columnHeaderResolution, + this.columnHeaderSize, + this.columnHeaderSubtitleFile, + this.columnHeaderStatus}); + this.listViewBatch.ContextMenuStrip = this.contextMenuStripBatch; + this.listViewBatch.FullRowSelect = true; + this.listViewBatch.HideSelection = false; + this.listViewBatch.Location = new System.Drawing.Point(6, 316); + this.listViewBatch.Name = "listViewBatch"; + this.listViewBatch.Size = new System.Drawing.Size(852, 191); + this.listViewBatch.TabIndex = 3; + this.listViewBatch.UseCompatibleStateImageBehavior = false; + this.listViewBatch.View = System.Windows.Forms.View.Details; + this.listViewBatch.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.listViewBatch_ColumnClick); + this.listViewBatch.DragDrop += new System.Windows.Forms.DragEventHandler(this.listViewBatch_DragDrop); + this.listViewBatch.DragEnter += new System.Windows.Forms.DragEventHandler(this.listViewBatch_DragEnter); + this.listViewBatch.KeyDown += new System.Windows.Forms.KeyEventHandler(this.listViewBatch_KeyDown); + // + // columnHeaderVideoFile + // + this.columnHeaderVideoFile.Text = "Video file"; + this.columnHeaderVideoFile.Width = 420; + // + // columnHeaderResolution + // + this.columnHeaderResolution.Text = "Resolution"; + this.columnHeaderResolution.Width = 80; + // + // columnHeaderSize + // + this.columnHeaderSize.Text = "Size"; + this.columnHeaderSize.Width = 80; + // + // columnHeaderSubtitleFile + // + this.columnHeaderSubtitleFile.Text = "Subtitle file"; + this.columnHeaderSubtitleFile.Width = 180; + // + // columnHeaderStatus + // + this.columnHeaderStatus.Text = "Status"; + this.columnHeaderStatus.Width = 80; + // + // contextMenuStripBatch + // + this.contextMenuStripBatch.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.addFilesToolStripMenuItem, + this.toolStripSeparator2, + this.pickSubtitleFileToolStripMenuItem, + this.removeSubtitleFileToolStripMenuItem, + this.toolStripSeparator1, + this.deleteToolStripMenuItem, + this.clearToolStripMenuItem}); + this.contextMenuStripBatch.Name = "contextMenuStripBatch"; + this.contextMenuStripBatch.Size = new System.Drawing.Size(179, 126); + this.contextMenuStripBatch.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuStripBatch_Opening); + // + // addFilesToolStripMenuItem + // + this.addFilesToolStripMenuItem.Name = "addFilesToolStripMenuItem"; + this.addFilesToolStripMenuItem.Size = new System.Drawing.Size(178, 22); + this.addFilesToolStripMenuItem.Text = "Add video files..."; + this.addFilesToolStripMenuItem.Click += new System.EventHandler(this.addFilesToolStripMenuItem_Click); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(175, 6); + // + // pickSubtitleFileToolStripMenuItem + // + this.pickSubtitleFileToolStripMenuItem.Name = "pickSubtitleFileToolStripMenuItem"; + this.pickSubtitleFileToolStripMenuItem.Size = new System.Drawing.Size(178, 22); + this.pickSubtitleFileToolStripMenuItem.Text = "Pick subtitle file..."; + this.pickSubtitleFileToolStripMenuItem.Click += new System.EventHandler(this.pickSubtitleFileToolStripMenuItem_Click); + // + // removeSubtitleFileToolStripMenuItem + // + this.removeSubtitleFileToolStripMenuItem.Name = "removeSubtitleFileToolStripMenuItem"; + this.removeSubtitleFileToolStripMenuItem.Size = new System.Drawing.Size(178, 22); + this.removeSubtitleFileToolStripMenuItem.Text = "Remove subtitle file"; + this.removeSubtitleFileToolStripMenuItem.Click += new System.EventHandler(this.removeSubtitleFileToolStripMenuItem_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(175, 6); + // + // deleteToolStripMenuItem + // + this.deleteToolStripMenuItem.Name = "deleteToolStripMenuItem"; + this.deleteToolStripMenuItem.Size = new System.Drawing.Size(178, 22); + this.deleteToolStripMenuItem.Text = "Delete"; + this.deleteToolStripMenuItem.Click += new System.EventHandler(this.deleteToolStripMenuItem_Click); + // + // clearToolStripMenuItem + // + this.clearToolStripMenuItem.Name = "clearToolStripMenuItem"; + this.clearToolStripMenuItem.Size = new System.Drawing.Size(178, 22); + this.clearToolStripMenuItem.Text = "Clear"; + this.clearToolStripMenuItem.Click += new System.EventHandler(this.clearToolStripMenuItem_Click); + // // videoPlayerContainer1 // this.videoPlayerContainer1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) @@ -1595,6 +1414,187 @@ namespace Nikse.SubtitleEdit.Forms this.videoPlayerContainer1.VideoWidth = 0; this.videoPlayerContainer1.Volume = 0D; // + // buttonOutputFileSettings + // + this.buttonOutputFileSettings.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.buttonOutputFileSettings.Location = new System.Drawing.Point(255, 513); + this.buttonOutputFileSettings.Name = "buttonOutputFileSettings"; + this.buttonOutputFileSettings.Size = new System.Drawing.Size(167, 23); + this.buttonOutputFileSettings.TabIndex = 148; + this.buttonOutputFileSettings.Text = "Output file/folder..."; + this.buttonOutputFileSettings.UseVisualStyleBackColor = true; + this.buttonOutputFileSettings.Click += new System.EventHandler(this.buttonOutputFileSettings_Click); + // + // buttonPreview + // + this.buttonPreview.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.buttonPreview.Location = new System.Drawing.Point(621, 586); + this.buttonPreview.Name = "buttonPreview"; + this.buttonPreview.Size = new System.Drawing.Size(121, 23); + this.buttonPreview.TabIndex = 130; + this.buttonPreview.Text = "Preview"; + this.buttonPreview.UseVisualStyleBackColor = true; + this.buttonPreview.Click += new System.EventHandler(this.buttonPreview_Click); + // + // linkLabelHelp + // + this.linkLabelHelp.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.linkLabelHelp.AutoSize = true; + this.linkLabelHelp.Location = new System.Drawing.Point(844, 563); + this.linkLabelHelp.Name = "linkLabelHelp"; + this.linkLabelHelp.Size = new System.Drawing.Size(29, 13); + this.linkLabelHelp.TabIndex = 120; + this.linkLabelHelp.TabStop = true; + this.linkLabelHelp.Text = "Help"; + this.linkLabelHelp.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelHelp_LinkClicked); + // + // contextMenuStripRes + // + this.contextMenuStripRes.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.useSourceResolutionToolStripMenuItem, + this.x2160ToolStripMenuItem, + this.uHD3840x2160ToolStripMenuItem, + this.k2048x1080ToolStripMenuItem, + this.dCI2KScope2048x858ToolStripMenuItem, + this.dCI2KFlat1998x1080ToolStripMenuItem, + this.toolStripMenuItemYouTubeShort, + this.p1920x1080ToolStripMenuItem, + this.x1080ToolStripMenuItem, + this.p1280x720ToolStripMenuItem, + this.x720ToolStripMenuItem, + this.p848x480ToolStripMenuItem, + this.pAL720x576ToolStripMenuItem, + this.nTSC720x480ToolStripMenuItem, + this.x352ToolStripMenuItem, + this.x272ToolStripMenuItem}); + this.contextMenuStripRes.Name = "contextMenuStripRes"; + this.contextMenuStripRes.Size = new System.Drawing.Size(221, 356); + this.contextMenuStripRes.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuStripRes_Opening); + // + // useSourceResolutionToolStripMenuItem + // + this.useSourceResolutionToolStripMenuItem.Name = "useSourceResolutionToolStripMenuItem"; + this.useSourceResolutionToolStripMenuItem.Size = new System.Drawing.Size(220, 22); + this.useSourceResolutionToolStripMenuItem.Text = "Use source resoluton"; + this.useSourceResolutionToolStripMenuItem.Click += new System.EventHandler(this.useSourceResolutionToolStripMenuItem_Click); + // + // x2160ToolStripMenuItem + // + this.x2160ToolStripMenuItem.Name = "x2160ToolStripMenuItem"; + this.x2160ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); + this.x2160ToolStripMenuItem.Text = "4K (4096x2160)"; + this.x2160ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); + // + // uHD3840x2160ToolStripMenuItem + // + this.uHD3840x2160ToolStripMenuItem.Name = "uHD3840x2160ToolStripMenuItem"; + this.uHD3840x2160ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); + this.uHD3840x2160ToolStripMenuItem.Text = "UHD (3840x2160)"; + this.uHD3840x2160ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); + // + // k2048x1080ToolStripMenuItem + // + this.k2048x1080ToolStripMenuItem.Name = "k2048x1080ToolStripMenuItem"; + this.k2048x1080ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); + this.k2048x1080ToolStripMenuItem.Text = "2K (2048x1080)"; + this.k2048x1080ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); + // + // dCI2KScope2048x858ToolStripMenuItem + // + this.dCI2KScope2048x858ToolStripMenuItem.Name = "dCI2KScope2048x858ToolStripMenuItem"; + this.dCI2KScope2048x858ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); + this.dCI2KScope2048x858ToolStripMenuItem.Text = "DCI 2K Scope (2048x858)"; + this.dCI2KScope2048x858ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); + // + // dCI2KFlat1998x1080ToolStripMenuItem + // + this.dCI2KFlat1998x1080ToolStripMenuItem.Name = "dCI2KFlat1998x1080ToolStripMenuItem"; + this.dCI2KFlat1998x1080ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); + this.dCI2KFlat1998x1080ToolStripMenuItem.Text = "DCI 2K Flat (1998x1080)"; + this.dCI2KFlat1998x1080ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); + // + // toolStripMenuItemYouTubeShort + // + this.toolStripMenuItemYouTubeShort.Name = "toolStripMenuItemYouTubeShort"; + this.toolStripMenuItemYouTubeShort.Size = new System.Drawing.Size(220, 22); + this.toolStripMenuItemYouTubeShort.Text = "YouTube shorts (1080x1920)"; + this.toolStripMenuItemYouTubeShort.Click += new System.EventHandler(this.ResolutionPickClick); + // + // p1920x1080ToolStripMenuItem + // + this.p1920x1080ToolStripMenuItem.Name = "p1920x1080ToolStripMenuItem"; + this.p1920x1080ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); + this.p1920x1080ToolStripMenuItem.Text = "1080p (1920x1080)"; + this.p1920x1080ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); + // + // x1080ToolStripMenuItem + // + this.x1080ToolStripMenuItem.Name = "x1080ToolStripMenuItem"; + this.x1080ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); + this.x1080ToolStripMenuItem.Text = "1440x1080"; + this.x1080ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); + // + // p1280x720ToolStripMenuItem + // + this.p1280x720ToolStripMenuItem.Name = "p1280x720ToolStripMenuItem"; + this.p1280x720ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); + this.p1280x720ToolStripMenuItem.Text = "720p (1280x720)"; + this.p1280x720ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); + // + // x720ToolStripMenuItem + // + this.x720ToolStripMenuItem.Name = "x720ToolStripMenuItem"; + this.x720ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); + this.x720ToolStripMenuItem.Text = "960x720"; + this.x720ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); + // + // p848x480ToolStripMenuItem + // + this.p848x480ToolStripMenuItem.Name = "p848x480ToolStripMenuItem"; + this.p848x480ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); + this.p848x480ToolStripMenuItem.Text = "480p (848x480)"; + this.p848x480ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); + // + // pAL720x576ToolStripMenuItem + // + this.pAL720x576ToolStripMenuItem.Name = "pAL720x576ToolStripMenuItem"; + this.pAL720x576ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); + this.pAL720x576ToolStripMenuItem.Text = "PAL (720x576)"; + this.pAL720x576ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); + // + // nTSC720x480ToolStripMenuItem + // + this.nTSC720x480ToolStripMenuItem.Name = "nTSC720x480ToolStripMenuItem"; + this.nTSC720x480ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); + this.nTSC720x480ToolStripMenuItem.Text = "NTSC (720x480)"; + this.nTSC720x480ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); + // + // x352ToolStripMenuItem + // + this.x352ToolStripMenuItem.Name = "x352ToolStripMenuItem"; + this.x352ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); + this.x352ToolStripMenuItem.Text = "640x352"; + this.x352ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); + // + // x272ToolStripMenuItem + // + this.x272ToolStripMenuItem.Name = "x272ToolStripMenuItem"; + this.x272ToolStripMenuItem.Size = new System.Drawing.Size(220, 22); + this.x272ToolStripMenuItem.Text = "640x272"; + this.x272ToolStripMenuItem.Click += new System.EventHandler(this.ResolutionPickClick); + // + // buttonMode + // + this.buttonMode.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.buttonMode.ImeMode = System.Windows.Forms.ImeMode.NoControl; + this.buttonMode.Location = new System.Drawing.Point(748, 586); + this.buttonMode.Name = "buttonMode"; + this.buttonMode.Size = new System.Drawing.Size(125, 23); + this.buttonMode.TabIndex = 143; + this.buttonMode.Text = "Batch mode"; + this.buttonMode.UseVisualStyleBackColor = true; + this.buttonMode.Click += new System.EventHandler(this.buttonMode_Click); + // // labelPreviewPleaseWait // this.labelPreviewPleaseWait.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); diff --git a/src/ui/Forms/GenerateVideoWithHardSubs.cs b/src/ui/Forms/GenerateVideoWithHardSubs.cs index 9bfe80d3a..722e7ca6a 100644 --- a/src/ui/Forms/GenerateVideoWithHardSubs.cs +++ b/src/ui/Forms/GenerateVideoWithHardSubs.cs @@ -29,7 +29,7 @@ namespace Nikse.SubtitleEdit.Forms private long _totalFrames; private StringBuilder _log; private readonly bool _isAssa; - private readonly FfmpegMediaInfo _mediaInfo; + private FfmpegMediaInfo _mediaInfo; private bool _promptFFmpegParameters; private readonly bool _mpvOn; private readonly string _mpvSubtitleFileName; @@ -42,6 +42,7 @@ namespace Nikse.SubtitleEdit.Forms public bool BatchMode { get; set; } public string BatchInfo { get; set; } private readonly List _batchVideoAndSubList; + private const int ListViewBatchSubItemIndexColumnVideoSize = 2; private const int ListViewBatchSubItemIndexColumnSubtitleFile = 3; private const int ListViewBatchSubItemIndexColumnStatus = 4; @@ -248,7 +249,6 @@ namespace Nikse.SubtitleEdit.Forms UiUtil.FixLargeFonts(this, buttonGenerate); UiUtil.FixFonts(this, 2000); - _mediaInfo = FfmpegMediaInfo.Parse(inputVideoFileName); if (_videoInfo != null && _videoInfo.TotalSeconds > 0) @@ -459,6 +459,8 @@ namespace Nikse.SubtitleEdit.Forms labelPleaseWait.Text = $"{index + 1}/{_batchVideoAndSubList.Count} - {LanguageSettings.Current.General.PleaseWait}"; var videoAndSub = _batchVideoAndSubList[index]; + + _mediaInfo = FfmpegMediaInfo.Parse(videoAndSub.VideoFileName); _videoInfo = UiUtil.GetVideoInfo(videoAndSub.VideoFileName); if (useSourceResolution) { @@ -977,12 +979,18 @@ namespace Nikse.SubtitleEdit.Forms if (_abort) { process.Kill(); + return false; } var v = (int)_processedFrames; SetProgress(v); } + if (_abort) + { + return false; + } + if (process.ExitCode != 0) { _log.AppendLine("ffmpeg exit code: " + process.ExitCode); @@ -2108,9 +2116,25 @@ namespace Nikse.SubtitleEdit.Forms return; } - foreach (var fileName in openFileDialog1.FileNames) + try { - AddInputFile(fileName); + Cursor = Cursors.WaitCursor; + Refresh(); + Application.DoEvents(); + for (var i = 0; i < listViewBatch.Columns.Count; i++) + { + ListViewSorter.SetSortArrow(listViewBatch.Columns[i], SortOrder.None); + } + + foreach (var fileName in openFileDialog1.FileNames) + { + Application.DoEvents(); + AddInputFile(fileName); + } + } + finally + { + Cursor = Cursors.Default; } } } @@ -2162,25 +2186,44 @@ namespace Nikse.SubtitleEdit.Forms item.SubtitleFileFileSizeInBytes = new FileInfo(subFileName).Length; } - - var vInfo = new VideoInfo { Success = false }; - if (fileName.EndsWith(".mp4", StringComparison.OrdinalIgnoreCase)) + var mediaInfo = FfmpegMediaInfo.Parse(fileName); + int width; + int height; + if (mediaInfo.VideoWidth > 0 && mediaInfo.VideoHeight > 0) { - vInfo = QuartsPlayer.GetVideoInfo(fileName); + width = mediaInfo.VideoWidth; + height = mediaInfo.VideoHeight; + } + else + { + var vInfo = new VideoInfo { Success = false }; + if (fileName.EndsWith(".mp4", StringComparison.OrdinalIgnoreCase)) + { + vInfo = QuartsPlayer.GetVideoInfo(fileName); + if (!vInfo.Success) + { + vInfo = LibMpvDynamic.GetVideoInfo(fileName); + } + } + if (!vInfo.Success) { - vInfo = LibMpvDynamic.GetVideoInfo(fileName); + vInfo = UiUtil.GetVideoInfo(fileName); } + + width = vInfo.Width; + height = vInfo.Height; } - if (!vInfo.Success) + if (width == 0 || height == 0) { - vInfo = UiUtil.GetVideoInfo(fileName); + SeLogger.Error("Skipping burn-in file with no video: " + fileName); + return; // skip audio or damaged files } var listViewItem = new ListViewItem(fileName); listViewItem.Tag = item; - listViewItem.SubItems.Add($"{vInfo.Width}x{vInfo.Height}"); + listViewItem.SubItems.Add($"{width}x{height}"); var s = Utilities.FormatBytesToDisplayFileSize(item.VideoFileSizeInBytes); listViewItem.SubItems.Add(s); listViewItem.SubItems.Add(Path.GetFileName(item.SubtitleFileName)); @@ -2262,13 +2305,14 @@ namespace Nikse.SubtitleEdit.Forms return; } - try - { - var fileNames = (string[])e.Data.GetData(DataFormats.FileDrop); - labelPleaseWait.Visible = true; + var fileNames = (string[])e.Data.GetData(DataFormats.FileDrop); + labelPleaseWait.Visible = true; - TaskDelayHelper.RunDelayed(TimeSpan.FromMilliseconds(5), () => + TaskDelayHelper.RunDelayed(TimeSpan.FromMilliseconds(5), () => + { + try { + Cursor = Cursors.WaitCursor; foreach (var fileName in fileNames) { if (FileUtil.IsDirectory(fileName)) @@ -2277,15 +2321,17 @@ namespace Nikse.SubtitleEdit.Forms } else { + Application.DoEvents(); AddInputFile(fileName); } } - }); - } - finally - { - labelPleaseWait.Visible = false; - } + } + finally + { + Cursor = Cursors.Default; + labelPleaseWait.Visible = false; + } + }); } private void SearchFolder(string path) @@ -2376,9 +2422,49 @@ namespace Nikse.SubtitleEdit.Forms useSourceResolutionToolStripMenuItem.Visible = BatchMode; } - private void nikseLabelOutputFileFolder_Click(object sender, EventArgs e) + private void listViewBatch_ColumnClick(object sender, ColumnClickEventArgs e) { + if (_converting || listViewBatch.Items.Count == 0) + { + return; + } + for (var i = 0; i < listViewBatch.Columns.Count; i++) + { + ListViewSorter.SetSortArrow(listViewBatch.Columns[i], SortOrder.None); + } + + var lv = (ListView)sender; + if (!(lv.ListViewItemSorter is ListViewSorter sorter)) + { + sorter = new ListViewSorter + { + ColumnNumber = e.Column, + IsDisplayFileSize = e.Column == ListViewBatchSubItemIndexColumnVideoSize, + }; + lv.ListViewItemSorter = sorter; + } + + if (e.Column == sorter.ColumnNumber) + { + sorter.Descending = !sorter.Descending; // inverse sort direction + } + else + { + sorter.ColumnNumber = e.Column; + sorter.Descending = false; + sorter.IsDisplayFileSize = e.Column == ListViewBatchSubItemIndexColumnVideoSize; + } + + lv.Sort(); + + ListViewSorter.SetSortArrow(listViewBatch.Columns[e.Column], sorter.Descending ? SortOrder.Descending : SortOrder.Ascending); + + _batchVideoAndSubList.Clear(); + foreach (ListViewItem item in listViewBatch.Items) + { + _batchVideoAndSubList.Add((BatchVideoAndSub)item.Tag); + } } } } diff --git a/src/ui/Forms/JoinSubtitles.Designer.cs b/src/ui/Forms/JoinSubtitles.Designer.cs index 69208c17e..b04b216ac 100644 --- a/src/ui/Forms/JoinSubtitles.Designer.cs +++ b/src/ui/Forms/JoinSubtitles.Designer.cs @@ -28,6 +28,7 @@ /// private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); this.buttonCancel = new System.Windows.Forms.Button(); this.buttonJoin = new System.Windows.Forms.Button(); this.listViewParts = new System.Windows.Forms.ListView(); @@ -45,7 +46,13 @@ this.numericUpDownAddMs = new Nikse.SubtitleEdit.Controls.NikseUpDown(); this.radioButtonJoinAddTime = new System.Windows.Forms.RadioButton(); this.labelAddTime = new Nikse.SubtitleEdit.Controls.NikseLabel(); + this.contextMenuStripParts = new System.Windows.Forms.ContextMenuStrip(this.components); + this.moveUpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.moveDownToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.moveTopToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.moveBottomToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.groupBoxPreview.SuspendLayout(); + this.contextMenuStripParts.SuspendLayout(); this.SuspendLayout(); // // buttonCancel @@ -83,6 +90,7 @@ this.columnHeaderStartTime, this.columnHeaderEndTime, this.columnHeaderFileName}); + this.listViewParts.ContextMenuStrip = this.contextMenuStripParts; this.listViewParts.FullRowSelect = true; this.listViewParts.HideSelection = false; this.listViewParts.Location = new System.Drawing.Point(6, 19); @@ -91,6 +99,7 @@ this.listViewParts.TabIndex = 101; this.listViewParts.UseCompatibleStateImageBehavior = false; this.listViewParts.View = System.Windows.Forms.View.Details; + this.listViewParts.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.listViewParts_ColumnClick); this.listViewParts.DragDrop += new System.Windows.Forms.DragEventHandler(this.listViewParts_DragDrop); this.listViewParts.DragEnter += new System.Windows.Forms.DragEventHandler(this.listViewParts_DragEnter); // @@ -252,6 +261,49 @@ this.labelAddTime.TabIndex = 34; this.labelAddTime.Text = "Add milliseconds after each file"; // + // contextMenuStripParts + // + this.contextMenuStripParts.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.moveUpToolStripMenuItem, + this.moveDownToolStripMenuItem, + this.moveTopToolStripMenuItem, + this.moveBottomToolStripMenuItem}); + this.contextMenuStripParts.Name = "contextMenuStrip1"; + this.contextMenuStripParts.Size = new System.Drawing.Size(216, 92); + this.contextMenuStripParts.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuStripParts_Opening); + // + // moveUpToolStripMenuItem + // + this.moveUpToolStripMenuItem.Name = "moveUpToolStripMenuItem"; + this.moveUpToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Up))); + this.moveUpToolStripMenuItem.Size = new System.Drawing.Size(215, 22); + this.moveUpToolStripMenuItem.Text = "Move up"; + this.moveUpToolStripMenuItem.Click += new System.EventHandler(this.moveUpToolStripMenuItem_Click); + // + // moveDownToolStripMenuItem + // + this.moveDownToolStripMenuItem.Name = "moveDownToolStripMenuItem"; + this.moveDownToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Down))); + this.moveDownToolStripMenuItem.Size = new System.Drawing.Size(215, 22); + this.moveDownToolStripMenuItem.Text = "Move down"; + this.moveDownToolStripMenuItem.Click += new System.EventHandler(this.moveDownToolStripMenuItem_Click); + // + // moveTopToolStripMenuItem + // + this.moveTopToolStripMenuItem.Name = "moveTopToolStripMenuItem"; + this.moveTopToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Home))); + this.moveTopToolStripMenuItem.Size = new System.Drawing.Size(215, 22); + this.moveTopToolStripMenuItem.Text = "Move to top"; + this.moveTopToolStripMenuItem.Click += new System.EventHandler(this.moveTopToolStripMenuItem_Click); + // + // moveBottomToolStripMenuItem + // + this.moveBottomToolStripMenuItem.Name = "moveBottomToolStripMenuItem"; + this.moveBottomToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.End))); + this.moveBottomToolStripMenuItem.Size = new System.Drawing.Size(215, 22); + this.moveBottomToolStripMenuItem.Text = "Move to bottom"; + this.moveBottomToolStripMenuItem.Click += new System.EventHandler(this.moveBottomToolStripMenuItem_Click); + // // JoinSubtitles // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -279,6 +331,7 @@ this.Resize += new System.EventHandler(this.JoinSubtitles_Resize); this.groupBoxPreview.ResumeLayout(false); this.groupBoxPreview.PerformLayout(); + this.contextMenuStripParts.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -303,5 +356,10 @@ private Nikse.SubtitleEdit.Controls.NikseUpDown numericUpDownAddMs; private System.Windows.Forms.RadioButton radioButtonJoinAddTime; private Nikse.SubtitleEdit.Controls.NikseLabel labelAddTime; + private System.Windows.Forms.ContextMenuStrip contextMenuStripParts; + private System.Windows.Forms.ToolStripMenuItem moveUpToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem moveDownToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem moveTopToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem moveBottomToolStripMenuItem; } } \ No newline at end of file diff --git a/src/ui/Forms/JoinSubtitles.cs b/src/ui/Forms/JoinSubtitles.cs index 823bf5d55..7668c57ef 100644 --- a/src/ui/Forms/JoinSubtitles.cs +++ b/src/ui/Forms/JoinSubtitles.cs @@ -7,6 +7,7 @@ using System.IO; using System.Linq; using System.Text; using System.Windows.Forms; +using Nikse.SubtitleEdit.Core.Enums; using MessageBox = Nikse.SubtitleEdit.Forms.SeMsgBox.MessageBox; namespace Nikse.SubtitleEdit.Forms @@ -30,6 +31,11 @@ namespace Nikse.SubtitleEdit.Forms listViewParts.Columns[2].Text = LanguageSettings.Current.JoinSubtitles.EndTime; listViewParts.Columns[3].Text = LanguageSettings.Current.JoinSubtitles.FileName; + moveUpToolStripMenuItem.Text = LanguageSettings.Current.DvdSubRip.MoveUp; + moveDownToolStripMenuItem.Text = LanguageSettings.Current.DvdSubRip.MoveDown; + moveTopToolStripMenuItem.Text = LanguageSettings.Current.MultipleReplace.MoveToTop; + moveBottomToolStripMenuItem.Text = LanguageSettings.Current.MultipleReplace.MoveToBottom; + buttonAddFile.Text = LanguageSettings.Current.DvdSubRip.Add; buttonRemoveFile.Text = LanguageSettings.Current.DvdSubRip.Remove; buttonClear.Text = LanguageSettings.Current.DvdSubRip.Clear; @@ -88,14 +94,21 @@ namespace Nikse.SubtitleEdit.Forms private void listViewParts_DragDrop(object sender, DragEventArgs e) { var files = (string[])e.Data.GetData(DataFormats.FileDrop); - foreach (string fileName in files) + + TaskDelayHelper.RunDelayed(TimeSpan.FromMilliseconds(1), () => { - if (!_fileNamesToJoin.Any(file => file.Equals(fileName, StringComparison.OrdinalIgnoreCase))) + var fileNames = files.ToList(); + fileNames.Sort(ListViewSorter.NaturalComparer); + foreach (var fileName in fileNames) { - _fileNamesToJoin.Add(fileName); + if (!_fileNamesToJoin.Any(file => file.Equals(fileName, StringComparison.OrdinalIgnoreCase))) + { + _fileNamesToJoin.Add(fileName); + } } - } - SortAndLoad(); + + SortAndLoad(); + }); } private void SortAndLoad() @@ -260,21 +273,16 @@ namespace Nikse.SubtitleEdit.Forms if (!radioButtonJoinAddTime.Checked) { - for (int outer = 0; outer < subtitles.Count; outer++) + for (var outer = 0; outer < subtitles.Count; outer++) { - for (int inner = 1; inner < subtitles.Count; inner++) + for (var inner = 1; inner < subtitles.Count; inner++) { var a = subtitles[inner - 1]; var b = subtitles[inner]; if (a.Paragraphs.Count > 0 && b.Paragraphs.Count > 0 && a.Paragraphs[0].StartTime.TotalMilliseconds > b.Paragraphs[0].StartTime.TotalMilliseconds) { - var t1 = _fileNamesToJoin[inner - 1]; - _fileNamesToJoin[inner - 1] = _fileNamesToJoin[inner]; - _fileNamesToJoin[inner] = t1; - - var t2 = subtitles[inner - 1]; - subtitles[inner - 1] = subtitles[inner]; - subtitles[inner] = t2; + (_fileNamesToJoin[inner - 1], _fileNamesToJoin[inner]) = (_fileNamesToJoin[inner], _fileNamesToJoin[inner - 1]); + (subtitles[inner - 1], subtitles[inner]) = (subtitles[inner], subtitles[inner - 1]); } } } @@ -287,6 +295,7 @@ namespace Nikse.SubtitleEdit.Forms { var sub = subtitles[i]; var lvi = new ListViewItem($"{sub.Paragraphs.Count:#,###,###}"); + lvi.Tag = fileName; if (sub.Paragraphs.Count > 0) { lvi.SubItems.Add(sub.Paragraphs[0].StartTime.ToString()); @@ -325,6 +334,11 @@ namespace Nikse.SubtitleEdit.Forms } } + if (radioButtonJoinPlain.Checked) + { + JoinedSubtitle.Sort(SubtitleSortCriteria.StartTime); + } + JoinedSubtitle.Renumber(); labelTotalLines.Text = string.Format(LanguageSettings.Current.JoinSubtitles.TotalNumberOfLinesX, JoinedSubtitle.Paragraphs.Count); } @@ -364,7 +378,9 @@ namespace Nikse.SubtitleEdit.Forms if (openFileDialog1.ShowDialog(this) == DialogResult.OK) { var sb = new StringBuilder(); - foreach (string fileName in openFileDialog1.FileNames) + var fileNames = openFileDialog1.FileNames.ToList(); + fileNames.Sort(ListViewSorter.NaturalComparer); + foreach (var fileName in fileNames) { Application.DoEvents(); if (File.Exists(fileName)) @@ -383,11 +399,13 @@ namespace Nikse.SubtitleEdit.Forms } } } + SortAndLoad(); if (sb.Length > 0) { MessageBox.Show(sb.ToString()); } + JoinSubtitles_Resize(sender, e); } } @@ -437,6 +455,218 @@ namespace Nikse.SubtitleEdit.Forms numericUpDownAddMs.Enabled = radioButtonJoinAddTime.Checked; labelAddTime.Enabled = radioButtonJoinAddTime.Checked; SortAndLoad(); + ListViewSorter.SetSortArrow(listViewParts.Columns[3], SortOrder.None); + } + + private void contextMenuStripParts_Opening(object sender, System.ComponentModel.CancelEventArgs e) + { + if (radioButtonJoinPlain.Checked) + { + e.Cancel = true; + } + } + + private void MoveUp(ListView listView) + { + if (listView.SelectedItems.Count != 1) + { + return; + } + + var idx = listView.SelectedItems[0].Index; + if (idx == 0) + { + return; + } + + var item = listView.SelectedItems[0]; + listView.Items.RemoveAt(idx); + var style = _fileNamesToJoin[idx]; + _fileNamesToJoin.RemoveAt(idx); + _fileNamesToJoin.Insert(idx - 1, style); + + idx--; + listView.Items.Insert(idx, item); + UpdateSelectedIndices(listView, idx); + } + + private void MoveDown(ListView listView) + { + if (listView.SelectedItems.Count != 1) + { + return; + } + + var idx = listView.SelectedItems[0].Index; + if (idx >= listView.Items.Count - 1) + { + return; + } + + var item = listView.SelectedItems[0]; + listView.Items.RemoveAt(idx); + var style = _fileNamesToJoin[idx]; + _fileNamesToJoin.RemoveAt(idx); + _fileNamesToJoin.Insert(idx + 1, style); + + idx++; + listView.Items.Insert(idx, item); + UpdateSelectedIndices(listView, idx); + } + + private void MoveToTop(ListView listView) + { + if (listView.SelectedItems.Count != 1) + { + return; + } + + var idx = listView.SelectedItems[0].Index; + if (idx == 0) + { + return; + } + + var item = listView.SelectedItems[0]; + listView.Items.RemoveAt(idx); + var style = _fileNamesToJoin[idx]; + _fileNamesToJoin.RemoveAt(idx); + _fileNamesToJoin.Insert(0, style); + + idx = 0; + listView.Items.Insert(idx, item); + UpdateSelectedIndices(listView, idx); + } + + private void MoveToBottom(ListView listView) + { + if (listView.SelectedItems.Count != 1) + { + return; + } + + var idx = listView.SelectedItems[0].Index; + if (idx == listView.Items.Count - 1) + { + return; + } + + var item = listView.SelectedItems[0]; + listView.Items.RemoveAt(idx); + var style = _fileNamesToJoin[idx]; + _fileNamesToJoin.RemoveAt(idx); + _fileNamesToJoin.Add(style); + + listView.Items.Add(item); + UpdateSelectedIndices(listView); + } + + private static void UpdateSelectedIndices(ListView listView, int startingIndex = -1, int numberOfSelectedItems = 1) + { + if (numberOfSelectedItems == 0) + { + return; + } + + if (startingIndex == -1 || startingIndex >= listView.Items.Count) + { + startingIndex = listView.Items.Count - 1; + } + + if (startingIndex - numberOfSelectedItems < -1) + { + return; + } + + listView.SelectedItems.Clear(); + for (var i = 0; i < numberOfSelectedItems; i++) + { + listView.Items[startingIndex - i].Selected = true; + listView.Items[startingIndex - i].EnsureVisible(); + listView.Items[startingIndex - i].Focused = true; + } + } + + private void moveUpToolStripMenuItem_Click(object sender, EventArgs e) + { + if (radioButtonJoinPlain.Checked) + { + return; + } + + ListViewSorter.SetSortArrow(listViewParts.Columns[3], SortOrder.None); + MoveUp(listViewParts); + } + + private void moveDownToolStripMenuItem_Click(object sender, EventArgs e) + { + if (radioButtonJoinPlain.Checked) + { + return; + } + + ListViewSorter.SetSortArrow(listViewParts.Columns[3], SortOrder.None); + MoveDown(listViewParts); + } + + private void moveTopToolStripMenuItem_Click(object sender, EventArgs e) + { + if (radioButtonJoinPlain.Checked) + { + return; + } + + ListViewSorter.SetSortArrow(listViewParts.Columns[3], SortOrder.None); + MoveToTop(listViewParts); + } + + private void moveBottomToolStripMenuItem_Click(object sender, EventArgs e) + { + if (radioButtonJoinPlain.Checked) + { + return; + } + + ListViewSorter.SetSortArrow(listViewParts.Columns[3], SortOrder.None); + MoveToBottom(listViewParts); + } + + private void listViewParts_ColumnClick(object sender, ColumnClickEventArgs e) + { + if (radioButtonJoinPlain.Checked || e.Column != 3) + { + return; + } + + var lv = (ListView)sender; + if (!(lv.ListViewItemSorter is ListViewSorter sorter)) + { + sorter = new ListViewSorter + { + ColumnNumber = e.Column, + }; + lv.ListViewItemSorter = sorter; + } + + if (e.Column == sorter.ColumnNumber) + { + sorter.Descending = !sorter.Descending; // inverse sort direction + } + else + { + sorter.ColumnNumber = e.Column; + } + + lv.Sort(); + + ListViewSorter.SetSortArrow(listViewParts.Columns[e.Column], sorter.Descending ? SortOrder.Descending : SortOrder.Ascending); + + _fileNamesToJoin.Clear(); + foreach (ListViewItem item in listViewParts.Items) + { + _fileNamesToJoin.Add((string)item.Tag); + } + SortAndLoad(); } } } diff --git a/src/ui/Forms/JoinSubtitles.resx b/src/ui/Forms/JoinSubtitles.resx index 9bad2f599..55f72738c 100644 --- a/src/ui/Forms/JoinSubtitles.resx +++ b/src/ui/Forms/JoinSubtitles.resx @@ -117,6 +117,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 159, 22 + 17, 17 diff --git a/src/ui/Forms/Main.Designer.cs b/src/ui/Forms/Main.Designer.cs index 1e6d87231..02660f86c 100644 --- a/src/ui/Forms/Main.Designer.cs +++ b/src/ui/Forms/Main.Designer.cs @@ -41,9 +41,9 @@ namespace Nikse.SubtitleEdit.Forms { this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Main)); - Nikse.SubtitleEdit.Core.Common.TimeCode timeCode1 = new Nikse.SubtitleEdit.Core.Common.TimeCode(); - Nikse.SubtitleEdit.Core.Common.TimeCode timeCode2 = new Nikse.SubtitleEdit.Core.Common.TimeCode(); - Nikse.SubtitleEdit.Core.Common.TimeCode timeCode3 = new Nikse.SubtitleEdit.Core.Common.TimeCode(); + Nikse.SubtitleEdit.Core.Common.TimeCode timeCode13 = new Nikse.SubtitleEdit.Core.Common.TimeCode(); + Nikse.SubtitleEdit.Core.Common.TimeCode timeCode14 = new Nikse.SubtitleEdit.Core.Common.TimeCode(); + Nikse.SubtitleEdit.Core.Common.TimeCode timeCode15 = new Nikse.SubtitleEdit.Core.Common.TimeCode(); this.statusStrip1 = new System.Windows.Forms.StatusStrip(); this.labelStatus = new System.Windows.Forms.ToolStripStatusLabel(); this.toolStripSelected = new System.Windows.Forms.ToolStripStatusLabel(); @@ -452,7 +452,6 @@ namespace Nikse.SubtitleEdit.Forms this.splitToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); this.mergeWithPreviousToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.mergeWithNextToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.runWhiperOnParagraphToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator11 = new System.Windows.Forms.ToolStripSeparator(); this.extendToPreviousToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.extendToNextToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -465,6 +464,7 @@ namespace Nikse.SubtitleEdit.Forms this.toolStripSeparatorGuessTimeCodes = new System.Windows.Forms.ToolStripSeparator(); this.removeShotChangeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.addShotChangeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.runWhiperOnParagraphToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.guessTimeCodesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.seekSilenceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.insertSubtitleHereToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -582,6 +582,9 @@ namespace Nikse.SubtitleEdit.Forms this.timerOriginalTextUndo = new System.Windows.Forms.Timer(this.components); this.contextMenuStripShowVideoControls = new System.Windows.Forms.ContextMenuStrip(this.components); this.toolStripMenuItemShowVideoControls = new System.Windows.Forms.ToolStripMenuItem(); + this.contextMenuStripVideoFileName = new System.Windows.Forms.ContextMenuStrip(this.components); + this.videoInfoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.openContainingFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.statusStrip1.SuspendLayout(); this.toolStrip1.SuspendLayout(); this.menuStrip1.SuspendLayout(); @@ -620,6 +623,7 @@ namespace Nikse.SubtitleEdit.Forms this.panelVideoPlayer.SuspendLayout(); this.contextMenuStripEmpty.SuspendLayout(); this.contextMenuStripShowVideoControls.SuspendLayout(); + this.contextMenuStripVideoFileName.SuspendLayout(); this.SuspendLayout(); // // statusStrip1 @@ -1077,7 +1081,7 @@ namespace Nikse.SubtitleEdit.Forms this.comboBoxEncoding.DropDownHeight = 215; this.comboBoxEncoding.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBoxEncoding.DropDownWidth = 0; - this.comboBoxEncoding.Items.AddRange(new object[] { + this.comboBoxEncoding.Items.AddRange(new string[] { "ANSI", "UTF-7", "UTF-8", @@ -3401,13 +3405,13 @@ namespace Nikse.SubtitleEdit.Forms // labelVideoInfo // this.labelVideoInfo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.labelVideoInfo.ContextMenuStrip = this.contextMenuStripVideoFileName; this.labelVideoInfo.Location = new System.Drawing.Point(603, 12); this.labelVideoInfo.Name = "labelVideoInfo"; this.labelVideoInfo.Size = new System.Drawing.Size(369, 19); this.labelVideoInfo.TabIndex = 12; this.labelVideoInfo.Text = "No video file loaded"; this.labelVideoInfo.TextAlign = System.Drawing.ContentAlignment.TopRight; - this.labelVideoInfo.Click += new System.EventHandler(this.labelVideoInfo_Click); // // trackBarWaveformPosition // @@ -3680,7 +3684,7 @@ namespace Nikse.SubtitleEdit.Forms this.comboBoxAutoContinue.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBoxAutoContinue.DropDownWidth = 96; this.comboBoxAutoContinue.FormattingEnabled = false; - this.comboBoxAutoContinue.Items.AddRange(new object[] { + this.comboBoxAutoContinue.Items.AddRange(new string[] { "0", "1", "2", @@ -3762,7 +3766,7 @@ namespace Nikse.SubtitleEdit.Forms this.comboBoxAutoRepeat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBoxAutoRepeat.DropDownWidth = 96; this.comboBoxAutoRepeat.FormattingEnabled = false; - this.comboBoxAutoRepeat.Items.AddRange(new object[] { + this.comboBoxAutoRepeat.Items.AddRange(new string[] { "0", "1", "2", @@ -3886,14 +3890,14 @@ namespace Nikse.SubtitleEdit.Forms this.timeUpDownVideoPosition.Size = new System.Drawing.Size(113, 23); this.timeUpDownVideoPosition.TabIndex = 12; this.timeUpDownVideoPosition.TabStop = false; - timeCode1.Hours = 0; - timeCode1.Milliseconds = 0; - timeCode1.Minutes = 0; - timeCode1.Seconds = 0; - timeCode1.TimeSpan = System.TimeSpan.Parse("00:00:00"); - timeCode1.TotalMilliseconds = 0D; - timeCode1.TotalSeconds = 0D; - this.timeUpDownVideoPosition.TimeCode = timeCode1; + timeCode13.Hours = 0; + timeCode13.Milliseconds = 0; + timeCode13.Minutes = 0; + timeCode13.Seconds = 0; + timeCode13.TimeSpan = System.TimeSpan.Parse("00:00:00"); + timeCode13.TotalMilliseconds = 0D; + timeCode13.TotalSeconds = 0D; + this.timeUpDownVideoPosition.TimeCode = timeCode13; this.timeUpDownVideoPosition.UseVideoOffset = false; // // buttonGotoSub @@ -4166,14 +4170,14 @@ namespace Nikse.SubtitleEdit.Forms this.timeUpDownVideoPositionAdjust.Size = new System.Drawing.Size(113, 23); this.timeUpDownVideoPositionAdjust.TabIndex = 13; this.timeUpDownVideoPositionAdjust.TabStop = false; - timeCode2.Hours = 0; - timeCode2.Milliseconds = 0; - timeCode2.Minutes = 0; - timeCode2.Seconds = 0; - timeCode2.TimeSpan = System.TimeSpan.Parse("00:00:00"); - timeCode2.TotalMilliseconds = 0D; - timeCode2.TotalSeconds = 0D; - this.timeUpDownVideoPositionAdjust.TimeCode = timeCode2; + timeCode14.Hours = 0; + timeCode14.Milliseconds = 0; + timeCode14.Minutes = 0; + timeCode14.Seconds = 0; + timeCode14.TimeSpan = System.TimeSpan.Parse("00:00:00"); + timeCode14.TotalMilliseconds = 0D; + timeCode14.TotalSeconds = 0D; + this.timeUpDownVideoPositionAdjust.TimeCode = timeCode14; this.timeUpDownVideoPositionAdjust.UseVideoOffset = false; // // buttonAdjustSetEndTime @@ -4472,7 +4476,7 @@ namespace Nikse.SubtitleEdit.Forms this.seekSilenceToolStripMenuItem, this.insertSubtitleHereToolStripMenuItem}); this.contextMenuStripWaveform.Name = "contextMenuStripWaveform"; - this.contextMenuStripWaveform.Size = new System.Drawing.Size(275, 534); + this.contextMenuStripWaveform.Size = new System.Drawing.Size(275, 512); this.contextMenuStripWaveform.Closing += new System.Windows.Forms.ToolStripDropDownClosingEventHandler(this.ContextMenuStripWaveformClosing); this.contextMenuStripWaveform.Opening += new System.ComponentModel.CancelEventHandler(this.ContextMenuStripWaveformOpening); // @@ -4546,13 +4550,6 @@ namespace Nikse.SubtitleEdit.Forms this.mergeWithNextToolStripMenuItem.Text = "Merge with next"; this.mergeWithNextToolStripMenuItem.Click += new System.EventHandler(this.MergeWithNextToolStripMenuItemClick); // - // runWhiperOnParagraphToolStripMenuItem - // - this.runWhiperOnParagraphToolStripMenuItem.Name = "runWhiperOnParagraphToolStripMenuItem"; - this.runWhiperOnParagraphToolStripMenuItem.Size = new System.Drawing.Size(274, 22); - this.runWhiperOnParagraphToolStripMenuItem.Text = "Run Whiper on paragraph..."; - this.runWhiperOnParagraphToolStripMenuItem.Click += new System.EventHandler(this.runWhiperOnParagraphToolStripMenuItem_Click); - // // toolStripSeparator11 // this.toolStripSeparator11.Name = "toolStripSeparator11"; @@ -4629,6 +4626,13 @@ namespace Nikse.SubtitleEdit.Forms this.addShotChangeToolStripMenuItem.Text = "Add shot change"; this.addShotChangeToolStripMenuItem.Click += new System.EventHandler(this.AddShotChangeToolStripMenuItemClick); // + // runWhiperOnParagraphToolStripMenuItem + // + this.runWhiperOnParagraphToolStripMenuItem.Name = "runWhiperOnParagraphToolStripMenuItem"; + this.runWhiperOnParagraphToolStripMenuItem.Size = new System.Drawing.Size(274, 22); + this.runWhiperOnParagraphToolStripMenuItem.Text = "Run Whiper on paragraph..."; + this.runWhiperOnParagraphToolStripMenuItem.Click += new System.EventHandler(this.runWhiperOnParagraphToolStripMenuItem_Click); + // // guessTimeCodesToolStripMenuItem // this.guessTimeCodesToolStripMenuItem.Name = "guessTimeCodesToolStripMenuItem"; @@ -5522,14 +5526,14 @@ namespace Nikse.SubtitleEdit.Forms this.timeUpDownStartTime.Size = new System.Drawing.Size(113, 23); this.timeUpDownStartTime.TabIndex = 0; this.timeUpDownStartTime.TabStop = false; - timeCode3.Hours = 0; - timeCode3.Milliseconds = 0; - timeCode3.Minutes = 0; - timeCode3.Seconds = 0; - timeCode3.TimeSpan = System.TimeSpan.Parse("00:00:00"); - timeCode3.TotalMilliseconds = 0D; - timeCode3.TotalSeconds = 0D; - this.timeUpDownStartTime.TimeCode = timeCode3; + timeCode15.Hours = 0; + timeCode15.Milliseconds = 0; + timeCode15.Minutes = 0; + timeCode15.Seconds = 0; + timeCode15.TimeSpan = System.TimeSpan.Parse("00:00:00"); + timeCode15.TotalMilliseconds = 0D; + timeCode15.TotalSeconds = 0D; + this.timeUpDownStartTime.TimeCode = timeCode15; this.timeUpDownStartTime.UseVideoOffset = false; // // numericUpDownDuration @@ -5883,6 +5887,29 @@ namespace Nikse.SubtitleEdit.Forms this.toolStripMenuItemShowVideoControls.Text = "Show video controls"; this.toolStripMenuItemShowVideoControls.Click += new System.EventHandler(this.ToolStripMenuItemShowVideoControlsClick); // + // contextMenuStripVideoFileName + // + this.contextMenuStripVideoFileName.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.videoInfoToolStripMenuItem, + this.openContainingFolderToolStripMenuItem}); + this.contextMenuStripVideoFileName.Name = "contextMenuStripVideoFileName"; + this.contextMenuStripVideoFileName.Size = new System.Drawing.Size(198, 48); + this.contextMenuStripVideoFileName.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuStripVideoFileName_Opening); + // + // videoInfoToolStripMenuItem + // + this.videoInfoToolStripMenuItem.Name = "videoInfoToolStripMenuItem"; + this.videoInfoToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.videoInfoToolStripMenuItem.Text = "Video info"; + this.videoInfoToolStripMenuItem.Click += new System.EventHandler(this.videoInfoToolStripMenuItem_Click); + // + // openContainingFolderToolStripMenuItem + // + this.openContainingFolderToolStripMenuItem.Name = "openContainingFolderToolStripMenuItem"; + this.openContainingFolderToolStripMenuItem.Size = new System.Drawing.Size(197, 22); + this.openContainingFolderToolStripMenuItem.Text = "Open containing folder"; + this.openContainingFolderToolStripMenuItem.Click += new System.EventHandler(this.openContainingFolderToolStripMenuItem_Click); + // // Main // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -5959,6 +5986,7 @@ namespace Nikse.SubtitleEdit.Forms this.panelVideoPlayer.ResumeLayout(false); this.contextMenuStripEmpty.ResumeLayout(false); this.contextMenuStripShowVideoControls.ResumeLayout(false); + this.contextMenuStripVideoFileName.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -6504,5 +6532,8 @@ namespace Nikse.SubtitleEdit.Forms private System.Windows.Forms.ToolStripButton toolStripButtonVideoOpen; private System.Windows.Forms.ToolStripMenuItem runWhiperOnParagraphToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem textToSpeechAndAddToVideoToolStripMenuItem; + private ContextMenuStrip contextMenuStripVideoFileName; + private ToolStripMenuItem videoInfoToolStripMenuItem; + private ToolStripMenuItem openContainingFolderToolStripMenuItem; } } \ No newline at end of file diff --git a/src/ui/Forms/Main.cs b/src/ui/Forms/Main.cs index 7f5e1b895..6374e4cb7 100644 --- a/src/ui/Forms/Main.cs +++ b/src/ui/Forms/Main.cs @@ -345,6 +345,7 @@ namespace Nikse.SubtitleEdit.Forms UiUtil.InitializeSubtitleFont(textBoxListViewText); UiUtil.InitializeSubtitleFont(textBoxListViewTextOriginal); UiUtil.InitializeSubtitleFont(SubtitleListview1); + UiUtil.InitializeSubtitleFont(textBoxSource); } private static string GetArgumentAfterColon(IEnumerable commandLineArguments, string requestedArgumentName) @@ -5783,6 +5784,7 @@ namespace Nikse.SubtitleEdit.Forms SubtitleListview1.BackColor = Configuration.Settings.General.SubtitleBackgroundColor; UiUtil.InitializeSubtitleFont(SubtitleListview1); + UiUtil.InitializeSubtitleFont(textBoxSource); mediaPlayer.SetSubtitleFont(); ShowSubtitle(); } @@ -23572,7 +23574,9 @@ namespace Nikse.SubtitleEdit.Forms private void SetAssaResolutionWithChecks() { - if (Configuration.Settings.SubtitleSettings.AssaResolutionAutoNew && IsAssa() && _videoInfo?.Height > 0) + if (Configuration.Settings.SubtitleSettings.AssaResolutionAutoNew && + string.IsNullOrEmpty(_subtitle?.Header) && + IsAssa() && _videoInfo?.Height > 0) { if (string.IsNullOrEmpty(_subtitle?.Header)) { @@ -36692,9 +36696,46 @@ namespace Nikse.SubtitleEdit.Forms } } - private void labelVideoInfo_Click(object sender, EventArgs e) + private void ToolStripButtonVideoOpenClick(object sender, EventArgs e) { - if (string.IsNullOrEmpty(_videoFileName) || _videoInfo == null || Configuration.Settings.Tools.DisableVidoInfoViaLabel) + OpenVideoDialog(); + } + + private void runWhiperOnParagraphToolStripMenuItem_Click(object sender, EventArgs e) + { + AudioToTextWhisperSelectedLines(); + } + + private void textToSpeechAndAddToVideoToolStripMenuItem_Click(object sender, EventArgs e) + { + TaskDelayHelper.RunDelayed(TimeSpan.FromMilliseconds(25), () => + { + if (string.IsNullOrEmpty(_videoFileName) || _videoInfo == null) + { + MessageBox.Show(LanguageSettings.Current.General.NoVideoLoaded); + return; + } + + if (RequireFfmpegOk()) + { + using (var form = new TextToSpeech(_subtitle, GetCurrentSubtitleFormat(), _videoFileName, _videoInfo)) + { + if (form.ShowDialog(this) == DialogResult.OK) + { + var idx = FirstSelectedIndex; + _subtitle = form.EditedSubtitle; + SubtitleListview1.Fill(_subtitle, _subtitleOriginal); + _subtitleListViewIndex = -1; + SubtitleListview1.SelectIndexAndEnsureVisibleFaster(idx); + } + } + } + }); + } + + private void videoInfoToolStripMenuItem_Click(object sender, EventArgs e) + { + if (string.IsNullOrEmpty(_videoFileName) || _videoInfo == null) { return; } @@ -36780,41 +36821,23 @@ namespace Nikse.SubtitleEdit.Forms MessageBox.Show(sb.ToString() + sbTrackInfo.ToString()); } - private void ToolStripButtonVideoOpenClick(object sender, EventArgs e) + private void contextMenuStripVideoFileName_Opening(object sender, CancelEventArgs e) { - OpenVideoDialog(); - } - - private void runWhiperOnParagraphToolStripMenuItem_Click(object sender, EventArgs e) - { - AudioToTextWhisperSelectedLines(); - } - - private void textToSpeechAndAddToVideoToolStripMenuItem_Click(object sender, EventArgs e) - { - TaskDelayHelper.RunDelayed(TimeSpan.FromMilliseconds(25), () => + if (string.IsNullOrEmpty(_videoFileName) || _videoInfo == null) { - if (string.IsNullOrEmpty(_videoFileName) || _videoInfo == null) - { - MessageBox.Show(LanguageSettings.Current.General.NoVideoLoaded); - return; - } + e.Cancel = true; + } - if (RequireFfmpegOk()) - { - using (var form = new TextToSpeech(_subtitle, GetCurrentSubtitleFormat(), _videoFileName, _videoInfo)) - { - if (form.ShowDialog(this) == DialogResult.OK) - { - var idx = FirstSelectedIndex; - _subtitle = form.EditedSubtitle; - SubtitleListview1.Fill(_subtitle, _subtitleOriginal); - _subtitleListViewIndex = -1; - SubtitleListview1.SelectIndexAndEnsureVisibleFaster(idx); - } - } - } - }); + openContainingFolderToolStripMenuItem.Text = _language.Menu.File.OpenContainingFolder; + videoInfoToolStripMenuItem.Text = _language.Menu.ContextMenu.MediaInfo; + } + + private void openContainingFolderToolStripMenuItem_Click(object sender, EventArgs e) + { + if (!string.IsNullOrEmpty(_videoFileName) && File.Exists(_videoFileName)) + { + UiUtil.OpenFolderFromFileName(_videoFileName); + } } } } \ No newline at end of file diff --git a/src/ui/Forms/Main.resx b/src/ui/Forms/Main.resx index d5979c470..c577e339f 100644 --- a/src/ui/Forms/Main.resx +++ b/src/ui/Forms/Main.resx @@ -684,6 +684,12 @@ ZW1zBV9zaXplCF92ZXJzaW9uBwAABggIAgAAAAkDAAAAAAAAAAAAAAAPAwAAAAAAAAAGCw== + + 929, 92 + + + 652, 56 + 652, 56 @@ -769,12 +775,12 @@ 981, 56 - - 668, 17 - 193, 17 + + 668, 17 + 17, 95 diff --git a/src/ui/Forms/MergeShortLines.cs b/src/ui/Forms/MergeShortLines.cs index 71ff16387..25e2d662c 100644 --- a/src/ui/Forms/MergeShortLines.cs +++ b/src/ui/Forms/MergeShortLines.cs @@ -346,18 +346,12 @@ namespace Nikse.SubtitleEdit.Forms private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewFixes.Items) - { - item.Checked = true; - } + listViewFixes.CheckAll(); } private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewFixes.Items) - { - item.Checked = !item.Checked; - } + listViewFixes.InvertCheck(); } } } diff --git a/src/ui/Forms/MergeTextWithSameTimeCodes.cs b/src/ui/Forms/MergeTextWithSameTimeCodes.cs index 7d10bb2fb..3ce97098b 100644 --- a/src/ui/Forms/MergeTextWithSameTimeCodes.cs +++ b/src/ui/Forms/MergeTextWithSameTimeCodes.cs @@ -297,18 +297,12 @@ namespace Nikse.SubtitleEdit.Forms private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewFixes.Items) - { - item.Checked = true; - } + listViewFixes.CheckAll(); } private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewFixes.Items) - { - item.Checked = !item.Checked; - } + listViewFixes.InvertCheck(); } private void checkBoxMakeDialog_CheckedChanged(object sender, EventArgs e) diff --git a/src/ui/Forms/ModifySelection.cs b/src/ui/Forms/ModifySelection.cs index 2419ff755..23c26b7a3 100644 --- a/src/ui/Forms/ModifySelection.cs +++ b/src/ui/Forms/ModifySelection.cs @@ -28,13 +28,15 @@ namespace Nikse.SubtitleEdit.Forms private const int FunctionEven = 7; private const int FunctionDurationLessThan = 8; private const int FunctionDurationGreaterThan = 9; - private const int FunctionExactlyOneLine = 10; - private const int FunctionExactlyTwoLines = 11; - private const int FunctionMoreThanTwoLines = 12; - private const int FunctionBookmarked = 13; - private const int FunctionBlankLines = 14; - private const int FunctionStyle = 15; - private const int FunctionActor = 16; + private const int FunctionCpsLessThan = 10; + private const int FunctionCpsGreaterThan = 11; + private const int FunctionExactlyOneLine = 12; + private const int FunctionExactlyTwoLines = 13; + private const int FunctionMoreThanTwoLines = 14; + private const int FunctionBookmarked = 15; + private const int FunctionBlankLines = 16; + private const int FunctionStyle = 17; + private const int FunctionActor = 18; private const string ContainsString = "Contains"; private const string StartsWith = "Starts with"; @@ -46,6 +48,8 @@ namespace Nikse.SubtitleEdit.Forms private const string Even = "Even"; private const string DurationLessThan = "Duration <"; private const string DurationGreaterThan = "Duration >"; + private const string CpsLessThan = "CPS <"; + private const string CpsGreaterThan = "CPS >"; private const string ExactlyOneLine = "Exactly one line"; private const string ExactlyTwoLines = "Exactly two lines"; private const string MoreThanTwoLines = "More than two lines"; @@ -97,6 +101,8 @@ namespace Nikse.SubtitleEdit.Forms comboBoxRule.Items.Add(LanguageSettings.Current.ModifySelection.EvenLines); comboBoxRule.Items.Add(LanguageSettings.Current.ModifySelection.DurationLessThan); comboBoxRule.Items.Add(LanguageSettings.Current.ModifySelection.DurationGreaterThan); + comboBoxRule.Items.Add(LanguageSettings.Current.ModifySelection.CpsLessThan); + comboBoxRule.Items.Add(LanguageSettings.Current.ModifySelection.CpsGreaterThan); comboBoxRule.Items.Add(LanguageSettings.Current.ModifySelection.ExactlyOneLine); comboBoxRule.Items.Add(LanguageSettings.Current.ModifySelection.ExactlyTwoLines); comboBoxRule.Items.Add(LanguageSettings.Current.ModifySelection.MoreThanTwoLines); @@ -142,6 +148,12 @@ namespace Nikse.SubtitleEdit.Forms case DurationGreaterThan: comboBoxRule.SelectedIndex = FunctionDurationGreaterThan; break; + case CpsLessThan: + comboBoxRule.SelectedIndex = FunctionCpsLessThan; + break; + case CpsGreaterThan: + comboBoxRule.SelectedIndex = FunctionCpsGreaterThan; + break; case ExactlyOneLine: comboBoxRule.SelectedIndex = FunctionExactlyOneLine; break; @@ -226,6 +238,12 @@ namespace Nikse.SubtitleEdit.Forms case FunctionDurationGreaterThan: Configuration.Settings.Tools.ModifySelectionRule = DurationGreaterThan; break; + case FunctionCpsLessThan: + Configuration.Settings.Tools.ModifySelectionRule = CpsLessThan; + break; + case FunctionCpsGreaterThan: + Configuration.Settings.Tools.ModifySelectionRule = CpsGreaterThan; + break; case FunctionExactlyOneLine: Configuration.Settings.Tools.ModifySelectionRule = ExactlyOneLine; break; @@ -311,7 +329,7 @@ namespace Nikse.SubtitleEdit.Forms } } - for (int i = 0; i < _subtitle.Paragraphs.Count; i++) + for (var i = 0; i < _subtitle.Paragraphs.Count; i++) { if ((radioButtonSubtractFromSelection.Checked || radioButtonIntersect.Checked) && _subtitleListView.Items[i].Selected || !radioButtonSubtractFromSelection.Checked && !radioButtonIntersect.Checked) @@ -397,6 +415,20 @@ namespace Nikse.SubtitleEdit.Forms listViewItems.Add(MakeListViewItem(p, i)); } } + else if (comboBoxRule.SelectedIndex == FunctionCpsLessThan) // Cps less than + { + if (Utilities.GetCharactersPerSecond(p) < (double)numericUpDownDuration.Value) + { + listViewItems.Add(MakeListViewItem(p, i)); + } + } + else if (comboBoxRule.SelectedIndex == FunctionCpsGreaterThan) // Cps greater than + { + if (Utilities.GetCharactersPerSecond(p) > (double)numericUpDownDuration.Value) + { + listViewItems.Add(MakeListViewItem(p, i)); + } + } else if (comboBoxRule.SelectedIndex == FunctionExactlyOneLine) { if (p.Text.SplitToLines().Count == 1) @@ -504,28 +536,37 @@ namespace Nikse.SubtitleEdit.Forms { textBoxText.Visible = true; listViewStyles.Visible = false; - numericUpDownDuration.Visible = comboBoxRule.SelectedIndex == FunctionDurationLessThan || comboBoxRule.SelectedIndex == FunctionDurationGreaterThan; + numericUpDownDuration.Visible = + comboBoxRule.SelectedIndex == FunctionDurationLessThan || + comboBoxRule.SelectedIndex == FunctionDurationGreaterThan || + comboBoxRule.SelectedIndex == FunctionCpsLessThan || + comboBoxRule.SelectedIndex == FunctionCpsGreaterThan; + if (comboBoxRule.SelectedIndex == FunctionRegEx) // RegEx { - // creat new context menu only if textBoxText doesn't already has one, this will prevent unnecessary + // create new context menu only if textBoxText doesn't already has one, this will prevent unnecessary // allocation regex option is already selected and user re-select it - textBoxText.ContextMenuStrip = textBoxText.ContextMenuStrip ?? + textBoxText.ContextMenuStrip = textBoxText.ContextMenuStrip ?? FindReplaceDialogHelper.GetRegExContextMenu(new NativeTextBoxAdapter(textBoxText)); checkBoxCaseSensitive.Enabled = false; } - else if (comboBoxRule.SelectedIndex == FunctionOdd || - comboBoxRule.SelectedIndex == FunctionEven || - comboBoxRule.SelectedIndex == FunctionExactlyOneLine || - comboBoxRule.SelectedIndex == FunctionExactlyTwoLines || - comboBoxRule.SelectedIndex == FunctionMoreThanTwoLines || - comboBoxRule.SelectedIndex == FunctionBookmarked || + else if (comboBoxRule.SelectedIndex == FunctionOdd || + comboBoxRule.SelectedIndex == FunctionEven || + comboBoxRule.SelectedIndex == FunctionExactlyOneLine || + comboBoxRule.SelectedIndex == FunctionExactlyTwoLines || + comboBoxRule.SelectedIndex == FunctionMoreThanTwoLines || + comboBoxRule.SelectedIndex == FunctionBookmarked || comboBoxRule.SelectedIndex == FunctionBlankLines) { checkBoxCaseSensitive.Enabled = false; textBoxText.ContextMenuStrip = null; textBoxText.Visible = false; } - else if (comboBoxRule.SelectedIndex == FunctionDurationLessThan || comboBoxRule.SelectedIndex == FunctionDurationGreaterThan || comboBoxRule.SelectedIndex == FunctionAllUppercase) + else if (comboBoxRule.SelectedIndex == FunctionDurationLessThan || + comboBoxRule.SelectedIndex == FunctionDurationGreaterThan || + comboBoxRule.SelectedIndex == FunctionCpsLessThan || + comboBoxRule.SelectedIndex == FunctionCpsGreaterThan || + comboBoxRule.SelectedIndex == FunctionAllUppercase) { checkBoxCaseSensitive.Enabled = false; listViewStyles.Visible = false; @@ -539,7 +580,7 @@ namespace Nikse.SubtitleEdit.Forms numericUpDownDuration.Value = Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds; } } - else + else if (comboBoxRule.SelectedIndex == FunctionDurationGreaterThan) { if (numericUpDownDuration.Value == 0 && Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds >= numericUpDownDuration.Minimum && @@ -548,6 +589,14 @@ namespace Nikse.SubtitleEdit.Forms numericUpDownDuration.Value = Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds; } } + else if (comboBoxRule.SelectedIndex == FunctionCpsLessThan) + { + numericUpDownDuration.Value = (int)Math.Round(Math.Max(10, Configuration.Settings.General.SubtitleOptimalCharactersPerSeconds - 5), MidpointRounding.AwayFromZero); + } + else if (comboBoxRule.SelectedIndex == FunctionCpsGreaterThan) + { + numericUpDownDuration.Value = (int)Math.Round(Configuration.Settings.General.SubtitleMaximumCharactersPerSeconds, MidpointRounding.AwayFromZero); + } } else if (comboBoxRule.SelectedIndex == FunctionStyle) { @@ -642,18 +691,12 @@ namespace Nikse.SubtitleEdit.Forms private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewFixes.Items) - { - item.Checked = true; - } + listViewFixes.CheckAll(); } private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewFixes.Items) - { - item.Checked = !item.Checked; - } + listViewFixes.InvertCheck(); } private void ModifySelection_Resize(object sender, EventArgs e) diff --git a/src/ui/Forms/MultipleReplace.cs b/src/ui/Forms/MultipleReplace.cs index bc42e7280..a7ab11a9e 100644 --- a/src/ui/Forms/MultipleReplace.cs +++ b/src/ui/Forms/MultipleReplace.cs @@ -570,18 +570,12 @@ namespace Nikse.SubtitleEdit.Forms private void buttonReplacesSelectAll_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewFixes.Items) - { - item.Checked = true; - } + listViewFixes.CheckAll(); } private void buttonReplacesInverseSelection_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewFixes.Items) - { - item.Checked = !item.Checked; - } + listViewFixes.InvertCheck(); } private void contextMenuStrip1_Opening(object sender, System.ComponentModel.CancelEventArgs e) @@ -1446,18 +1440,12 @@ namespace Nikse.SubtitleEdit.Forms private void selectAllToolStripMenuItem_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewRules.Items) - { - item.Checked = true; - } + listViewRules.CheckAll(); } private void inverseSelectionToolStripMenuItem_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewRules.Items) - { - item.Checked = !item.Checked; - } + listViewRules.InvertCheck(); } private void ContextMenuStripListViewFixesOpening(object sender, System.ComponentModel.CancelEventArgs e) diff --git a/src/ui/Forms/MultipleReplaceExportImport.cs b/src/ui/Forms/MultipleReplaceExportImport.cs index f1886962a..e71207e71 100644 --- a/src/ui/Forms/MultipleReplaceExportImport.cs +++ b/src/ui/Forms/MultipleReplaceExportImport.cs @@ -136,18 +136,12 @@ namespace Nikse.SubtitleEdit.Forms private void selectAllToolStripMenuItem_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewExportStyles.Items) - { - item.Checked = true; - } + listViewExportStyles.CheckAll(); } private void inverseSelectionToolStripMenuItem_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewExportStyles.Items) - { - item.Checked = !item.Checked; - } + listViewExportStyles.InvertCheck(); } } } diff --git a/src/ui/Forms/Ocr/BinaryOcrTrain.cs b/src/ui/Forms/Ocr/BinaryOcrTrain.cs index 096bcc4c0..675dd8757 100644 --- a/src/ui/Forms/Ocr/BinaryOcrTrain.cs +++ b/src/ui/Forms/Ocr/BinaryOcrTrain.cs @@ -328,12 +328,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr private void SelectAll_Click(object sender, EventArgs e) { - listViewFonts.BeginUpdate(); - foreach (ListViewItem fontItem in listViewFonts.Items) - { - fontItem.Checked = true; - } - listViewFonts.EndUpdate(); + listViewFonts.CheckAll(); } public void InitializeDetectFont(BinaryOcrBitmap bob, string text) diff --git a/src/ui/Forms/Ocr/VobSubCharactersImport.cs b/src/ui/Forms/Ocr/VobSubCharactersImport.cs index 89881497f..47ef345d6 100644 --- a/src/ui/Forms/Ocr/VobSubCharactersImport.cs +++ b/src/ui/Forms/Ocr/VobSubCharactersImport.cs @@ -143,11 +143,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr private void buttonFixesSelectAll_Click(object sender, EventArgs e) { listView1.ItemChecked -= listView1_ItemChecked; - - foreach (ListViewItem item in listView1.Items) - { - item.Checked = true; - } + listView1.CheckAll(); foreach (ListViewData d in _data) { diff --git a/src/ui/Forms/Ocr/VobSubOcr.cs b/src/ui/Forms/Ocr/VobSubOcr.cs index 9823c69f5..4427632f7 100644 --- a/src/ui/Forms/Ocr/VobSubOcr.cs +++ b/src/ui/Forms/Ocr/VobSubOcr.cs @@ -8600,6 +8600,13 @@ namespace Nikse.SubtitleEdit.Forms.Ocr // ignored } } + + e.Handled = true; + } + else if (e.KeyCode == Keys.Delete) + { + removeAllXToolStripMenuItem_Click(null, null); + e.Handled = true; } } diff --git a/src/ui/Forms/Options/SettingsProfileExport.cs b/src/ui/Forms/Options/SettingsProfileExport.cs index d0a79dda4..f7518faac 100644 --- a/src/ui/Forms/Options/SettingsProfileExport.cs +++ b/src/ui/Forms/Options/SettingsProfileExport.cs @@ -76,18 +76,12 @@ namespace Nikse.SubtitleEdit.Forms.Options private void selectAllToolStripMenuItem_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewExportStyles.Items) - { - item.Checked = true; - } + listViewExportStyles.CheckAll(); } private void inverseSelectionToolStripMenuItem_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewExportStyles.Items) - { - item.Checked = !item.Checked; - } + listViewExportStyles.InvertCheck(); } } } diff --git a/src/ui/Forms/SplitLongLines.cs b/src/ui/Forms/SplitLongLines.cs index 3772883ec..9bf788e6c 100644 --- a/src/ui/Forms/SplitLongLines.cs +++ b/src/ui/Forms/SplitLongLines.cs @@ -718,10 +718,7 @@ namespace Nikse.SubtitleEdit.Forms private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) { listViewFixes.ItemChecked -= listViewFixes_ItemChecked; - foreach (ListViewItem item in listViewFixes.Items) - { - item.Checked = true; - } + listViewFixes.CheckAll(); listViewFixes.ItemChecked += listViewFixes_ItemChecked; GeneratePreview(false); } @@ -729,10 +726,7 @@ namespace Nikse.SubtitleEdit.Forms private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) { listViewFixes.ItemChecked -= listViewFixes_ItemChecked; - foreach (ListViewItem item in listViewFixes.Items) - { - item.Checked = !item.Checked; - } + listViewFixes.InvertCheck(); listViewFixes.ItemChecked += listViewFixes_ItemChecked; GeneratePreview(false); } diff --git a/src/ui/Forms/Styles/SubStationAlphaStylesExport.cs b/src/ui/Forms/Styles/SubStationAlphaStylesExport.cs index 738ee61ce..3f5fe4a86 100644 --- a/src/ui/Forms/Styles/SubStationAlphaStylesExport.cs +++ b/src/ui/Forms/Styles/SubStationAlphaStylesExport.cs @@ -186,18 +186,12 @@ namespace Nikse.SubtitleEdit.Forms.Styles private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewExportStyles.Items) - { - item.Checked = true; - } + listViewExportStyles.CheckAll(); } private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewExportStyles.Items) - { - item.Checked = !item.Checked; - } + listViewExportStyles.InvertCheck(); } } } diff --git a/src/ui/Forms/Translate/AutoTranslate.cs b/src/ui/Forms/Translate/AutoTranslate.cs index dc8a903d7..eec68abb2 100644 --- a/src/ui/Forms/Translate/AutoTranslate.cs +++ b/src/ui/Forms/Translate/AutoTranslate.cs @@ -704,6 +704,20 @@ namespace Nikse.SubtitleEdit.Forms.Translate _autoTranslator = GetCurrentEngine(); var engineType = _autoTranslator.GetType(); + if (_autoTranslator.Name == DeepLTranslate.StaticName && string.IsNullOrWhiteSpace(nikseTextBoxApiKey.Text)) + { + MessageBox.Show(this, string.Format(LanguageSettings.Current.GoogleTranslate.XRequiresAnApiKey, _autoTranslator.Name), Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + _translationInProgress = false; + return; + } + + if (_autoTranslator.Name == DeepLTranslate.StaticName && string.IsNullOrWhiteSpace(nikseComboBoxUrl.Text)) + { + MessageBox.Show(this, string.Format("{0} require an url", _autoTranslator.Name), Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + _translationInProgress = false; + return; + } + SaveSettings(engineType); buttonOK.Enabled = false; diff --git a/src/ui/Forms/Tts/RegenerateAudioClip.Designer.cs b/src/ui/Forms/Tts/RegenerateAudioClip.Designer.cs index f08f44cba..aedece8f0 100644 --- a/src/ui/Forms/Tts/RegenerateAudioClip.Designer.cs +++ b/src/ui/Forms/Tts/RegenerateAudioClip.Designer.cs @@ -1,6 +1,6 @@ namespace Nikse.SubtitleEdit.Forms.Tts { - partial class RegenerateAudioClip + sealed partial class RegenerateAudioClip { /// /// Required designer variable. diff --git a/src/ui/Forms/Tts/RegenerateAudioClip.cs b/src/ui/Forms/Tts/RegenerateAudioClip.cs index 4dd960de3..9820fea43 100644 --- a/src/ui/Forms/Tts/RegenerateAudioClip.cs +++ b/src/ui/Forms/Tts/RegenerateAudioClip.cs @@ -5,7 +5,7 @@ using System.Windows.Forms; namespace Nikse.SubtitleEdit.Forms.Tts { - public partial class RegenerateAudioClip : Form + public sealed partial class RegenerateAudioClip : Form { public TextToSpeech.FileNameAndSpeedFactor FileNameAndSpeedFactor { get; set; } @@ -23,6 +23,10 @@ namespace Nikse.SubtitleEdit.Forms.Tts _textToSpeech = textToSpeech; _index = idx; + Text = LanguageSettings.Current.ExportCustomText.Edit; + labelText.Text = LanguageSettings.Current.General.Text; + labelVoice.Text = LanguageSettings.Current.TextToSpeech.Voice; + buttonReGenerate.Text = LanguageSettings.Current.TextToSpeech.Regenerate; buttonCancel.Text = LanguageSettings.Current.General.Cancel; UiUtil.FixLargeFonts(this, buttonCancel); diff --git a/src/ui/Forms/Tts/ReviewAudioClips.cs b/src/ui/Forms/Tts/ReviewAudioClips.cs index 763a2eb3d..ef276e7b5 100644 --- a/src/ui/Forms/Tts/ReviewAudioClips.cs +++ b/src/ui/Forms/Tts/ReviewAudioClips.cs @@ -24,6 +24,15 @@ namespace Nikse.SubtitleEdit.Forms.Tts UiUtil.PreInitialize(this); InitializeComponent(); UiUtil.FixFonts(this); + Text = LanguageSettings.Current.TextToSpeech.ReviewAudioClips; + labelInfo.Text = LanguageSettings.Current.TextToSpeech.ReviewInfo; + buttonEdit.Text = LanguageSettings.Current.ExportCustomText.Edit; + buttonPlay.Text = LanguageSettings.Current.TextToSpeech.Play; + checkBoxContinuePlay.Text = LanguageSettings.Current.TextToSpeech.AutoContinue; + columnHeaderCps.Text = LanguageSettings.Current.General.CharsPerSec; + columnHeaderInclude.Text = string.Empty; // include + columnHeaderText.Text = LanguageSettings.Current.General.Text; + columnHeaderVoice.Text = LanguageSettings.Current.TextToSpeech.Voice; buttonOK.Text = LanguageSettings.Current.General.Ok; UiUtil.FixLargeFonts(this, buttonOK); diff --git a/src/ui/Forms/Tts/TextToSpeech.Designer.cs b/src/ui/Forms/Tts/TextToSpeech.Designer.cs index 722fb7ac4..b0f4300f5 100644 --- a/src/ui/Forms/Tts/TextToSpeech.Designer.cs +++ b/src/ui/Forms/Tts/TextToSpeech.Designer.cs @@ -34,24 +34,29 @@ this.buttonGenerateTTS = new System.Windows.Forms.Button(); this.progressBar1 = new System.Windows.Forms.ProgressBar(); this.labelEngine = new System.Windows.Forms.Label(); - this.groupBoxMsSettings = new System.Windows.Forms.GroupBox(); + this.groupBoxSettings = new System.Windows.Forms.GroupBox(); + this.labelRegion = new System.Windows.Forms.Label(); + this.nikseComboBoxRegion = new Nikse.SubtitleEdit.Controls.NikseComboBox(); + this.labelVoiceCount = new System.Windows.Forms.Label(); this.checkBoxShowPreview = new System.Windows.Forms.CheckBox(); this.labelApiKey = new System.Windows.Forms.Label(); + this.nikseTextBoxApiKey = new Nikse.SubtitleEdit.Controls.NikseTextBox(); + this.TextBoxTest = new Nikse.SubtitleEdit.Controls.NikseTextBox(); this.buttonTestVoice = new System.Windows.Forms.Button(); this.checkBoxAddToVideoFile = new System.Windows.Forms.CheckBox(); this.labelVoice = new System.Windows.Forms.Label(); + this.nikseComboBoxVoice = new Nikse.SubtitleEdit.Controls.NikseComboBox(); + this.contextMenuStripVoices = new System.Windows.Forms.ContextMenuStrip(this.components); + this.refreshVoicesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.nikseComboBoxEngine = new Nikse.SubtitleEdit.Controls.NikseComboBox(); this.listViewActors = new System.Windows.Forms.ListView(); this.columnHeaderActor = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.columnHeaderVoice = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.contextMenuStripActors = new System.Windows.Forms.ContextMenuStrip(this.components); this.labelActors = new System.Windows.Forms.Label(); this.buttonCancel = new System.Windows.Forms.Button(); - this.labelVoiceCount = new System.Windows.Forms.Label(); - this.nikseTextBoxApiKey = new Nikse.SubtitleEdit.Controls.NikseTextBox(); - this.TextBoxTest = new Nikse.SubtitleEdit.Controls.NikseTextBox(); - this.nikseComboBoxVoice = new Nikse.SubtitleEdit.Controls.NikseComboBox(); - this.nikseComboBoxEngine = new Nikse.SubtitleEdit.Controls.NikseComboBox(); - this.groupBoxMsSettings.SuspendLayout(); + this.groupBoxSettings.SuspendLayout(); + this.contextMenuStripVoices.SuspendLayout(); this.SuspendLayout(); // // buttonOK @@ -108,27 +113,106 @@ this.labelEngine.TabIndex = 14; this.labelEngine.Text = "Engine"; // - // groupBoxMsSettings + // groupBoxSettings // - this.groupBoxMsSettings.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + this.groupBoxSettings.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left))); - this.groupBoxMsSettings.Controls.Add(this.labelVoiceCount); - this.groupBoxMsSettings.Controls.Add(this.checkBoxShowPreview); - this.groupBoxMsSettings.Controls.Add(this.labelApiKey); - this.groupBoxMsSettings.Controls.Add(this.nikseTextBoxApiKey); - this.groupBoxMsSettings.Controls.Add(this.TextBoxTest); - this.groupBoxMsSettings.Controls.Add(this.buttonTestVoice); - this.groupBoxMsSettings.Controls.Add(this.checkBoxAddToVideoFile); - this.groupBoxMsSettings.Controls.Add(this.labelVoice); - this.groupBoxMsSettings.Controls.Add(this.nikseComboBoxVoice); - this.groupBoxMsSettings.Controls.Add(this.labelEngine); - this.groupBoxMsSettings.Controls.Add(this.nikseComboBoxEngine); - this.groupBoxMsSettings.Location = new System.Drawing.Point(15, 12); - this.groupBoxMsSettings.Name = "groupBoxMsSettings"; - this.groupBoxMsSettings.Size = new System.Drawing.Size(391, 405); - this.groupBoxMsSettings.TabIndex = 1; - this.groupBoxMsSettings.TabStop = false; - this.groupBoxMsSettings.Text = "Settings"; + this.groupBoxSettings.Controls.Add(this.labelRegion); + this.groupBoxSettings.Controls.Add(this.nikseComboBoxRegion); + this.groupBoxSettings.Controls.Add(this.labelVoiceCount); + this.groupBoxSettings.Controls.Add(this.checkBoxShowPreview); + this.groupBoxSettings.Controls.Add(this.labelApiKey); + this.groupBoxSettings.Controls.Add(this.nikseTextBoxApiKey); + this.groupBoxSettings.Controls.Add(this.TextBoxTest); + this.groupBoxSettings.Controls.Add(this.buttonTestVoice); + this.groupBoxSettings.Controls.Add(this.checkBoxAddToVideoFile); + this.groupBoxSettings.Controls.Add(this.labelVoice); + this.groupBoxSettings.Controls.Add(this.nikseComboBoxVoice); + this.groupBoxSettings.Controls.Add(this.labelEngine); + this.groupBoxSettings.Controls.Add(this.nikseComboBoxEngine); + this.groupBoxSettings.Location = new System.Drawing.Point(15, 12); + this.groupBoxSettings.Name = "groupBoxSettings"; + this.groupBoxSettings.Size = new System.Drawing.Size(391, 405); + this.groupBoxSettings.TabIndex = 1; + this.groupBoxSettings.TabStop = false; + this.groupBoxSettings.Text = "Settings"; + // + // labelRegion + // + this.labelRegion.AutoSize = true; + this.labelRegion.ImeMode = System.Windows.Forms.ImeMode.NoControl; + this.labelRegion.Location = new System.Drawing.Point(14, 267); + this.labelRegion.Name = "labelRegion"; + this.labelRegion.Size = new System.Drawing.Size(41, 13); + this.labelRegion.TabIndex = 32; + this.labelRegion.Text = "Region"; + // + // nikseComboBoxRegion + // + this.nikseComboBoxRegion.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.nikseComboBoxRegion.BackColor = System.Drawing.SystemColors.Window; + this.nikseComboBoxRegion.BackColorDisabled = System.Drawing.Color.FromArgb(((int)(((byte)(240)))), ((int)(((byte)(240)))), ((int)(((byte)(240))))); + this.nikseComboBoxRegion.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(171)))), ((int)(((byte)(173)))), ((int)(((byte)(179))))); + this.nikseComboBoxRegion.BorderColorDisabled = System.Drawing.Color.FromArgb(((int)(((byte)(120)))), ((int)(((byte)(120)))), ((int)(((byte)(120))))); + this.nikseComboBoxRegion.ButtonForeColor = System.Drawing.SystemColors.ControlText; + this.nikseComboBoxRegion.ButtonForeColorDown = System.Drawing.Color.Orange; + this.nikseComboBoxRegion.ButtonForeColorOver = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215))))); + this.nikseComboBoxRegion.DropDownHeight = 400; + this.nikseComboBoxRegion.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.nikseComboBoxRegion.DropDownWidth = 0; + this.nikseComboBoxRegion.FormattingEnabled = false; + this.nikseComboBoxRegion.Items.AddRange(new string[] { + "australiaeast", + "brazilsouth", + "canadacentral", + "centralus", + "eastasia", + "eastus", + "eastus2", + "francecentral", + "germanywestcentral", + "centralindia", + "japaneast", + "japanwest", + "jioindiawest", + "koreacentral", + "northcentralus", + "northeurope", + "norwayeast", + "southcentralus", + "southeastasia", + "swedencentral", + "switzerlandnorth", + "switzerlandwest", + "uaenorth", + "usgovarizona", + "usgovvirginia", + "uksouth", + "westcentralus", + "westeurope", + "westus", + "westus2", + "westus3"}); + this.nikseComboBoxRegion.Location = new System.Drawing.Point(17, 283); + this.nikseComboBoxRegion.MaxLength = 32767; + this.nikseComboBoxRegion.Name = "nikseComboBoxRegion"; + this.nikseComboBoxRegion.SelectedIndex = -1; + this.nikseComboBoxRegion.SelectedItem = null; + this.nikseComboBoxRegion.SelectedText = ""; + this.nikseComboBoxRegion.Size = new System.Drawing.Size(351, 23); + this.nikseComboBoxRegion.TabIndex = 31; + this.nikseComboBoxRegion.UsePopupWindow = false; + // + // labelVoiceCount + // + this.labelVoiceCount.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.labelVoiceCount.Location = new System.Drawing.Point(268, 84); + this.labelVoiceCount.Name = "labelVoiceCount"; + this.labelVoiceCount.Size = new System.Drawing.Size(100, 23); + this.labelVoiceCount.TabIndex = 29; + this.labelVoiceCount.Text = "255"; + this.labelVoiceCount.TextAlign = System.Drawing.ContentAlignment.BottomRight; // // checkBoxShowPreview // @@ -147,15 +231,37 @@ // this.labelApiKey.AutoSize = true; this.labelApiKey.ImeMode = System.Windows.Forms.ImeMode.NoControl; - this.labelApiKey.Location = new System.Drawing.Point(20, 242); + this.labelApiKey.Location = new System.Drawing.Point(20, 224); this.labelApiKey.Name = "labelApiKey"; this.labelApiKey.Size = new System.Drawing.Size(44, 13); this.labelApiKey.TabIndex = 28; this.labelApiKey.Text = "API key"; // + // nikseTextBoxApiKey + // + this.nikseTextBoxApiKey.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.nikseTextBoxApiKey.FocusedColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215))))); + this.nikseTextBoxApiKey.Location = new System.Drawing.Point(17, 240); + this.nikseTextBoxApiKey.Name = "nikseTextBoxApiKey"; + this.nikseTextBoxApiKey.Size = new System.Drawing.Size(351, 20); + this.nikseTextBoxApiKey.TabIndex = 27; + // + // TextBoxTest + // + this.TextBoxTest.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.TextBoxTest.FocusedColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215))))); + this.TextBoxTest.Location = new System.Drawing.Point(17, 168); + this.TextBoxTest.Name = "TextBoxTest"; + this.TextBoxTest.Size = new System.Drawing.Size(351, 20); + this.TextBoxTest.TabIndex = 20; + this.TextBoxTest.Text = "Hello, how are you?"; + this.TextBoxTest.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxTest_KeyDown); + // // buttonTestVoice // - this.buttonTestVoice.Location = new System.Drawing.Point(17, 158); + this.buttonTestVoice.Location = new System.Drawing.Point(17, 139); this.buttonTestVoice.Name = "buttonTestVoice"; this.buttonTestVoice.Size = new System.Drawing.Size(150, 23); this.buttonTestVoice.TabIndex = 15; @@ -180,12 +286,80 @@ // this.labelVoice.AutoSize = true; this.labelVoice.ImeMode = System.Windows.Forms.ImeMode.NoControl; - this.labelVoice.Location = new System.Drawing.Point(14, 108); + this.labelVoice.Location = new System.Drawing.Point(14, 94); this.labelVoice.Name = "labelVoice"; this.labelVoice.Size = new System.Drawing.Size(34, 13); this.labelVoice.TabIndex = 16; this.labelVoice.Text = "Voice"; // + // nikseComboBoxVoice + // + this.nikseComboBoxVoice.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.nikseComboBoxVoice.BackColor = System.Drawing.SystemColors.Window; + this.nikseComboBoxVoice.BackColorDisabled = System.Drawing.Color.FromArgb(((int)(((byte)(240)))), ((int)(((byte)(240)))), ((int)(((byte)(240))))); + this.nikseComboBoxVoice.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(171)))), ((int)(((byte)(173)))), ((int)(((byte)(179))))); + this.nikseComboBoxVoice.BorderColorDisabled = System.Drawing.Color.FromArgb(((int)(((byte)(120)))), ((int)(((byte)(120)))), ((int)(((byte)(120))))); + this.nikseComboBoxVoice.ButtonForeColor = System.Drawing.SystemColors.ControlText; + this.nikseComboBoxVoice.ButtonForeColorDown = System.Drawing.Color.Orange; + this.nikseComboBoxVoice.ButtonForeColorOver = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215))))); + this.nikseComboBoxVoice.ContextMenuStrip = this.contextMenuStripVoices; + this.nikseComboBoxVoice.DropDownHeight = 400; + this.nikseComboBoxVoice.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.nikseComboBoxVoice.DropDownWidth = 0; + this.nikseComboBoxVoice.FormattingEnabled = false; + this.nikseComboBoxVoice.Location = new System.Drawing.Point(17, 110); + this.nikseComboBoxVoice.MaxLength = 32767; + this.nikseComboBoxVoice.Name = "nikseComboBoxVoice"; + this.nikseComboBoxVoice.SelectedIndex = -1; + this.nikseComboBoxVoice.SelectedItem = null; + this.nikseComboBoxVoice.SelectedText = ""; + this.nikseComboBoxVoice.Size = new System.Drawing.Size(351, 23); + this.nikseComboBoxVoice.TabIndex = 10; + this.nikseComboBoxVoice.UsePopupWindow = false; + // + // contextMenuStripVoices + // + this.contextMenuStripVoices.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.refreshVoicesToolStripMenuItem}); + this.contextMenuStripVoices.Name = "contextMenuStripVoices"; + this.contextMenuStripVoices.Size = new System.Drawing.Size(150, 26); + this.contextMenuStripVoices.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuStripVoices_Opening); + // + // refreshVoicesToolStripMenuItem + // + this.refreshVoicesToolStripMenuItem.Name = "refreshVoicesToolStripMenuItem"; + this.refreshVoicesToolStripMenuItem.Size = new System.Drawing.Size(149, 22); + this.refreshVoicesToolStripMenuItem.Text = "Refresh voices"; + this.refreshVoicesToolStripMenuItem.Click += new System.EventHandler(this.refreshVoicesToolStripMenuItem_Click); + // + // nikseComboBoxEngine + // + this.nikseComboBoxEngine.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.nikseComboBoxEngine.BackColor = System.Drawing.SystemColors.Window; + this.nikseComboBoxEngine.BackColorDisabled = System.Drawing.Color.FromArgb(((int)(((byte)(240)))), ((int)(((byte)(240)))), ((int)(((byte)(240))))); + this.nikseComboBoxEngine.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(171)))), ((int)(((byte)(173)))), ((int)(((byte)(179))))); + this.nikseComboBoxEngine.BorderColorDisabled = System.Drawing.Color.FromArgb(((int)(((byte)(120)))), ((int)(((byte)(120)))), ((int)(((byte)(120))))); + this.nikseComboBoxEngine.ButtonForeColor = System.Drawing.SystemColors.ControlText; + this.nikseComboBoxEngine.ButtonForeColorDown = System.Drawing.Color.Orange; + this.nikseComboBoxEngine.ButtonForeColorOver = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215))))); + this.nikseComboBoxEngine.DropDownHeight = 400; + this.nikseComboBoxEngine.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDown; + this.nikseComboBoxEngine.DropDownWidth = 391; + this.nikseComboBoxEngine.FormattingEnabled = false; + this.nikseComboBoxEngine.Location = new System.Drawing.Point(17, 40); + this.nikseComboBoxEngine.MaxLength = 32767; + this.nikseComboBoxEngine.Name = "nikseComboBoxEngine"; + this.nikseComboBoxEngine.SelectedIndex = -1; + this.nikseComboBoxEngine.SelectedItem = null; + this.nikseComboBoxEngine.SelectedText = ""; + this.nikseComboBoxEngine.Size = new System.Drawing.Size(351, 23); + this.nikseComboBoxEngine.TabIndex = 5; + this.nikseComboBoxEngine.TabStop = false; + this.nikseComboBoxEngine.Text = "nikseComboBox1"; + this.nikseComboBoxEngine.UsePopupWindow = false; + // // listViewActors // this.listViewActors.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) @@ -243,91 +417,6 @@ this.buttonCancel.UseVisualStyleBackColor = true; this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click); // - // labelVoiceCount - // - this.labelVoiceCount.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.labelVoiceCount.Location = new System.Drawing.Point(268, 98); - this.labelVoiceCount.Name = "labelVoiceCount"; - this.labelVoiceCount.Size = new System.Drawing.Size(100, 23); - this.labelVoiceCount.TabIndex = 29; - this.labelVoiceCount.Text = "255"; - this.labelVoiceCount.TextAlign = System.Drawing.ContentAlignment.BottomRight; - // - // nikseTextBoxApiKey - // - this.nikseTextBoxApiKey.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.nikseTextBoxApiKey.FocusedColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215))))); - this.nikseTextBoxApiKey.Location = new System.Drawing.Point(17, 258); - this.nikseTextBoxApiKey.Name = "nikseTextBoxApiKey"; - this.nikseTextBoxApiKey.Size = new System.Drawing.Size(351, 20); - this.nikseTextBoxApiKey.TabIndex = 27; - // - // TextBoxTest - // - this.TextBoxTest.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.TextBoxTest.FocusedColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215))))); - this.TextBoxTest.Location = new System.Drawing.Point(17, 187); - this.TextBoxTest.Name = "TextBoxTest"; - this.TextBoxTest.Size = new System.Drawing.Size(351, 20); - this.TextBoxTest.TabIndex = 20; - this.TextBoxTest.Text = "Hello, how are you?"; - this.TextBoxTest.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxTest_KeyDown); - // - // nikseComboBoxVoice - // - this.nikseComboBoxVoice.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.nikseComboBoxVoice.BackColor = System.Drawing.SystemColors.Window; - this.nikseComboBoxVoice.BackColorDisabled = System.Drawing.Color.FromArgb(((int)(((byte)(240)))), ((int)(((byte)(240)))), ((int)(((byte)(240))))); - this.nikseComboBoxVoice.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(171)))), ((int)(((byte)(173)))), ((int)(((byte)(179))))); - this.nikseComboBoxVoice.BorderColorDisabled = System.Drawing.Color.FromArgb(((int)(((byte)(120)))), ((int)(((byte)(120)))), ((int)(((byte)(120))))); - this.nikseComboBoxVoice.ButtonForeColor = System.Drawing.SystemColors.ControlText; - this.nikseComboBoxVoice.ButtonForeColorDown = System.Drawing.Color.Orange; - this.nikseComboBoxVoice.ButtonForeColorOver = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215))))); - this.nikseComboBoxVoice.DropDownHeight = 400; - this.nikseComboBoxVoice.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.nikseComboBoxVoice.DropDownWidth = 0; - this.nikseComboBoxVoice.FormattingEnabled = false; - this.nikseComboBoxVoice.Location = new System.Drawing.Point(17, 124); - this.nikseComboBoxVoice.MaxLength = 32767; - this.nikseComboBoxVoice.Name = "nikseComboBoxVoice"; - this.nikseComboBoxVoice.SelectedIndex = -1; - this.nikseComboBoxVoice.SelectedItem = null; - this.nikseComboBoxVoice.SelectedText = ""; - this.nikseComboBoxVoice.Size = new System.Drawing.Size(351, 23); - this.nikseComboBoxVoice.TabIndex = 10; - this.nikseComboBoxVoice.UsePopupWindow = false; - // - // nikseComboBoxEngine - // - this.nikseComboBoxEngine.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.nikseComboBoxEngine.BackColor = System.Drawing.SystemColors.Window; - this.nikseComboBoxEngine.BackColorDisabled = System.Drawing.Color.FromArgb(((int)(((byte)(240)))), ((int)(((byte)(240)))), ((int)(((byte)(240))))); - this.nikseComboBoxEngine.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(171)))), ((int)(((byte)(173)))), ((int)(((byte)(179))))); - this.nikseComboBoxEngine.BorderColorDisabled = System.Drawing.Color.FromArgb(((int)(((byte)(120)))), ((int)(((byte)(120)))), ((int)(((byte)(120))))); - this.nikseComboBoxEngine.ButtonForeColor = System.Drawing.SystemColors.ControlText; - this.nikseComboBoxEngine.ButtonForeColorDown = System.Drawing.Color.Orange; - this.nikseComboBoxEngine.ButtonForeColorOver = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215))))); - this.nikseComboBoxEngine.DropDownHeight = 400; - this.nikseComboBoxEngine.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDown; - this.nikseComboBoxEngine.DropDownWidth = 391; - this.nikseComboBoxEngine.FormattingEnabled = false; - this.nikseComboBoxEngine.Location = new System.Drawing.Point(17, 40); - this.nikseComboBoxEngine.MaxLength = 32767; - this.nikseComboBoxEngine.Name = "nikseComboBoxEngine"; - this.nikseComboBoxEngine.SelectedIndex = -1; - this.nikseComboBoxEngine.SelectedItem = null; - this.nikseComboBoxEngine.SelectedText = ""; - this.nikseComboBoxEngine.Size = new System.Drawing.Size(351, 23); - this.nikseComboBoxEngine.TabIndex = 5; - this.nikseComboBoxEngine.TabStop = false; - this.nikseComboBoxEngine.Text = "nikseComboBox1"; - this.nikseComboBoxEngine.UsePopupWindow = false; - this.nikseComboBoxEngine.SelectedIndexChanged += new System.EventHandler(this.nikseComboBoxEngine_SelectedIndexChanged); - // // TextToSpeech // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -336,13 +425,13 @@ this.Controls.Add(this.buttonCancel); this.Controls.Add(this.labelActors); this.Controls.Add(this.listViewActors); - this.Controls.Add(this.groupBoxMsSettings); + this.Controls.Add(this.groupBoxSettings); this.Controls.Add(this.progressBar1); this.Controls.Add(this.buttonGenerateTTS); this.Controls.Add(this.labelProgress); this.Controls.Add(this.buttonOK); this.KeyPreview = true; - this.MinimumSize = new System.Drawing.Size(827, 481); + this.MinimumSize = new System.Drawing.Size(860, 520); this.Name = "TextToSpeech"; this.ShowIcon = false; this.ShowInTaskbar = false; @@ -354,8 +443,9 @@ this.ResizeEnd += new System.EventHandler(this.TextToSpeech_ResizeEnd); this.SizeChanged += new System.EventHandler(this.TextToSpeech_SizeChanged); this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextToSpeech_KeyDown); - this.groupBoxMsSettings.ResumeLayout(false); - this.groupBoxMsSettings.PerformLayout(); + this.groupBoxSettings.ResumeLayout(false); + this.groupBoxSettings.PerformLayout(); + this.contextMenuStripVoices.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -368,7 +458,7 @@ private System.Windows.Forms.ProgressBar progressBar1; private Controls.NikseComboBox nikseComboBoxEngine; private System.Windows.Forms.Label labelEngine; - private System.Windows.Forms.GroupBox groupBoxMsSettings; + private System.Windows.Forms.GroupBox groupBoxSettings; private System.Windows.Forms.Label labelVoice; private Controls.NikseComboBox nikseComboBoxVoice; private System.Windows.Forms.CheckBox checkBoxAddToVideoFile; @@ -384,5 +474,9 @@ private System.Windows.Forms.CheckBox checkBoxShowPreview; private System.Windows.Forms.Button buttonCancel; private System.Windows.Forms.Label labelVoiceCount; + private System.Windows.Forms.Label labelRegion; + private Controls.NikseComboBox nikseComboBoxRegion; + private System.Windows.Forms.ContextMenuStrip contextMenuStripVoices; + private System.Windows.Forms.ToolStripMenuItem refreshVoicesToolStripMenuItem; } } \ No newline at end of file diff --git a/src/ui/Forms/Tts/TextToSpeech.cs b/src/ui/Forms/Tts/TextToSpeech.cs index 1997a100e..8ddebe2cd 100644 --- a/src/ui/Forms/Tts/TextToSpeech.cs +++ b/src/ui/Forms/Tts/TextToSpeech.cs @@ -33,7 +33,9 @@ namespace Nikse.SubtitleEdit.Forms.Tts private bool _abort; private readonly List _actors; private readonly List _engines; + private readonly List _piperVoices; private readonly List _elevenLabVoices; + private readonly List _azureVoices; private bool _actorsOn; private bool _converting; @@ -65,6 +67,20 @@ namespace Nikse.SubtitleEdit.Forms.Tts } } + public class AzureVoiceModel + { + public string DisplayName { get; set; } + public string LocalName { get; set; } + public string ShortName { get; set; } + public string Gender { get; set; } + public string Locale { get; set; } + + public override string ToString() + { + return $"{Locale} - {DisplayName} ({Gender})"; + } + } + public enum TextToSpeechEngineId { Piper, @@ -72,6 +88,7 @@ namespace Nikse.SubtitleEdit.Forms.Tts Coqui, MsSpeechSynthesizer, ElevenLabs, + AzureTextToSpeech, } public TextToSpeech(Subtitle subtitle, SubtitleFormat subtitleFormat, string videoFileName, VideoInfo videoInfo) @@ -84,7 +101,9 @@ namespace Nikse.SubtitleEdit.Forms.Tts _subtitleFormat = subtitleFormat; _videoFileName = videoFileName; _videoInfo = videoInfo; + _piperVoices = new List(); _elevenLabVoices = new List(); + _azureVoices = new List(); _actors = _subtitle.Paragraphs .Where(p => !string.IsNullOrEmpty(p.Actor)) .Select(p => p.Actor) @@ -92,12 +111,15 @@ namespace Nikse.SubtitleEdit.Forms.Tts .ToList(); Text = LanguageSettings.Current.TextToSpeech.Title; + groupBoxSettings.Text = LanguageSettings.Current.Settings.Title; labelVoice.Text = LanguageSettings.Current.TextToSpeech.Voice; labelApiKey.Text = LanguageSettings.Current.VobSubOcr.ApiKey; buttonTestVoice.Text = LanguageSettings.Current.TextToSpeech.TestVoice; labelActors.Text = LanguageSettings.Current.TextToSpeech.ActorInfo; checkBoxAddToVideoFile.Text = LanguageSettings.Current.TextToSpeech.AddAudioToVideo; buttonGenerateTTS.Text = LanguageSettings.Current.TextToSpeech.GenerateSpeech; + labelRegion.Text = LanguageSettings.Current.General.Region; + checkBoxShowPreview.Text = LanguageSettings.Current.TextToSpeech.ReviewAudioClips; buttonOK.Text = LanguageSettings.Current.General.Ok; buttonCancel.Text = LanguageSettings.Current.General.Cancel; UiUtil.FixLargeFonts(this, buttonOK); @@ -108,13 +130,14 @@ namespace Nikse.SubtitleEdit.Forms.Tts _engines = new List(); _engines.Add(new TextToSpeechEngine(TextToSpeechEngineId.Piper, "Piper (fast/good)", _engines.Count)); - _engines.Add(new TextToSpeechEngine(TextToSpeechEngineId.Tortoise, "Tortoise TTS (very slow/good)", _engines.Count)); + _engines.Add(new TextToSpeechEngine(TextToSpeechEngineId.Tortoise, "Tortoise TTS (slow/good)", _engines.Count)); _engines.Add(new TextToSpeechEngine(TextToSpeechEngineId.Coqui, "Coqui AI TTS (only one voice)", _engines.Count)); if (Configuration.IsRunningOnWindows) { _engines.Add(new TextToSpeechEngine(TextToSpeechEngineId.MsSpeechSynthesizer, "Microsoft SpeechSynthesizer (very fast/robotic)", _engines.Count)); } _engines.Add(new TextToSpeechEngine(TextToSpeechEngineId.ElevenLabs, "ElevenLabs TTS (online/pay/good)", _engines.Count)); + _engines.Add(new TextToSpeechEngine(TextToSpeechEngineId.AzureTextToSpeech, "Microsoft Azure TTS (online/pay/good)", _engines.Count)); _actorAndVoices = new List(); nikseComboBoxEngine.DropDownStyle = ComboBoxStyle.DropDownList; @@ -135,22 +158,25 @@ namespace Nikse.SubtitleEdit.Forms.Tts labelActors.Visible = false; listViewActors.Visible = false; - nikseComboBoxEngine_SelectedIndexChanged(null, null); if (!SubtitleFormatHasActors() || !_actors.Any()) { - var w = groupBoxMsSettings.Width + 100; + var w = groupBoxSettings.Width + 100; var right = buttonCancel.Right; - groupBoxMsSettings.Left = progressBar1.Left; - groupBoxMsSettings.Width = right - progressBar1.Left; - groupBoxMsSettings.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom; + groupBoxSettings.Left = progressBar1.Left; + groupBoxSettings.Width = right - progressBar1.Left; + groupBoxSettings.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom; Width = w; MinimumSize = new Size(w, MinimumSize.Height); Width = w; } + nikseComboBoxEngine_SelectedIndexChanged(null, null); + nikseComboBoxEngine.SelectedIndexChanged += nikseComboBoxEngine_SelectedIndexChanged; nikseComboBoxVoice.Text = Configuration.Settings.Tools.TextToSpeechLastVoice; + checkBoxAddToVideoFile.Checked = Configuration.Settings.Tools.TextToSpeechAddToVideoFile; + checkBoxShowPreview.Checked = Configuration.Settings.Tools.TextToSpeechPreview; } private void SetActor(ActorAndVoice actor) @@ -307,6 +333,12 @@ namespace Nikse.SubtitleEdit.Forms.Tts return result; } + if (engine.Id == TextToSpeechEngineId.AzureTextToSpeech) + { + var result = await GenerateParagraphAudioAzure(subtitle, showProgressBar, overrideFileName); + return result; + } + return false; } @@ -594,7 +626,6 @@ namespace Nikse.SubtitleEdit.Forms.Tts progressBar1.Value = 0; progressBar1.Maximum = subtitle.Paragraphs.Count; progressBar1.Visible = showProgressBar; - var voices = PiperModels.GetVoices(); for (var index = 0; index < subtitle.Paragraphs.Count; index++) { @@ -618,13 +649,13 @@ namespace Nikse.SubtitleEdit.Forms.Tts } } - var voice = voices.First(x => x.ToString() == nikseComboBoxVoice.Text); + var voice = _piperVoices.First(x => x.ToString() == nikseComboBoxVoice.Text); if (_actorAndVoices.Count > 0 && !string.IsNullOrEmpty(p.Actor)) { var f = _actorAndVoices.FirstOrDefault(x => x.Actor == p.Actor); if (f != null && !string.IsNullOrEmpty(f.Voice)) { - voice = voices[f.VoiceIndex]; + voice = _piperVoices[f.VoiceIndex]; } } @@ -900,6 +931,171 @@ namespace Nikse.SubtitleEdit.Forms.Tts return true; } + private async Task> GetAzureVoices(bool useCache) + { + var ttsPath = Path.Combine(Configuration.DataDirectory, "TextToSpeech"); + if (!Directory.Exists(ttsPath)) + { + Directory.CreateDirectory(ttsPath); + } + + var azurePath = Path.Combine(ttsPath, "Azure"); + if (!Directory.Exists(azurePath)) + { + Directory.CreateDirectory(azurePath); + } + + var list = new List(); + var jsonFileName = Path.Combine(azurePath, "AzureVoices.json"); + if (!File.Exists(jsonFileName)) + { + var asm = System.Reflection.Assembly.GetExecutingAssembly(); + var stream = asm.GetManifestResourceStream("Nikse.SubtitleEdit.Resources.AzureVoices.zip"); + if (stream != null) + { + using (var zip = ZipExtractor.Open(stream)) + { + var dir = zip.ReadCentralDir(); + foreach (var entry in dir) + { + var fileName = Path.GetFileName(entry.FilenameInZip); + if (!string.IsNullOrEmpty(fileName)) + { + var name = entry.FilenameInZip; + var path = Path.Combine(azurePath, name.Replace('/', Path.DirectorySeparatorChar)); + zip.ExtractFile(entry, path); + } + } + } + } + } + + if (!useCache) + { + var httpClient = new HttpClient(); + httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json"); + httpClient.DefaultRequestHeaders.TryAddWithoutValidation("accept", "application/json"); + httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Ocp-Apim-Subscription-Key", nikseTextBoxApiKey.Text.Trim()); + + var url = $"https://{nikseComboBoxRegion.Text.Trim()}.tts.speech.microsoft.com/cognitiveservices/voices/list"; + var result = await httpClient.GetAsync(new Uri(url), CancellationToken.None); + var bytes = await result.Content.ReadAsByteArrayAsync(); + + if (!result.IsSuccessStatusCode) + { + Cursor = Cursors.Default; + var error = Encoding.UTF8.GetString(bytes).Trim(); + SeLogger.Error($"Failed getting voices form Azure via url \"{url}\" : Status code={result.StatusCode} {error}"); + MessageBox.Show(this, "Calling url: " + url + Environment.NewLine + "Got error: " + error); + return new List(); + } + + File.WriteAllBytes(jsonFileName, bytes); + } + + var json = File.ReadAllText(jsonFileName); + var parser = new SeJsonParser(); + var arr = parser.GetArrayElements(json); + foreach (var item in arr) + { + var displayName = parser.GetFirstObject(item, "DisplayName"); + var localName = parser.GetFirstObject(item, "LocalName"); + var shortName = parser.GetFirstObject(item, "ShortName"); + var gender = parser.GetFirstObject(item, "Gender"); + var locale = parser.GetFirstObject(item, "Locale"); + + list.Add(new AzureVoiceModel + { + DisplayName = displayName, + LocalName = localName, + ShortName = shortName, + Gender = gender, + Locale = locale, + }); + } + + return list; + } + + private async Task GenerateParagraphAudioAzure(Subtitle subtitle, bool showProgressBar, string overrideFileName) + { + if (string.IsNullOrWhiteSpace(nikseTextBoxApiKey.Text)) + { + MessageBox.Show("Please add API key"); + nikseTextBoxApiKey.Focus(); + return false; + } + + if (string.IsNullOrWhiteSpace(nikseComboBoxRegion.Text)) + { + MessageBox.Show("Please add region"); + nikseComboBoxRegion.Focus(); + return false; + } + + var httpClient = new HttpClient(); + httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "ssml+xml"); + httpClient.DefaultRequestHeaders.TryAddWithoutValidation("accept", "audio/mpeg"); + httpClient.DefaultRequestHeaders.TryAddWithoutValidation("X-Microsoft-OutputFormat", "audio-16khz-32kbitrate-mono-mp3"); + httpClient.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "SubtitleEdit"); + httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Ocp-Apim-Subscription-Key", nikseTextBoxApiKey.Text.Trim()); + + progressBar1.Value = 0; + progressBar1.Maximum = subtitle.Paragraphs.Count; + progressBar1.Visible = showProgressBar; + + var voices = _azureVoices; + var v = nikseComboBoxVoice.Text; + + for (var index = 0; index < subtitle.Paragraphs.Count; index++) + { + if (showProgressBar) + { + progressBar1.Value = index + 1; + labelProgress.Text = string.Format(LanguageSettings.Current.TextToSpeech.GeneratingSpeechFromTextXOfY, index + 1, subtitle.Paragraphs.Count); + } + + var p = subtitle.Paragraphs[index]; + var outputFileName = Path.Combine(_waveFolder, string.IsNullOrEmpty(overrideFileName) ? index + ".mp3" : overrideFileName.Replace(".wav", ".mp3")); + + if (_actorAndVoices.Count > 0 && !string.IsNullOrEmpty(p.Actor)) + { + var f = _actorAndVoices.FirstOrDefault(x => x.Actor == p.Actor); + if (f != null && !string.IsNullOrEmpty(f.Voice)) + { + v = f.Voice; + } + } + + var voice = voices.First(x => x.ToString() == v); + + var url = $"https://{nikseComboBoxRegion.Text.Trim()}.tts.speech.microsoft.com/cognitiveservices/v1"; + var data = $"{System.Net.WebUtility.HtmlEncode(p.Text)}"; + var content = new StringContent(data, Encoding.UTF8); + var result = await httpClient.PostAsync(url, content, CancellationToken.None); + var bytes = await result.Content.ReadAsByteArrayAsync(); + + if (!result.IsSuccessStatusCode) + { + var error = Encoding.UTF8.GetString(bytes).Trim(); + SeLogger.Error($"Azure TTS failed calling API on address {url} : Status code={result.StatusCode} {error}" + Environment.NewLine + "Data=" + data); + MessageBox.Show(this, "Calling url: " + url + Environment.NewLine + "With: " + data + Environment.NewLine + Environment.NewLine + "Error: " + error + result); + return false; + } + + File.WriteAllBytes(outputFileName, bytes); + + progressBar1.Refresh(); + labelProgress.Refresh(); + Application.DoEvents(); + } + + progressBar1.Visible = false; + labelProgress.Text = string.Empty; + + return true; + } + private void buttonOK_Click(object sender, EventArgs e) { EditedSubtitle = _subtitle; @@ -913,6 +1109,8 @@ namespace Nikse.SubtitleEdit.Forms.Tts labelApiKey.Visible = false; nikseTextBoxApiKey.Visible = false; + labelRegion.Visible = false; + nikseComboBoxRegion.Visible = false; labelVoice.Text = LanguageSettings.Current.TextToSpeech.Voice; if (SubtitleFormatHasActors() && _actors.Any()) @@ -937,7 +1135,12 @@ namespace Nikse.SubtitleEdit.Forms.Tts if (engine.Id == TextToSpeechEngineId.Piper) { - foreach (var voice in PiperModels.GetVoices()) + if (_piperVoices.Count == 0) + { + _piperVoices.AddRange(GetPiperVoices(true)); + } + + foreach (var voice in _piperVoices) { nikseComboBoxVoice.Items.Add(voice.ToString()); } @@ -983,7 +1186,7 @@ namespace Nikse.SubtitleEdit.Forms.Tts if (_elevenLabVoices.Count == 0) { - _elevenLabVoices.AddRange(GetElevenLabVoices()); + _elevenLabVoices.AddRange(GetElevenLabVoices(true)); } foreach (var voice in _elevenLabVoices) @@ -992,6 +1195,22 @@ namespace Nikse.SubtitleEdit.Forms.Tts } } + if (engine.Id == TextToSpeechEngineId.AzureTextToSpeech) + { + nikseTextBoxApiKey.Text = Configuration.Settings.Tools.TextToSpeechAzureApiKey; + nikseComboBoxRegion.Text = Configuration.Settings.Tools.TextToSpeechAzureRegion; + + labelApiKey.Visible = true; + nikseTextBoxApiKey.Visible = true; + + var azureVoices = GetAzureVoices(true).Result; + _azureVoices.AddRange(azureVoices); + nikseComboBoxVoice.Items.AddRange(_azureVoices.Select(p => p.ToString()).ToArray()); + + labelRegion.Visible = true; + nikseComboBoxRegion.Visible = true; + } + if (nikseComboBoxVoice.Items.Count > 0) { nikseComboBoxVoice.SelectedIndex = 0; @@ -1025,7 +1244,7 @@ namespace Nikse.SubtitleEdit.Forms.Tts if (engine.Id == TextToSpeechEngineId.Piper) { - var voices = PiperModels.GetVoices(); + var voices = _piperVoices; foreach (var voiceLanguage in voices .GroupBy(p => p.Language) .OrderBy(p => p.Key)) @@ -1062,7 +1281,98 @@ namespace Nikse.SubtitleEdit.Forms.Tts parent.DropDownItems.Add(tsi); } - DarkTheme.SetDarkTheme(parent); + if (Configuration.Settings.General.UseDarkTheme) + { + DarkTheme.SetDarkTheme(parent); + } + } + } + } + if (engine.Id == TextToSpeechEngineId.AzureTextToSpeech) + { + var voices = _azureVoices; + foreach (var voiceLanguage in voices + .GroupBy(p => p.Locale.Substring(0, 2)) + .OrderBy(p => p.Key)) + { + if (voiceLanguage.Count() == 1) + { + var voice = voiceLanguage.First(); + var tsi = new ToolStripMenuItem(); + tsi.Tag = new ActorAndVoice { Voice = voice.ToString(), VoiceIndex = voices.IndexOf(voice) }; + tsi.Text = voice.ToString(); + tsi.Click += (x, args) => + { + var a = (ActorAndVoice)(x as ToolStripItem).Tag; + SetActor(a); + }; + contextMenuStripActors.Items.Add(tsi); + } + else + { + if (voiceLanguage.Count() < 30) + { + var parent = new ToolStripMenuItem(); + parent.Text = voiceLanguage.Key; + contextMenuStripActors.Items.Add(parent); + var tsiList = new List(nikseComboBoxVoice.Items.Count); + foreach (var voice in voiceLanguage.OrderBy(p => p.ToString()).ToList()) + { + var tsi = new ToolStripMenuItem(); + tsi.Tag = new ActorAndVoice { Voice = voice.ToString(), VoiceIndex = voices.IndexOf(voice) }; + tsi.Text = voice.ToString(); + tsi.Click += (x, args) => + { + var a = (ActorAndVoice)(x as ToolStripItem).Tag; + SetActor(a); + }; + tsiList.Add(tsi); + } + parent.DropDownItems.AddRange(tsiList.ToArray()); + + if (Configuration.Settings.General.UseDarkTheme) + { + DarkTheme.SetDarkTheme(parent); + } + } + else + { + var parent = new ToolStripMenuItem(); + parent.Text = voiceLanguage.Key; + contextMenuStripActors.Items.Add(parent); + var subGroup = voiceLanguage.GroupBy(p => p.Locale); + foreach (var subGroupElement in subGroup) + { + var groupParent = new ToolStripMenuItem(); + groupParent.Text = subGroupElement.Key; + parent.DropDownItems.Add(groupParent); + var tsiList = new List(subGroupElement.Count()); + foreach (var voice in subGroupElement.OrderBy(p => p.DisplayName).ToList()) + { + var tsi = new ToolStripMenuItem(); + tsi.Tag = new ActorAndVoice { Voice = voice.ToString(), VoiceIndex = voices.IndexOf(voice) }; + tsi.Text = voice.ToString(); + tsi.Click += (x, args) => + { + var a = (ActorAndVoice)(x as ToolStripItem).Tag; + SetActor(a); + }; + tsiList.Add(tsi); + } + + groupParent.DropDownItems.AddRange(tsiList.ToArray()); + + if (Configuration.Settings.General.UseDarkTheme) + { + DarkTheme.SetDarkTheme(groupParent); + } + + } + if (Configuration.Settings.General.UseDarkTheme) + { + DarkTheme.SetDarkTheme(parent); + } + } } } } @@ -1105,12 +1415,16 @@ namespace Nikse.SubtitleEdit.Forms.Tts parent.DropDownItems.Add(tsi); } - DarkTheme.SetDarkTheme(parent); + if (Configuration.Settings.General.UseDarkTheme) + { + DarkTheme.SetDarkTheme(parent); + } } } } else { + var tsiList = new List(nikseComboBoxVoice.Items.Count); for (var index = 0; index < nikseComboBoxVoice.Items.Count; index++) { var item = nikseComboBoxVoice.Items[index]; @@ -1123,8 +1437,10 @@ namespace Nikse.SubtitleEdit.Forms.Tts var a = (ActorAndVoice)(x as ToolStripItem).Tag; SetActor(a); }; - contextMenuStripActors.Items.Add(tsi); + tsiList.Add(tsi); } + + contextMenuStripActors.Items.AddRange(tsiList.ToArray()); } labelActors.Visible = true; @@ -1134,7 +1450,104 @@ namespace Nikse.SubtitleEdit.Forms.Tts } } - private List GetElevenLabVoices() + private List GetPiperVoices(bool useCache) + { + var ttsPath = Path.Combine(Configuration.DataDirectory, "TextToSpeech"); + if (!Directory.Exists(ttsPath)) + { + Directory.CreateDirectory(ttsPath); + } + + var elevenLabsPath = Path.Combine(ttsPath, "Piper"); + if (!Directory.Exists(elevenLabsPath)) + { + Directory.CreateDirectory(elevenLabsPath); + } + + var result = new List(); + + var jsonFileName = Path.Combine(elevenLabsPath, "voices.json"); + + if (!File.Exists(jsonFileName)) + { + var asm = System.Reflection.Assembly.GetExecutingAssembly(); + var stream = asm.GetManifestResourceStream("Nikse.SubtitleEdit.Resources.PiperVoices.zip"); + if (stream != null) + { + using (var zip = ZipExtractor.Open(stream)) + { + var dir = zip.ReadCentralDir(); + foreach (var entry in dir) + { + var fileName = Path.GetFileName(entry.FilenameInZip); + if (!string.IsNullOrEmpty(fileName)) + { + var name = entry.FilenameInZip; + var path = Path.Combine(elevenLabsPath, name.Replace('/', Path.DirectorySeparatorChar)); + zip.ExtractFile(entry, path); + } + } + } + } + } + + if (!useCache) + { + var httpClient = new HttpClient(); + httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json"); + httpClient.DefaultRequestHeaders.TryAddWithoutValidation("accept", "application/json"); + var url = "https://huggingface.co/rhasspy/piper-voices/resolve/main/voices.json?download=true"; + var res = httpClient.GetAsync(new Uri(url), CancellationToken.None).Result; + var bytes = res.Content.ReadAsByteArrayAsync().Result; + + if (!res.IsSuccessStatusCode) + { + var error = Encoding.UTF8.GetString(bytes).Trim(); + SeLogger.Error($"Failed getting voices form Piper via url \"{url}\" : Status code={res.StatusCode} {error}"); + MessageBox.Show(this, "Calling url: " + url + Environment.NewLine + "Got error: " + error + " " + result); + return result; + } + + File.WriteAllBytes(jsonFileName, bytes); + } + + if (File.Exists(jsonFileName)) + { + var json = File.ReadAllText(jsonFileName); + var parser = new SeJsonParser(); + var arr = parser.GetRootElements(json); + + foreach (var element in arr) + { + var elements = parser.GetRootElements(element.Json); + var name = elements.FirstOrDefault(p => p.Name == "name"); + var quality = elements.FirstOrDefault(p => p.Name == "quality"); + var language = elements.FirstOrDefault(p => p.Name == "language"); + var files = elements.FirstOrDefault(p => p.Name == "files"); + + if (name != null && quality != null && language != null && files != null) + { + var languageDisplay = parser.GetFirstObject(language.Json, "name_english"); + var languageFamily = parser.GetFirstObject(language.Json, "family"); + var languageCode = parser.GetFirstObject(language.Json, "code"); + + var filesElements = parser.GetRootElements(files.Json); + var model = filesElements.FirstOrDefault(p => p.Name.EndsWith(".onnx")); + var config = filesElements.FirstOrDefault(p => p.Name.EndsWith("onnx.json")); + if (model != null && config != null) + { + var modelUrl = "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/" + model.Name; + var configUrl = "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/" + config.Name; + result.Add(new PiperModel(name.Json, languageDisplay, quality.Json, modelUrl, configUrl)); + } + } + } + } + + return result; + } + + private List GetElevenLabVoices(bool useCache) { var ttsPath = Path.Combine(Configuration.DataDirectory, "TextToSpeech"); if (!Directory.Exists(ttsPath)) @@ -1175,6 +1588,33 @@ namespace Nikse.SubtitleEdit.Forms.Tts } } + if (!useCache) + { + var httpClient = new HttpClient(); + httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json"); + httpClient.DefaultRequestHeaders.TryAddWithoutValidation("accept", "application/json"); + + if (!string.IsNullOrWhiteSpace(nikseTextBoxApiKey.Text)) + { + httpClient.DefaultRequestHeaders.TryAddWithoutValidation("xi-api-key", nikseTextBoxApiKey.Text.Trim()); + } + + var url = "https://api.elevenlabs.io/v1/voices"; + var res = httpClient.GetAsync(new Uri(url), CancellationToken.None).Result; + var bytes = res.Content.ReadAsByteArrayAsync().Result; + + if (!res.IsSuccessStatusCode) + { + Cursor = Cursors.Default; + var error = Encoding.UTF8.GetString(bytes).Trim(); + SeLogger.Error($"Failed getting voices form ElevenLabs via url \"{url}\" : Status code={res.StatusCode} {error}"); + MessageBox.Show(this, "Calling url: " + url + Environment.NewLine + "Got error: " + error); + return new List(); + } + + File.WriteAllBytes(jsonFileName, bytes); + } + if (File.Exists(jsonFileName)) { var json = File.ReadAllText(jsonFileName); @@ -1332,9 +1772,16 @@ namespace Nikse.SubtitleEdit.Forms.Tts { Configuration.Settings.Tools.TextToSpeechElevenLabsApiKey = nikseTextBoxApiKey.Text; } + else if (engine.Id == TextToSpeechEngineId.AzureTextToSpeech) + { + Configuration.Settings.Tools.TextToSpeechAzureApiKey = nikseTextBoxApiKey.Text; + Configuration.Settings.Tools.TextToSpeechAzureRegion = nikseComboBoxRegion.Text; + } Configuration.Settings.Tools.TextToSpeechEngine = engine.Id.ToString(); Configuration.Settings.Tools.TextToSpeechLastVoice = nikseComboBoxVoice.Text; + Configuration.Settings.Tools.TextToSpeechAddToVideoFile = checkBoxAddToVideoFile.Checked; + Configuration.Settings.Tools.TextToSpeechPreview = checkBoxShowPreview.Checked; } private void TextToSpeech_KeyDown(object sender, KeyEventArgs e) @@ -1356,21 +1803,26 @@ namespace Nikse.SubtitleEdit.Forms.Tts public string GetParagraphAudio(Paragraph paragraph) { - if (_actorsOn) + if (_actorsOn && _actorAndVoices.Count > 0 && !string.IsNullOrEmpty(paragraph.Actor)) { - var engine = _engines.First(p => p.Index == nikseComboBoxEngine.SelectedIndex); - - if (engine.Id == TextToSpeechEngineId.Piper) + var f = _actorAndVoices.FirstOrDefault(x => x.Actor == paragraph.Actor); + if (f != null && !string.IsNullOrEmpty(f.Voice)) { - var voices = PiperModels.GetVoices(); - var voice = voices.First(x => x.ToString() == nikseComboBoxVoice.Text); - if (_actorAndVoices.Count > 0 && !string.IsNullOrEmpty(paragraph.Actor)) + var engine = _engines.First(p => p.Index == nikseComboBoxEngine.SelectedIndex); + + if (engine.Id == TextToSpeechEngineId.Piper) { - var f = _actorAndVoices.FirstOrDefault(x => x.Actor == paragraph.Actor); - if (f != null && !string.IsNullOrEmpty(f.Voice)) - { - return voices[f.VoiceIndex].Voice; - } + return _piperVoices[f.VoiceIndex].ToString(); + } + + if (engine.Id == TextToSpeechEngineId.AzureTextToSpeech) + { + return _azureVoices[f.VoiceIndex].ToString(); + } + + if (engine.Id == TextToSpeechEngineId.ElevenLabs) + { + return _elevenLabVoices[f.VoiceIndex].ToString(); } } } @@ -1405,5 +1857,79 @@ namespace Nikse.SubtitleEdit.Forms.Tts nikseComboBoxEngine.DropDownWidth = nikseComboBoxEngine.Width; nikseComboBoxVoice.DropDownWidth = nikseComboBoxVoice.Width; } + + private void RefreshVoices() + { + if (nikseTextBoxApiKey.Visible && string.IsNullOrWhiteSpace(nikseTextBoxApiKey.Text)) + { + Cursor = Cursors.Default; + MessageBox.Show("Please add API key"); + nikseTextBoxApiKey.Focus(); + return; + } + + var engine = _engines.First(p => p.Index == nikseComboBoxEngine.SelectedIndex); + if (engine.Id == TextToSpeechEngineId.AzureTextToSpeech) + { + if (string.IsNullOrWhiteSpace(nikseComboBoxRegion.Text)) + { + Cursor = Cursors.Default; + MessageBox.Show("Please add region"); + nikseComboBoxRegion.Focus(); + return; + } + + var _ = GetAzureVoices(false).Result; + nikseComboBoxEngine_SelectedIndexChanged(null, null); + } + else if (engine.Id == TextToSpeechEngineId.ElevenLabs) + { + GetElevenLabVoices(false); + nikseComboBoxEngine_SelectedIndexChanged(null, null); + } + } + + private void contextMenuStripVoices_Opening(object sender, System.ComponentModel.CancelEventArgs e) + { + var engine = _engines.First(p => p.Index == nikseComboBoxEngine.SelectedIndex); + if ( + //engine.Id == TextToSpeechEngineId.AzureTextToSpeech || + engine.Id == TextToSpeechEngineId.ElevenLabs || + engine.Id == TextToSpeechEngineId.Piper + ) + { + return; + } + + e.Cancel = true; + } + + private void refreshVoicesToolStripMenuItem_Click(object sender, EventArgs e) + { + var dr = MessageBox.Show(this, "Download updated voice list from the internet?", "Update voices", MessageBoxButtons.YesNoCancel); + if (dr != DialogResult.Yes) + { + return; + } + + try + { + Cursor = Cursors.WaitCursor; + RefreshVoices(); + Cursor = Cursors.Default; + MessageBox.Show(this, "Voice list downloaded"); + } + catch (Exception ex) + { + Cursor = Cursors.Default; + MessageBox.Show(this, "Voice list download failed!" + Environment.NewLine + + Environment.NewLine + + ex.Message); + } + finally + { + Cursor = Cursors.Default; + } + } } } \ No newline at end of file diff --git a/src/ui/Forms/Tts/TextToSpeech.resx b/src/ui/Forms/Tts/TextToSpeech.resx index dec39f79f..78a54a51c 100644 --- a/src/ui/Forms/Tts/TextToSpeech.resx +++ b/src/ui/Forms/Tts/TextToSpeech.resx @@ -117,6 +117,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 200, 17 + 17, 17 diff --git a/src/ui/Forms/VTT/WebVttImportExport.cs b/src/ui/Forms/VTT/WebVttImportExport.cs index 3868abfa5..6b4d49cd9 100644 --- a/src/ui/Forms/VTT/WebVttImportExport.cs +++ b/src/ui/Forms/VTT/WebVttImportExport.cs @@ -145,18 +145,12 @@ namespace Nikse.SubtitleEdit.Forms.VTT private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewExportStyles.Items) - { - item.Checked = true; - } + listViewExportStyles.CheckAll(); } private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewExportStyles.Items) - { - item.Checked = !item.Checked; - } + listViewExportStyles.InvertCheck(); } } } diff --git a/src/ui/Forms/VTT/WebVttStylePicker.cs b/src/ui/Forms/VTT/WebVttStylePicker.cs index 43eead8b8..31319e4e4 100644 --- a/src/ui/Forms/VTT/WebVttStylePicker.cs +++ b/src/ui/Forms/VTT/WebVttStylePicker.cs @@ -57,18 +57,12 @@ namespace Nikse.SubtitleEdit.Forms.VTT private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewExportStyles.Items) - { - item.Checked = true; - } + listViewExportStyles.CheckAll(); } private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) { - foreach (ListViewItem item in listViewExportStyles.Items) - { - item.Checked = !item.Checked; - } + listViewExportStyles.InvertCheck(); } private void listViewExportStyles_SelectedIndexChanged(object sender, EventArgs e) diff --git a/src/ui/Languages/da-DK.xml b/src/ui/Languages/da-DK.xml index c6dc45b86..7f0086787 100644 --- a/src/ui/Languages/da-DK.xml +++ b/src/ui/Languages/da-DK.xml @@ -1447,6 +1447,7 @@ Go to "Indstillinger -> Indstillinger -> Værktøj" for at indtaste din Bi Fjern/eksporter sceneændringer... Batch generer bølgeformer... Vis/skjul bølgeform og spektrogram + Tekst til tale og føj til video... Pop video vinduer ud Saml video vinduer @@ -2120,6 +2121,8 @@ Hvis du har redigeret denne fil med Subtitle Edit du måske finde en backup via Lige linjer Varighed mindre end Varighed større end + CPS mindre end + CPS større end Præcis én linje Præcis to linjer Mere end to linjer @@ -3146,6 +3149,23 @@ Fortsæt? Et synkronisering punkt vil justere positioner, to eller flere synkroniserings punkter vil justere position og hastighed Anvend + + Tekst til tale + Stemme + Test stemme + Standardstemme + Tilføj lyd til videofil (ny fil) + Generer tale fra tekst + Højreklik for at tildele skuespiller til stemme + Justerer hastighed: {0} / {1}... + Samler lydspor: {0} / {1}... + Genererer tale fra tekst: {0} / {1}... + Gennemgå lydklip + Gennemgå og rediger/fjern lydklip + Spil + Auto-fortsæt + Regenerer + SMPTE timing Vil du bruge SMPTE-timing til aktuelle undertekster? diff --git a/src/ui/Languages/it-IT.xml b/src/ui/Languages/it-IT.xml index c8d5edbfb..061f7507d 100644 --- a/src/ui/Languages/it-IT.xml +++ b/src/ui/Languages/it-IT.xml @@ -3,7 +3,7 @@ Subtitle Edit 4.0.5 - Tradotto da NAMP e bovirus - Data traduzione: 15.04.2024 + Tradotto da NAMP e bovirus - Data traduzione: 29.04.2024 it-IT OK @@ -1610,6 +1610,7 @@ Per usare una chiave API inserisci la chiave API di traduzione di Google in "Opz Vista sorgente Vista elenco Estrai audio... + Info media @@ -2129,6 +2130,8 @@ Vuoi scaricare mpv e youtuibe-dl e continuare? Righe uguali Durata inferiore a Durata maggiore di + CPS inferiore a + CPS superiore a Esattamente una linea Esattamente due linee Più di due righe @@ -3166,6 +3169,11 @@ Vuoi continuare? Regolazione velocità: {0} / {1}... Unione traccia audio: {0} / {1}... Generazione parlato dal testo: {0} / {1}... + Rivedi clip audio + Rivedi e modifica/rimuovi clip audio + Riproduci + Continua automaticamente + Rigenera Tempistica SMPTE diff --git a/src/ui/Languages/sv-SE.xml b/src/ui/Languages/sv-SE.xml index cbecb4dbb..1eb18102c 100644 --- a/src/ui/Languages/sv-SE.xml +++ b/src/ui/Languages/sv-SE.xml @@ -1453,6 +1453,7 @@ Gå till "Alternativ -> Inställningar -> Verktyg" för att ange din nycke Ta bort/exportera bildändringar... Batch genererar vågformdata... Visa/dölj ljudformat och spektrogram + Text till tal och lägg till video... Avdocka videokontrollerna Docka videokontrollerna @@ -2129,6 +2130,8 @@ Ladda ner och fortsätta? Jämna radnummer Varaktighet kortare än Varaktighet längre än + CPS mindre än + CPS större än Exakt en rad Exakt två rader Mer än två rader @@ -3156,6 +3159,23 @@ och N bryter En synkpunkt kommer att justera positionen. två eller flera synkroniseringspunkter kommer att justera position och hastighet Verkställ + + Text till tal + Röst + Testa röst + Standardröst + Lägg till ljud till videofil (ny fil) + Generera tal från text + Högerklicka för att tilldela skådespelare till röst + Justerar hastighet: {0} / {1}... + Slår ihop ljudspår: {0} / {1}... + Genererar tal från text: {0} / {1}... + Granska ljudklipp + Granska och redigera/ta bort ljudklipp + Spela + Auto-fortsätt + Regenerera + SMPTE-timing Använd SMPTE-timing för aktuell undertext? diff --git a/src/ui/Languages/zh-Hans.xml b/src/ui/Languages/zh-Hans.xml index dab37c52d..f34ea786d 100644 --- a/src/ui/Languages/zh-Hans.xml +++ b/src/ui/Languages/zh-Hans.xml @@ -2117,6 +2117,8 @@ Command line: {1} {2} 匹配行 时长小于 时长大于 + CPS 小于 + CP S大于 正好一行 正好两行 超过两行 diff --git a/src/ui/Logic/Language.cs b/src/ui/Logic/Language.cs index 44da8cc9c..c551a1b43 100644 --- a/src/ui/Logic/Language.cs +++ b/src/ui/Logic/Language.cs @@ -2210,6 +2210,7 @@ namespace Nikse.SubtitleEdit.Logic GoToSourceView = "Go to source view", GoToListView = "Go to list view", ExtractAudio = "Extract audio...", + MediaInfo = "Media information", } }, @@ -2461,6 +2462,8 @@ namespace Nikse.SubtitleEdit.Logic EvenLines = "Even-numbered lines", DurationLessThan = "Duration less than", DurationGreaterThan = "Duration greater than", + CpsLessThan = "CPS less than", + CpsGreaterThan = "CPS greater than", ExactlyOneLine = "Exactly one line", ExactlyTwoLines = "Exactly two lines", MoreThanTwoLines = "More than two lines", @@ -3563,6 +3566,11 @@ can edit in same subtitle file (collaboration)", AdjustingSpeedXOfY = "Adjusting speed: {0} / {1}...", MergingAudioTrackXOfY = "Merging audio track: {0} / {1}...", GeneratingSpeechFromTextXOfY = "Generating speech from text: {0} / {1}...", + ReviewAudioClips = "Review audio clips", + ReviewInfo = "Review and edit/remove audio clips", + AutoContinue = "Auto-continue", + Play = "Play", + Regenerate = "Regenerate", }; TimedTextSmpteTiming = new LanguageStructure.TimedTextSmpteTiming diff --git a/src/ui/Logic/LanguageDeserializer.cs b/src/ui/Logic/LanguageDeserializer.cs index 643f3c6d8..3da9a72ab 100644 --- a/src/ui/Logic/LanguageDeserializer.cs +++ b/src/ui/Logic/LanguageDeserializer.cs @@ -5170,6 +5170,9 @@ namespace Nikse.SubtitleEdit.Logic case "Main/Menu/ContextMenu/ExtractAudio": language.Main.Menu.ContextMenu.ExtractAudio = reader.Value; break; + case "Main/Menu/ContextMenu/MediaInfo": + language.Main.Menu.ContextMenu.MediaInfo = reader.Value; + break; case "Main/Controls/SubtitleFormat": language.Main.Controls.SubtitleFormat = reader.Value; break; @@ -5770,6 +5773,12 @@ namespace Nikse.SubtitleEdit.Logic case "ModifySelection/DurationGreaterThan": language.ModifySelection.DurationGreaterThan = reader.Value; break; + case "ModifySelection/CpsLessThan": + language.ModifySelection.CpsLessThan = reader.Value; + break; + case "ModifySelection/CpsGreaterThan": + language.ModifySelection.CpsGreaterThan = reader.Value; + break; case "ModifySelection/ExactlyOneLine": language.ModifySelection.ExactlyOneLine = reader.Value; break; @@ -8671,6 +8680,21 @@ namespace Nikse.SubtitleEdit.Logic case "TextToSpeech/GeneratingSpeechFromTextXOfY": language.TextToSpeech.GeneratingSpeechFromTextXOfY = reader.Value; break; + case "TextToSpeech/ReviewAudioClips": + language.TextToSpeech.ReviewAudioClips = reader.Value; + break; + case "TextToSpeech/ReviewInfo": + language.TextToSpeech.ReviewInfo = reader.Value; + break; + case "TextToSpeech/Play": + language.TextToSpeech.Play = reader.Value; + break; + case "TextToSpeech/AutoContinue": + language.TextToSpeech.AutoContinue = reader.Value; + break; + case "TextToSpeech/Regenerate": + language.TextToSpeech.Regenerate = reader.Value; + break; case "TimedTextSmpteTiming/Title": language.TimedTextSmpteTiming.Title = reader.Value; break; diff --git a/src/ui/Logic/LanguageStructure.cs b/src/ui/Logic/LanguageStructure.cs index 4a7e81594..a336bac1b 100644 --- a/src/ui/Logic/LanguageStructure.cs +++ b/src/ui/Logic/LanguageStructure.cs @@ -2015,6 +2015,7 @@ public string GoToSourceView { get; set; } public string GoToListView { get; set; } public string ExtractAudio { get; set; } + public string MediaInfo { get; set; } } public FileMenu File { get; set; } @@ -2271,6 +2272,8 @@ public string EvenLines { get; set; } public string DurationLessThan { get; set; } public string DurationGreaterThan { get; set; } + public string CpsLessThan { get; set; } + public string CpsGreaterThan { get; set; } public string ExactlyOneLine { get; set; } public string ExactlyTwoLines { get; set; } public string MoreThanTwoLines { get; set; } @@ -3372,6 +3375,11 @@ public string AdjustingSpeedXOfY { get; set; } public string MergingAudioTrackXOfY { get; set; } public string GeneratingSpeechFromTextXOfY { get; set; } + public string ReviewAudioClips { get; set; } + public string ReviewInfo { get; set; } + public string Play { get; set; } + public string AutoContinue { get; set; } + public string Regenerate { get; set; } } public class TimedTextSmpteTiming diff --git a/src/ui/Logic/ListViewSorter.cs b/src/ui/Logic/ListViewSorter.cs index f9c2a8a92..21916d47a 100644 --- a/src/ui/Logic/ListViewSorter.cs +++ b/src/ui/Logic/ListViewSorter.cs @@ -13,7 +13,8 @@ namespace Nikse.SubtitleEdit.Logic public bool IsDisplayFileSize { get; set; } public bool Descending { get; set; } - private Regex _invariantNumber = new Regex(@"\d+\.{1,2}", RegexOptions.Compiled); + private static readonly Regex Numbers = new Regex(@"\d+", RegexOptions.Compiled); + private static readonly Regex InvariantNumber = new Regex(@"\d+\.{1,2}", RegexOptions.Compiled); public int Compare(object o1, object o2) { @@ -32,7 +33,7 @@ namespace Nikse.SubtitleEdit.Logic var s1 = lvi1.SubItems[ColumnNumber].Text; var s2 = lvi2.SubItems[ColumnNumber].Text; - if (_invariantNumber.IsMatch(s1) && _invariantNumber.IsMatch(s2) && + if (InvariantNumber.IsMatch(s1) && InvariantNumber.IsMatch(s2) && int.TryParse(s1, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var i1) && int.TryParse(s2, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var i2)) { @@ -53,7 +54,35 @@ namespace Nikse.SubtitleEdit.Logic return i1 > i2 ? 1 : i1 == i2 ? 0 : -1; } - return string.Compare(lvi2.SubItems[ColumnNumber].Text, lvi1.SubItems[ColumnNumber].Text, StringComparison.Ordinal); + return NaturalComparer(lvi2.SubItems[ColumnNumber].Text, lvi1.SubItems[ColumnNumber].Text); + } + + public static void SetSortArrow(ColumnHeader columnHeader, SortOrder sortOrder) + { + const string ascArrow = " ▲"; + const string descArrow = " ▼"; + + if (columnHeader.Text.EndsWith(ascArrow) || columnHeader.Text.EndsWith(descArrow)) + { + columnHeader.Text = columnHeader.Text.Substring(0, columnHeader.Text.Length - 2); + } + + switch (sortOrder) + { + case SortOrder.Ascending: + columnHeader.Text += ascArrow; + break; + case SortOrder.Descending: + columnHeader.Text += descArrow; + break; + } + } + + public static int NaturalComparer(string x, string y) + { + var str2 = Numbers.Replace(x, m => m.Value.PadLeft(10, '0')).RemoveChar(' '); + var str1 = Numbers.Replace(y, m => m.Value.PadLeft(10, '0')).RemoveChar(' '); + return string.Compare(str2, str1, StringComparison.OrdinalIgnoreCase); } } } diff --git a/src/ui/Logic/UiUtil.cs b/src/ui/Logic/UiUtil.cs index 9155a4e07..7f978693c 100644 --- a/src/ui/Logic/UiUtil.cs +++ b/src/ui/Logic/UiUtil.cs @@ -1121,6 +1121,36 @@ namespace Nikse.SubtitleEdit.Logic public static void AutoSizeLastColumn(this ListView listView) => listView.Columns[listView.Columns.Count - 1].Width = -2; + public static void CheckAll(this ListView lv) + { + lv.BeginUpdate(); + foreach (ListViewItem item in lv.Items) + { + item.Checked = true; + } + lv.EndUpdate(); + } + + public static void InvertCheck(this ListView lv) + { + lv.BeginUpdate(); + foreach (ListViewItem item in lv.Items) + { + item.Checked = !item.Checked; + } + lv.EndUpdate(); + } + + public static void UncheckAll(this ListView lv) + { + lv.BeginUpdate(); + foreach (ListViewItem item in lv.Items) + { + item.Checked = false; + } + lv.EndUpdate(); + } + public static void SelectAll(this ListView lv) { lv.BeginUpdate(); diff --git a/src/ui/Logic/VideoPreviewGenerator.cs b/src/ui/Logic/VideoPreviewGenerator.cs index 00cadb04c..d24160279 100644 --- a/src/ui/Logic/VideoPreviewGenerator.cs +++ b/src/ui/Logic/VideoPreviewGenerator.cs @@ -271,7 +271,7 @@ namespace Nikse.SubtitleEdit.Logic StartInfo = { FileName = GetFfmpegLocation(), - Arguments = $"{cutStart}-i \"{inputVideoFileName}\"{cutEnd}-vf \"ass={Path.GetFileName(assaSubtitleFileName)}\",yadif,format=yuv420p -g 30 -bf 2 -s {width}x{height} {videoEncodingSettings} {passSettings} {presetSettings} {crfSettings} {audioSettings}{tuneParameter} -use_editlist 0 -movflags +faststart {outputVideoFileName}".TrimStart(), + Arguments = $"{cutStart}-i \"{inputVideoFileName}\"{cutEnd} -vf scale={width}:{height} -vf \"ass={Path.GetFileName(assaSubtitleFileName)}\",yadif,format=yuv420p -g 30 -bf 2 -s {width}x{height} {videoEncodingSettings} {passSettings} {presetSettings} {crfSettings} {audioSettings}{tuneParameter} -use_editlist 0 -movflags +faststart {outputVideoFileName}".TrimStart(), UseShellExecute = false, CreateNoWindow = true, WorkingDirectory = Path.GetDirectoryName(assaSubtitleFileName) ?? string.Empty, diff --git a/src/ui/Resources/AzureVoices.zip b/src/ui/Resources/AzureVoices.zip new file mode 100644 index 000000000..70b9ac9fa Binary files /dev/null and b/src/ui/Resources/AzureVoices.zip differ diff --git a/src/ui/Resources/PiperVoices.zip b/src/ui/Resources/PiperVoices.zip new file mode 100644 index 000000000..d5e4478e8 Binary files /dev/null and b/src/ui/Resources/PiperVoices.zip differ diff --git a/src/ui/SubtitleEdit.csproj b/src/ui/SubtitleEdit.csproj index d8eb752d0..b537a0b4d 100644 --- a/src/ui/SubtitleEdit.csproj +++ b/src/ui/SubtitleEdit.csproj @@ -2454,7 +2454,9 @@ + + Designer