This commit is contained in:
niksedk 2024-04-30 07:00:30 +02:00
commit 56205e4222
61 changed files with 3055 additions and 1060 deletions

View File

@ -4,6 +4,9 @@
* NEW: * NEW:
* Add "Text To Speech" - thx darnn/cvrle77/msjsc001 * Add "Text To Speech" - thx darnn/cvrle77/msjsc001
* Add burn-in batch mode - thx Leon/David * 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: * IMPROVED:
* Update Portuguese translation - thx hugok79 * Update Portuguese translation - thx hugok79
* Update Bulgarian translation - thx Калин * Update Bulgarian translation - thx Калин
@ -20,6 +23,8 @@
* Fix possible crash in teletext reading - thx yellobyte * Fix possible crash in teletext reading - thx yellobyte
* Fix unwanted text boxes background color change - thx Leon * Fix unwanted text boxes background color change - thx Leon
* Fix Whisper on selection in waveform in "translation mode" - thx rRobis * 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) 4.0.5 (13th April 2024)

View File

@ -417,6 +417,7 @@
<Word from="drugare" to="prijatelje" /> <Word from="drugare" to="prijatelje" />
<Word from="drugafije" to="drugačije" /> <Word from="drugafije" to="drugačije" />
<Word from="drugčiji" to="drugačiji" /> <Word from="drugčiji" to="drugačiji" />
<Word from="Drugde" to="Drugdje" />
<Word from="drugde" to="drugdje" /> <Word from="drugde" to="drugdje" />
<Word from="druze" to="druže" /> <Word from="druze" to="druže" />
<Word from="drvoseča" to="drvosječa" /> <Word from="drvoseča" to="drvosječa" />
@ -2041,6 +2042,8 @@
<Word from="razumeju" to="razumiju" /> <Word from="razumeju" to="razumiju" />
<Word from="Razumeju" to="Razumiju" /> <Word from="Razumeju" to="Razumiju" />
<Word from="razumijeti" to="razumjeti" /> <Word from="razumijeti" to="razumjeti" />
<Word from="Razneću" to="Raznijet ću" />
<Word from="razneću" to="raznijet ću" />
<Word from="recitujte" to="recitirajte" /> <Word from="recitujte" to="recitirajte" />
<Word from="recitujem" to="recitiram" /> <Word from="recitujem" to="recitiram" />
<Word from="recituje" to="recitira" /> <Word from="recituje" to="recitira" />
@ -4055,6 +4058,7 @@
<LinePart from="možeš da dobiješ" to="možeš dobiti" /> <LinePart from="možeš da dobiješ" to="možeš dobiti" />
<LinePart from="možeš da dođeš" to="možeš doći" /> <LinePart from="možeš da dođeš" to="možeš doći" />
<LinePart from="može da uđe" to="može ući" /> <LinePart from="može da uđe" to="može ući" />
<LinePart from="može da ide" to="može ići" />
<LinePart from="možeš da imaš" to="možeš imati" /> <LinePart from="možeš da imaš" to="možeš imati" />
<LinePart from="možeš da odeš" to="možeš otići" /> <LinePart from="možeš da odeš" to="možeš otići" />
<LinePart from="možeš da uđeš" to="možeš ući" /> <LinePart from="možeš da uđeš" to="možeš ući" />

View File

@ -1610,6 +1610,7 @@ To use an API key, go to "Options -&gt; Settings -&gt; Auto-translate" to enter
<GoToSourceView>Go to source view</GoToSourceView> <GoToSourceView>Go to source view</GoToSourceView>
<GoToListView>Go to list view</GoToListView> <GoToListView>Go to list view</GoToListView>
<ExtractAudio>Extract audio...</ExtractAudio> <ExtractAudio>Extract audio...</ExtractAudio>
<MediaInfo>Media information</MediaInfo>
</ContextMenu> </ContextMenu>
</Menu> </Menu>
<Controls> <Controls>
@ -2129,6 +2130,8 @@ Download and continue?</VideoFromUrlRequirements>
<EvenLines>Even-numbered lines</EvenLines> <EvenLines>Even-numbered lines</EvenLines>
<DurationLessThan>Duration less than</DurationLessThan> <DurationLessThan>Duration less than</DurationLessThan>
<DurationGreaterThan>Duration greater than</DurationGreaterThan> <DurationGreaterThan>Duration greater than</DurationGreaterThan>
<CpsLessThan>CPS less than</CpsLessThan>
<CpsGreaterThan>CPS greater than</CpsGreaterThan>
<ExactlyOneLine>Exactly one line</ExactlyOneLine> <ExactlyOneLine>Exactly one line</ExactlyOneLine>
<ExactlyTwoLines>Exactly two lines</ExactlyTwoLines> <ExactlyTwoLines>Exactly two lines</ExactlyTwoLines>
<MoreThanTwoLines>More than two lines</MoreThanTwoLines> <MoreThanTwoLines>More than two lines</MoreThanTwoLines>
@ -3166,6 +3169,11 @@ Continue?</RestoreDefaultSettingsMsg>
<AdjustingSpeedXOfY>Adjusting speed: {0} / {1}...</AdjustingSpeedXOfY> <AdjustingSpeedXOfY>Adjusting speed: {0} / {1}...</AdjustingSpeedXOfY>
<MergingAudioTrackXOfY>Merging audio track: {0} / {1}...</MergingAudioTrackXOfY> <MergingAudioTrackXOfY>Merging audio track: {0} / {1}...</MergingAudioTrackXOfY>
<GeneratingSpeechFromTextXOfY>Generating speech from text: {0} / {1}...</GeneratingSpeechFromTextXOfY> <GeneratingSpeechFromTextXOfY>Generating speech from text: {0} / {1}...</GeneratingSpeechFromTextXOfY>
<ReviewAudioClips>Review audio clips</ReviewAudioClips>
<ReviewInfo>Review and edit/remove audio clips</ReviewInfo>
<Play>Play</Play>
<AutoContinue>Auto-continue</AutoContinue>
<Regenerate>Regenerate</Regenerate>
</TextToSpeech> </TextToSpeech>
<TimedTextSmpteTiming> <TimedTextSmpteTiming>
<Title>SMPTE timing</Title> <Title>SMPTE timing</Title>

View File

@ -1,4 +1,4 @@
#!bin/bash #!/bin/bash
function ShowHelp() function ShowHelp()
{ {

View File

@ -192,5 +192,50 @@ namespace Test.Core
}".Replace('\'', '"'), "items"); }".Replace('\'', '"'), "items");
Assert.AreEqual(4, result.Count); 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);
}
} }
} }

View File

@ -4,12 +4,17 @@ using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
namespace Nikse.SubtitleEdit.Core.Common namespace Nikse.SubtitleEdit.Core.Common
{ {
public class FfmpegMediaInfo public class FfmpegMediaInfo
{ {
public List<FfmpegTrackInfo> Tracks { get; set; } public List<FfmpegTrackInfo> 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() private FfmpegMediaInfo()
{ {
@ -56,6 +61,20 @@ namespace Nikse.SubtitleEdit.Core.Common
var s = line.Trim(); var s = line.Trim();
if (s.StartsWith("Stream #", StringComparison.Ordinal)) 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('¤'); var arr = s.Replace(": ", "¤").Split('¤');
if (arr.Length == 3) if (arr.Length == 3)
{ {

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using Nikse.SubtitleEdit.Core.ContainerFormats.Ebml;
using System.Collections.Generic;
using System.Text; using System.Text;
namespace Nikse.SubtitleEdit.Core.Common namespace Nikse.SubtitleEdit.Core.Common
@ -1300,5 +1301,389 @@ namespace Nikse.SubtitleEdit.Core.Common
} }
return string.Empty; return string.Empty;
} }
public class RootElement
{
public string Name { get; set; }
public string Json { get; set; }
}
public List<RootElement> GetRootElements(string content)
{
Errors = new List<string>();
var list = new List<RootElement>();
var i = 0;
var max = content.Length;
var state = new Stack<StateElement>();
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;
}
} }
} }

View File

@ -193,7 +193,10 @@ namespace Nikse.SubtitleEdit.Core.Common
public string TextToSpeechEngine { get; set; } public string TextToSpeechEngine { get; set; }
public string TextToSpeechLastVoice { get; set; } public string TextToSpeechLastVoice { get; set; }
public string TextToSpeechElevenLabsApiKey { 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 ListViewSyntaxColorDurationSmall { get; set; }
public bool ListViewSyntaxColorDurationBig { get; set; } public bool ListViewSyntaxColorDurationBig { get; set; }
public bool ListViewSyntaxColorOverlap { get; set; } public bool ListViewSyntaxColorOverlap { get; set; }
@ -557,6 +560,8 @@ namespace Nikse.SubtitleEdit.Core.Common
AnthropicApiUrl = "https://api.anthropic.com/v1/messages"; 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:"; 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"; AnthropicApiModel = "claude-3-opus-20240229";
TextToSpeechAzureRegion = "westeurope";
TextToSpeechAddToVideoFile = true;
TranslateAllowSplit = true; TranslateAllowSplit = true;
TranslateViaCopyPasteAutoCopyToClipboard = true; TranslateViaCopyPasteAutoCopyToClipboard = true;
TranslateViaCopyPasteMaxSize = 5000; TranslateViaCopyPasteMaxSize = 5000;
@ -5481,16 +5486,34 @@ $HorzAlign = Center
settings.Tools.TextToSpeechElevenLabsApiKey = subNode.InnerText; 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"); subNode = node.SelectSingleNode("TranslateViaCopyPasteAutoCopyToClipboard");
if (subNode != null) if (subNode != null)
{ {
settings.Tools.TranslateViaCopyPasteAutoCopyToClipboard = Convert.ToBoolean(subNode.InnerText, CultureInfo.InvariantCulture); settings.Tools.TranslateViaCopyPasteAutoCopyToClipboard = Convert.ToBoolean(subNode.InnerText, CultureInfo.InvariantCulture);
} }
subNode = node.SelectSingleNode("DisableVidoInfoViaLabel"); subNode = node.SelectSingleNode("TextToSpeechPreview");
if (subNode != null) 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"); subNode = node.SelectSingleNode("ListViewSyntaxColorDurationSmall");
@ -12023,7 +12046,10 @@ $HorzAlign = Center
textWriter.WriteElementString("TextToSpeechEngine", settings.Tools.TextToSpeechEngine); textWriter.WriteElementString("TextToSpeechEngine", settings.Tools.TextToSpeechEngine);
textWriter.WriteElementString("TextToSpeechLastVoice", settings.Tools.TextToSpeechLastVoice); textWriter.WriteElementString("TextToSpeechLastVoice", settings.Tools.TextToSpeechLastVoice);
textWriter.WriteElementString("TextToSpeechElevenLabsApiKey", settings.Tools.TextToSpeechElevenLabsApiKey); 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("ListViewSyntaxColorDurationSmall", settings.Tools.ListViewSyntaxColorDurationSmall.ToString(CultureInfo.InvariantCulture));
textWriter.WriteElementString("ListViewSyntaxColorDurationBig", settings.Tools.ListViewSyntaxColorDurationBig.ToString(CultureInfo.InvariantCulture)); textWriter.WriteElementString("ListViewSyntaxColorDurationBig", settings.Tools.ListViewSyntaxColorDurationBig.ToString(CultureInfo.InvariantCulture));
textWriter.WriteElementString("ListViewSyntaxColorLongLines", settings.Tools.ListViewSyntaxColorLongLines.ToString(CultureInfo.InvariantCulture)); textWriter.WriteElementString("ListViewSyntaxColorLongLines", settings.Tools.ListViewSyntaxColorLongLines.ToString(CultureInfo.InvariantCulture));

View File

@ -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
{
/// <summary>
/// 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'']
/// </summary>
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<string> 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<string> 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;
}
}
}

View File

@ -154,6 +154,7 @@ namespace Nikse.SubtitleEdit.Core.SubtitleFormats
new KanopyHtml(), new KanopyHtml(),
new LambdaCap(), new LambdaCap(),
new Lrc(), new Lrc(),
new Lrc3DigitsMs(),
new LrcNoEndTime(), new LrcNoEndTime(),
new MacSub(), new MacSub(),
new MagicVideoTitler(), new MagicVideoTitler(),
@ -247,6 +248,7 @@ namespace Nikse.SubtitleEdit.Core.SubtitleFormats
new WebVTT(), new WebVTT(),
new WebVTTFileWithLineNumber(), new WebVTTFileWithLineNumber(),
new WhisperRaw(), new WhisperRaw(),
new WhisperRaw2(),
new Xif(), new Xif(),
new Xmp(), new Xmp(),
new YouTubeAnnotations(), new YouTubeAnnotations(),

View File

@ -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<string> 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();
}
}
}

View File

@ -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;
}
}
}

View File

@ -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<PiperModels> GetVoices()
{
var models = new List<PiperModels>
{
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();
}
}
}

View File

@ -23,6 +23,11 @@ namespace Nikse.SubtitleEdit.Controls
_items.AddRange(items); _items.AddRange(items);
} }
public void AddRange(string[] items)
{
_items.AddRange(items);
}
public IEnumerator GetEnumerator() public IEnumerator GetEnumerator()
{ {
return _items.GetEnumerator(); return _items.GetEnumerator();

View File

@ -338,21 +338,9 @@ namespace Nikse.SubtitleEdit.Forms
} }
} }
private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) => listViewFixes.CheckAll();
{
foreach (ListViewItem item in listViewFixes.Items)
{
item.Checked = true;
}
}
private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) => listViewFixes.InvertCheck();
{
foreach (ListViewItem item in listViewFixes.Items)
{
item.Checked = !item.Checked;
}
}
private void checkBoxCheckShotChanges_CheckedChanged(object sender, EventArgs e) private void checkBoxCheckShotChanges_CheckedChanged(object sender, EventArgs e)
{ {

View File

@ -125,20 +125,8 @@ namespace Nikse.SubtitleEdit.Forms.Assa
} }
} }
private void ToolStripMenuItemSelectAll_Click(object sender, EventArgs e) private void ToolStripMenuItemSelectAll_Click(object sender, EventArgs e) => listViewCategories.CheckAll();
{
foreach (ListViewItem item in listViewCategories.Items)
{
item.Checked = true;
}
}
private void ToolStripMenuItemInverseSelection_Click(object sender, EventArgs e) private void ToolStripMenuItemInverseSelection_Click(object sender, EventArgs e) => listViewCategories.InvertCheck();
{
foreach (ListViewItem item in listViewCategories.Items)
{
item.Checked = !item.Checked;
}
}
} }
} }

View File

@ -251,18 +251,12 @@ namespace Nikse.SubtitleEdit.Forms
private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewFixes.Items) listViewFixes.CheckAll();
{
item.Checked = true;
}
} }
private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewFixes.Items) listViewFixes.InvertCheck();
{
item.Checked = !item.Checked;
}
} }
private void AutoBreakUnbreakLines_FormClosing(object sender, FormClosingEventArgs e) private void AutoBreakUnbreakLines_FormClosing(object sender, FormClosingEventArgs e)

View File

@ -3977,18 +3977,12 @@ namespace Nikse.SubtitleEdit.Forms
private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewConvertOptions.Items) listViewConvertOptions.CheckAll();
{
item.Checked = true;
}
} }
private void inverseSelectionToolStripMenuItem_Click(object sender, EventArgs e) private void inverseSelectionToolStripMenuItem_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewConvertOptions.Items) listViewConvertOptions.InvertCheck();
{
item.Checked = !item.Checked;
}
} }
private void listViewInputFiles_ColumnClick(object sender, ColumnClickEventArgs e) private void listViewInputFiles_ColumnClick(object sender, ColumnClickEventArgs e)
@ -3998,6 +3992,11 @@ namespace Nikse.SubtitleEdit.Forms
return; return;
} }
for (var i = 0; i < listViewInputFiles.Columns.Count; i++)
{
ListViewSorter.SetSortArrow(listViewInputFiles.Columns[i], SortOrder.None);
}
if (!(listViewInputFiles.ListViewItemSorter is ListViewSorter sorter)) if (!(listViewInputFiles.ListViewItemSorter is ListViewSorter sorter))
{ {
sorter = new ListViewSorter sorter = new ListViewSorter
@ -4020,7 +4019,10 @@ namespace Nikse.SubtitleEdit.Forms
sorter.IsNumber = false; sorter.IsNumber = false;
sorter.IsDisplayFileSize = e.Column == columnHeaderSize.DisplayIndex; sorter.IsDisplayFileSize = e.Column == columnHeaderSize.DisplayIndex;
} }
listViewInputFiles.Sort(); listViewInputFiles.Sort();
ListViewSorter.SetSortArrow(listViewInputFiles.Columns[e.Column], sorter.Descending ? SortOrder.Descending : SortOrder.Ascending);
} }
private void buttonBrowseEncoding_Click(object sender, EventArgs e) private void buttonBrowseEncoding_Click(object sender, EventArgs e)

View File

@ -335,18 +335,12 @@ namespace Nikse.SubtitleEdit.Forms
private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewFixes.Items) listViewFixes.CheckAll();
{
item.Checked = true;
}
} }
private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewFixes.Items) listViewFixes.InvertCheck();
{
item.Checked = !item.Checked;
}
} }
private void toolStripMenuItem1SelectAll_Click(object sender, EventArgs e) private void toolStripMenuItem1SelectAll_Click(object sender, EventArgs e)

View File

@ -1145,21 +1145,9 @@ namespace Nikse.SubtitleEdit.Forms
listViewFixes.Sort(); listViewFixes.Sort();
} }
private void ButtonSelectAllClick(object sender, EventArgs e) private void ButtonSelectAllClick(object sender, EventArgs e) => listView1.CheckAll();
{
foreach (ListViewItem item in listView1.Items)
{
item.Checked = true;
}
}
private void ButtonInverseSelectionClick(object sender, EventArgs e) private void ButtonInverseSelectionClick(object sender, EventArgs e) => listView1.InvertCheck();
{
foreach (ListViewItem item in listView1.Items)
{
item.Checked = !item.Checked;
}
}
private void ListViewFixesSelectedIndexChanged(object sender, EventArgs e) private void ListViewFixesSelectedIndexChanged(object sender, EventArgs e)
{ {
@ -1370,18 +1358,12 @@ namespace Nikse.SubtitleEdit.Forms
private void ButtonFixesSelectAllClick(object sender, EventArgs e) private void ButtonFixesSelectAllClick(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewFixes.Items) listViewFixes.CheckAll();
{
item.Checked = true;
}
} }
private void ButtonFixesInverseClick(object sender, EventArgs e) private void ButtonFixesInverseClick(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewFixes.Items) listViewFixes.InvertCheck();
{
item.Checked = !item.Checked;
}
} }
private void ButtonFixesApplyClick(object sender, EventArgs e) private void ButtonFixesApplyClick(object sender, EventArgs e)
@ -1948,18 +1930,12 @@ namespace Nikse.SubtitleEdit.Forms
private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewFixes.Items) listViewFixes.CheckAll();
{
item.Checked = true;
}
} }
private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewFixes.Items) listViewFixes.InvertCheck();
{
item.Checked = !item.Checked;
}
} }
private void setCurrentFixesAsDefaultToolStripMenuItem_Click(object sender, EventArgs e) private void setCurrentFixesAsDefaultToolStripMenuItem_Click(object sender, EventArgs e)

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,7 @@ namespace Nikse.SubtitleEdit.Forms
private long _totalFrames; private long _totalFrames;
private StringBuilder _log; private StringBuilder _log;
private readonly bool _isAssa; private readonly bool _isAssa;
private readonly FfmpegMediaInfo _mediaInfo; private FfmpegMediaInfo _mediaInfo;
private bool _promptFFmpegParameters; private bool _promptFFmpegParameters;
private readonly bool _mpvOn; private readonly bool _mpvOn;
private readonly string _mpvSubtitleFileName; private readonly string _mpvSubtitleFileName;
@ -42,6 +42,7 @@ namespace Nikse.SubtitleEdit.Forms
public bool BatchMode { get; set; } public bool BatchMode { get; set; }
public string BatchInfo { get; set; } public string BatchInfo { get; set; }
private readonly List<BatchVideoAndSub> _batchVideoAndSubList; private readonly List<BatchVideoAndSub> _batchVideoAndSubList;
private const int ListViewBatchSubItemIndexColumnVideoSize = 2;
private const int ListViewBatchSubItemIndexColumnSubtitleFile = 3; private const int ListViewBatchSubItemIndexColumnSubtitleFile = 3;
private const int ListViewBatchSubItemIndexColumnStatus = 4; private const int ListViewBatchSubItemIndexColumnStatus = 4;
@ -248,7 +249,6 @@ namespace Nikse.SubtitleEdit.Forms
UiUtil.FixLargeFonts(this, buttonGenerate); UiUtil.FixLargeFonts(this, buttonGenerate);
UiUtil.FixFonts(this, 2000); UiUtil.FixFonts(this, 2000);
_mediaInfo = FfmpegMediaInfo.Parse(inputVideoFileName); _mediaInfo = FfmpegMediaInfo.Parse(inputVideoFileName);
if (_videoInfo != null && _videoInfo.TotalSeconds > 0) if (_videoInfo != null && _videoInfo.TotalSeconds > 0)
@ -459,6 +459,8 @@ namespace Nikse.SubtitleEdit.Forms
labelPleaseWait.Text = $"{index + 1}/{_batchVideoAndSubList.Count} - {LanguageSettings.Current.General.PleaseWait}"; labelPleaseWait.Text = $"{index + 1}/{_batchVideoAndSubList.Count} - {LanguageSettings.Current.General.PleaseWait}";
var videoAndSub = _batchVideoAndSubList[index]; var videoAndSub = _batchVideoAndSubList[index];
_mediaInfo = FfmpegMediaInfo.Parse(videoAndSub.VideoFileName);
_videoInfo = UiUtil.GetVideoInfo(videoAndSub.VideoFileName); _videoInfo = UiUtil.GetVideoInfo(videoAndSub.VideoFileName);
if (useSourceResolution) if (useSourceResolution)
{ {
@ -977,12 +979,18 @@ namespace Nikse.SubtitleEdit.Forms
if (_abort) if (_abort)
{ {
process.Kill(); process.Kill();
return false;
} }
var v = (int)_processedFrames; var v = (int)_processedFrames;
SetProgress(v); SetProgress(v);
} }
if (_abort)
{
return false;
}
if (process.ExitCode != 0) if (process.ExitCode != 0)
{ {
_log.AppendLine("ffmpeg exit code: " + process.ExitCode); _log.AppendLine("ffmpeg exit code: " + process.ExitCode);
@ -2108,11 +2116,27 @@ namespace Nikse.SubtitleEdit.Forms
return; return;
} }
try
{
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) foreach (var fileName in openFileDialog1.FileNames)
{ {
Application.DoEvents();
AddInputFile(fileName); AddInputFile(fileName);
} }
} }
finally
{
Cursor = Cursors.Default;
}
}
} }
private void AddInputFile(string fileName) private void AddInputFile(string fileName)
@ -2162,7 +2186,16 @@ namespace Nikse.SubtitleEdit.Forms
item.SubtitleFileFileSizeInBytes = new FileInfo(subFileName).Length; item.SubtitleFileFileSizeInBytes = new FileInfo(subFileName).Length;
} }
var mediaInfo = FfmpegMediaInfo.Parse(fileName);
int width;
int height;
if (mediaInfo.VideoWidth > 0 && mediaInfo.VideoHeight > 0)
{
width = mediaInfo.VideoWidth;
height = mediaInfo.VideoHeight;
}
else
{
var vInfo = new VideoInfo { Success = false }; var vInfo = new VideoInfo { Success = false };
if (fileName.EndsWith(".mp4", StringComparison.OrdinalIgnoreCase)) if (fileName.EndsWith(".mp4", StringComparison.OrdinalIgnoreCase))
{ {
@ -2178,9 +2211,19 @@ namespace Nikse.SubtitleEdit.Forms
vInfo = UiUtil.GetVideoInfo(fileName); vInfo = UiUtil.GetVideoInfo(fileName);
} }
width = vInfo.Width;
height = vInfo.Height;
}
if (width == 0 || height == 0)
{
SeLogger.Error("Skipping burn-in file with no video: " + fileName);
return; // skip audio or damaged files
}
var listViewItem = new ListViewItem(fileName); var listViewItem = new ListViewItem(fileName);
listViewItem.Tag = item; listViewItem.Tag = item;
listViewItem.SubItems.Add($"{vInfo.Width}x{vInfo.Height}"); listViewItem.SubItems.Add($"{width}x{height}");
var s = Utilities.FormatBytesToDisplayFileSize(item.VideoFileSizeInBytes); var s = Utilities.FormatBytesToDisplayFileSize(item.VideoFileSizeInBytes);
listViewItem.SubItems.Add(s); listViewItem.SubItems.Add(s);
listViewItem.SubItems.Add(Path.GetFileName(item.SubtitleFileName)); listViewItem.SubItems.Add(Path.GetFileName(item.SubtitleFileName));
@ -2262,13 +2305,14 @@ namespace Nikse.SubtitleEdit.Forms
return; return;
} }
try
{
var fileNames = (string[])e.Data.GetData(DataFormats.FileDrop); var fileNames = (string[])e.Data.GetData(DataFormats.FileDrop);
labelPleaseWait.Visible = true; labelPleaseWait.Visible = true;
TaskDelayHelper.RunDelayed(TimeSpan.FromMilliseconds(5), () => TaskDelayHelper.RunDelayed(TimeSpan.FromMilliseconds(5), () =>
{ {
try
{
Cursor = Cursors.WaitCursor;
foreach (var fileName in fileNames) foreach (var fileName in fileNames)
{ {
if (FileUtil.IsDirectory(fileName)) if (FileUtil.IsDirectory(fileName))
@ -2277,15 +2321,17 @@ namespace Nikse.SubtitleEdit.Forms
} }
else else
{ {
Application.DoEvents();
AddInputFile(fileName); AddInputFile(fileName);
} }
} }
});
} }
finally finally
{ {
Cursor = Cursors.Default;
labelPleaseWait.Visible = false; labelPleaseWait.Visible = false;
} }
});
} }
private void SearchFolder(string path) private void SearchFolder(string path)
@ -2376,9 +2422,49 @@ namespace Nikse.SubtitleEdit.Forms
useSourceResolutionToolStripMenuItem.Visible = BatchMode; 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);
}
} }
} }
} }

View File

@ -28,6 +28,7 @@
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent()
{ {
this.components = new System.ComponentModel.Container();
this.buttonCancel = new System.Windows.Forms.Button(); this.buttonCancel = new System.Windows.Forms.Button();
this.buttonJoin = new System.Windows.Forms.Button(); this.buttonJoin = new System.Windows.Forms.Button();
this.listViewParts = new System.Windows.Forms.ListView(); this.listViewParts = new System.Windows.Forms.ListView();
@ -45,7 +46,13 @@
this.numericUpDownAddMs = new Nikse.SubtitleEdit.Controls.NikseUpDown(); this.numericUpDownAddMs = new Nikse.SubtitleEdit.Controls.NikseUpDown();
this.radioButtonJoinAddTime = new System.Windows.Forms.RadioButton(); this.radioButtonJoinAddTime = new System.Windows.Forms.RadioButton();
this.labelAddTime = new Nikse.SubtitleEdit.Controls.NikseLabel(); 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.groupBoxPreview.SuspendLayout();
this.contextMenuStripParts.SuspendLayout();
this.SuspendLayout(); this.SuspendLayout();
// //
// buttonCancel // buttonCancel
@ -83,6 +90,7 @@
this.columnHeaderStartTime, this.columnHeaderStartTime,
this.columnHeaderEndTime, this.columnHeaderEndTime,
this.columnHeaderFileName}); this.columnHeaderFileName});
this.listViewParts.ContextMenuStrip = this.contextMenuStripParts;
this.listViewParts.FullRowSelect = true; this.listViewParts.FullRowSelect = true;
this.listViewParts.HideSelection = false; this.listViewParts.HideSelection = false;
this.listViewParts.Location = new System.Drawing.Point(6, 19); this.listViewParts.Location = new System.Drawing.Point(6, 19);
@ -91,6 +99,7 @@
this.listViewParts.TabIndex = 101; this.listViewParts.TabIndex = 101;
this.listViewParts.UseCompatibleStateImageBehavior = false; this.listViewParts.UseCompatibleStateImageBehavior = false;
this.listViewParts.View = System.Windows.Forms.View.Details; 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.DragDrop += new System.Windows.Forms.DragEventHandler(this.listViewParts_DragDrop);
this.listViewParts.DragEnter += new System.Windows.Forms.DragEventHandler(this.listViewParts_DragEnter); this.listViewParts.DragEnter += new System.Windows.Forms.DragEventHandler(this.listViewParts_DragEnter);
// //
@ -252,6 +261,49 @@
this.labelAddTime.TabIndex = 34; this.labelAddTime.TabIndex = 34;
this.labelAddTime.Text = "Add milliseconds after each file"; 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 // JoinSubtitles
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -279,6 +331,7 @@
this.Resize += new System.EventHandler(this.JoinSubtitles_Resize); this.Resize += new System.EventHandler(this.JoinSubtitles_Resize);
this.groupBoxPreview.ResumeLayout(false); this.groupBoxPreview.ResumeLayout(false);
this.groupBoxPreview.PerformLayout(); this.groupBoxPreview.PerformLayout();
this.contextMenuStripParts.ResumeLayout(false);
this.ResumeLayout(false); this.ResumeLayout(false);
this.PerformLayout(); this.PerformLayout();
@ -303,5 +356,10 @@
private Nikse.SubtitleEdit.Controls.NikseUpDown numericUpDownAddMs; private Nikse.SubtitleEdit.Controls.NikseUpDown numericUpDownAddMs;
private System.Windows.Forms.RadioButton radioButtonJoinAddTime; private System.Windows.Forms.RadioButton radioButtonJoinAddTime;
private Nikse.SubtitleEdit.Controls.NikseLabel labelAddTime; 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;
} }
} }

View File

@ -7,6 +7,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using Nikse.SubtitleEdit.Core.Enums;
using MessageBox = Nikse.SubtitleEdit.Forms.SeMsgBox.MessageBox; using MessageBox = Nikse.SubtitleEdit.Forms.SeMsgBox.MessageBox;
namespace Nikse.SubtitleEdit.Forms namespace Nikse.SubtitleEdit.Forms
@ -30,6 +31,11 @@ namespace Nikse.SubtitleEdit.Forms
listViewParts.Columns[2].Text = LanguageSettings.Current.JoinSubtitles.EndTime; listViewParts.Columns[2].Text = LanguageSettings.Current.JoinSubtitles.EndTime;
listViewParts.Columns[3].Text = LanguageSettings.Current.JoinSubtitles.FileName; 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; buttonAddFile.Text = LanguageSettings.Current.DvdSubRip.Add;
buttonRemoveFile.Text = LanguageSettings.Current.DvdSubRip.Remove; buttonRemoveFile.Text = LanguageSettings.Current.DvdSubRip.Remove;
buttonClear.Text = LanguageSettings.Current.DvdSubRip.Clear; buttonClear.Text = LanguageSettings.Current.DvdSubRip.Clear;
@ -88,14 +94,21 @@ namespace Nikse.SubtitleEdit.Forms
private void listViewParts_DragDrop(object sender, DragEventArgs e) private void listViewParts_DragDrop(object sender, DragEventArgs e)
{ {
var files = (string[])e.Data.GetData(DataFormats.FileDrop); var files = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (string fileName in files)
TaskDelayHelper.RunDelayed(TimeSpan.FromMilliseconds(1), () =>
{
var fileNames = files.ToList();
fileNames.Sort(ListViewSorter.NaturalComparer);
foreach (var fileName in fileNames)
{ {
if (!_fileNamesToJoin.Any(file => file.Equals(fileName, StringComparison.OrdinalIgnoreCase))) if (!_fileNamesToJoin.Any(file => file.Equals(fileName, StringComparison.OrdinalIgnoreCase)))
{ {
_fileNamesToJoin.Add(fileName); _fileNamesToJoin.Add(fileName);
} }
} }
SortAndLoad(); SortAndLoad();
});
} }
private void SortAndLoad() private void SortAndLoad()
@ -260,21 +273,16 @@ namespace Nikse.SubtitleEdit.Forms
if (!radioButtonJoinAddTime.Checked) 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 a = subtitles[inner - 1];
var b = subtitles[inner]; var b = subtitles[inner];
if (a.Paragraphs.Count > 0 && b.Paragraphs.Count > 0 && a.Paragraphs[0].StartTime.TotalMilliseconds > b.Paragraphs[0].StartTime.TotalMilliseconds) 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], _fileNamesToJoin[inner - 1]);
_fileNamesToJoin[inner - 1] = _fileNamesToJoin[inner]; (subtitles[inner - 1], subtitles[inner]) = (subtitles[inner], subtitles[inner - 1]);
_fileNamesToJoin[inner] = t1;
var t2 = subtitles[inner - 1];
subtitles[inner - 1] = subtitles[inner];
subtitles[inner] = t2;
} }
} }
} }
@ -287,6 +295,7 @@ namespace Nikse.SubtitleEdit.Forms
{ {
var sub = subtitles[i]; var sub = subtitles[i];
var lvi = new ListViewItem($"{sub.Paragraphs.Count:#,###,###}"); var lvi = new ListViewItem($"{sub.Paragraphs.Count:#,###,###}");
lvi.Tag = fileName;
if (sub.Paragraphs.Count > 0) if (sub.Paragraphs.Count > 0)
{ {
lvi.SubItems.Add(sub.Paragraphs[0].StartTime.ToString()); 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(); JoinedSubtitle.Renumber();
labelTotalLines.Text = string.Format(LanguageSettings.Current.JoinSubtitles.TotalNumberOfLinesX, JoinedSubtitle.Paragraphs.Count); 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) if (openFileDialog1.ShowDialog(this) == DialogResult.OK)
{ {
var sb = new StringBuilder(); 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(); Application.DoEvents();
if (File.Exists(fileName)) if (File.Exists(fileName))
@ -383,11 +399,13 @@ namespace Nikse.SubtitleEdit.Forms
} }
} }
} }
SortAndLoad(); SortAndLoad();
if (sb.Length > 0) if (sb.Length > 0)
{ {
MessageBox.Show(sb.ToString()); MessageBox.Show(sb.ToString());
} }
JoinSubtitles_Resize(sender, e); JoinSubtitles_Resize(sender, e);
} }
} }
@ -437,6 +455,218 @@ namespace Nikse.SubtitleEdit.Forms
numericUpDownAddMs.Enabled = radioButtonJoinAddTime.Checked; numericUpDownAddMs.Enabled = radioButtonJoinAddTime.Checked;
labelAddTime.Enabled = radioButtonJoinAddTime.Checked; labelAddTime.Enabled = radioButtonJoinAddTime.Checked;
SortAndLoad(); 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();
} }
} }
} }

View File

@ -117,6 +117,9 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<metadata name="contextMenuStripParts.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>159, 22</value>
</metadata>
<metadata name="openFileDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="openFileDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value> <value>17, 17</value>
</metadata> </metadata>

View File

@ -41,9 +41,9 @@ namespace Nikse.SubtitleEdit.Forms
{ {
this.components = new System.ComponentModel.Container(); this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Main)); 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 timeCode13 = new Nikse.SubtitleEdit.Core.Common.TimeCode();
Nikse.SubtitleEdit.Core.Common.TimeCode timeCode2 = new Nikse.SubtitleEdit.Core.Common.TimeCode(); Nikse.SubtitleEdit.Core.Common.TimeCode timeCode14 = new Nikse.SubtitleEdit.Core.Common.TimeCode();
Nikse.SubtitleEdit.Core.Common.TimeCode timeCode3 = 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.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.labelStatus = new System.Windows.Forms.ToolStripStatusLabel(); this.labelStatus = new System.Windows.Forms.ToolStripStatusLabel();
this.toolStripSelected = 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.splitToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.mergeWithPreviousToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.mergeWithPreviousToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mergeWithNextToolStripMenuItem = 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.toolStripSeparator11 = new System.Windows.Forms.ToolStripSeparator();
this.extendToPreviousToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.extendToPreviousToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.extendToNextToolStripMenuItem = 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.toolStripSeparatorGuessTimeCodes = new System.Windows.Forms.ToolStripSeparator();
this.removeShotChangeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.removeShotChangeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.addShotChangeToolStripMenuItem = 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.guessTimeCodesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.seekSilenceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.seekSilenceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.insertSubtitleHereToolStripMenuItem = 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.timerOriginalTextUndo = new System.Windows.Forms.Timer(this.components);
this.contextMenuStripShowVideoControls = new System.Windows.Forms.ContextMenuStrip(this.components); this.contextMenuStripShowVideoControls = new System.Windows.Forms.ContextMenuStrip(this.components);
this.toolStripMenuItemShowVideoControls = new System.Windows.Forms.ToolStripMenuItem(); 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.statusStrip1.SuspendLayout();
this.toolStrip1.SuspendLayout(); this.toolStrip1.SuspendLayout();
this.menuStrip1.SuspendLayout(); this.menuStrip1.SuspendLayout();
@ -620,6 +623,7 @@ namespace Nikse.SubtitleEdit.Forms
this.panelVideoPlayer.SuspendLayout(); this.panelVideoPlayer.SuspendLayout();
this.contextMenuStripEmpty.SuspendLayout(); this.contextMenuStripEmpty.SuspendLayout();
this.contextMenuStripShowVideoControls.SuspendLayout(); this.contextMenuStripShowVideoControls.SuspendLayout();
this.contextMenuStripVideoFileName.SuspendLayout();
this.SuspendLayout(); this.SuspendLayout();
// //
// statusStrip1 // statusStrip1
@ -1077,7 +1081,7 @@ namespace Nikse.SubtitleEdit.Forms
this.comboBoxEncoding.DropDownHeight = 215; this.comboBoxEncoding.DropDownHeight = 215;
this.comboBoxEncoding.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBoxEncoding.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBoxEncoding.DropDownWidth = 0; this.comboBoxEncoding.DropDownWidth = 0;
this.comboBoxEncoding.Items.AddRange(new object[] { this.comboBoxEncoding.Items.AddRange(new string[] {
"ANSI", "ANSI",
"UTF-7", "UTF-7",
"UTF-8", "UTF-8",
@ -3401,13 +3405,13 @@ namespace Nikse.SubtitleEdit.Forms
// labelVideoInfo // labelVideoInfo
// //
this.labelVideoInfo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 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.Location = new System.Drawing.Point(603, 12);
this.labelVideoInfo.Name = "labelVideoInfo"; this.labelVideoInfo.Name = "labelVideoInfo";
this.labelVideoInfo.Size = new System.Drawing.Size(369, 19); this.labelVideoInfo.Size = new System.Drawing.Size(369, 19);
this.labelVideoInfo.TabIndex = 12; this.labelVideoInfo.TabIndex = 12;
this.labelVideoInfo.Text = "No video file loaded"; this.labelVideoInfo.Text = "No video file loaded";
this.labelVideoInfo.TextAlign = System.Drawing.ContentAlignment.TopRight; this.labelVideoInfo.TextAlign = System.Drawing.ContentAlignment.TopRight;
this.labelVideoInfo.Click += new System.EventHandler(this.labelVideoInfo_Click);
// //
// trackBarWaveformPosition // trackBarWaveformPosition
// //
@ -3680,7 +3684,7 @@ namespace Nikse.SubtitleEdit.Forms
this.comboBoxAutoContinue.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBoxAutoContinue.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBoxAutoContinue.DropDownWidth = 96; this.comboBoxAutoContinue.DropDownWidth = 96;
this.comboBoxAutoContinue.FormattingEnabled = false; this.comboBoxAutoContinue.FormattingEnabled = false;
this.comboBoxAutoContinue.Items.AddRange(new object[] { this.comboBoxAutoContinue.Items.AddRange(new string[] {
"0", "0",
"1", "1",
"2", "2",
@ -3762,7 +3766,7 @@ namespace Nikse.SubtitleEdit.Forms
this.comboBoxAutoRepeat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBoxAutoRepeat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBoxAutoRepeat.DropDownWidth = 96; this.comboBoxAutoRepeat.DropDownWidth = 96;
this.comboBoxAutoRepeat.FormattingEnabled = false; this.comboBoxAutoRepeat.FormattingEnabled = false;
this.comboBoxAutoRepeat.Items.AddRange(new object[] { this.comboBoxAutoRepeat.Items.AddRange(new string[] {
"0", "0",
"1", "1",
"2", "2",
@ -3886,14 +3890,14 @@ namespace Nikse.SubtitleEdit.Forms
this.timeUpDownVideoPosition.Size = new System.Drawing.Size(113, 23); this.timeUpDownVideoPosition.Size = new System.Drawing.Size(113, 23);
this.timeUpDownVideoPosition.TabIndex = 12; this.timeUpDownVideoPosition.TabIndex = 12;
this.timeUpDownVideoPosition.TabStop = false; this.timeUpDownVideoPosition.TabStop = false;
timeCode1.Hours = 0; timeCode13.Hours = 0;
timeCode1.Milliseconds = 0; timeCode13.Milliseconds = 0;
timeCode1.Minutes = 0; timeCode13.Minutes = 0;
timeCode1.Seconds = 0; timeCode13.Seconds = 0;
timeCode1.TimeSpan = System.TimeSpan.Parse("00:00:00"); timeCode13.TimeSpan = System.TimeSpan.Parse("00:00:00");
timeCode1.TotalMilliseconds = 0D; timeCode13.TotalMilliseconds = 0D;
timeCode1.TotalSeconds = 0D; timeCode13.TotalSeconds = 0D;
this.timeUpDownVideoPosition.TimeCode = timeCode1; this.timeUpDownVideoPosition.TimeCode = timeCode13;
this.timeUpDownVideoPosition.UseVideoOffset = false; this.timeUpDownVideoPosition.UseVideoOffset = false;
// //
// buttonGotoSub // buttonGotoSub
@ -4166,14 +4170,14 @@ namespace Nikse.SubtitleEdit.Forms
this.timeUpDownVideoPositionAdjust.Size = new System.Drawing.Size(113, 23); this.timeUpDownVideoPositionAdjust.Size = new System.Drawing.Size(113, 23);
this.timeUpDownVideoPositionAdjust.TabIndex = 13; this.timeUpDownVideoPositionAdjust.TabIndex = 13;
this.timeUpDownVideoPositionAdjust.TabStop = false; this.timeUpDownVideoPositionAdjust.TabStop = false;
timeCode2.Hours = 0; timeCode14.Hours = 0;
timeCode2.Milliseconds = 0; timeCode14.Milliseconds = 0;
timeCode2.Minutes = 0; timeCode14.Minutes = 0;
timeCode2.Seconds = 0; timeCode14.Seconds = 0;
timeCode2.TimeSpan = System.TimeSpan.Parse("00:00:00"); timeCode14.TimeSpan = System.TimeSpan.Parse("00:00:00");
timeCode2.TotalMilliseconds = 0D; timeCode14.TotalMilliseconds = 0D;
timeCode2.TotalSeconds = 0D; timeCode14.TotalSeconds = 0D;
this.timeUpDownVideoPositionAdjust.TimeCode = timeCode2; this.timeUpDownVideoPositionAdjust.TimeCode = timeCode14;
this.timeUpDownVideoPositionAdjust.UseVideoOffset = false; this.timeUpDownVideoPositionAdjust.UseVideoOffset = false;
// //
// buttonAdjustSetEndTime // buttonAdjustSetEndTime
@ -4472,7 +4476,7 @@ namespace Nikse.SubtitleEdit.Forms
this.seekSilenceToolStripMenuItem, this.seekSilenceToolStripMenuItem,
this.insertSubtitleHereToolStripMenuItem}); this.insertSubtitleHereToolStripMenuItem});
this.contextMenuStripWaveform.Name = "contextMenuStripWaveform"; 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.Closing += new System.Windows.Forms.ToolStripDropDownClosingEventHandler(this.ContextMenuStripWaveformClosing);
this.contextMenuStripWaveform.Opening += new System.ComponentModel.CancelEventHandler(this.ContextMenuStripWaveformOpening); 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.Text = "Merge with next";
this.mergeWithNextToolStripMenuItem.Click += new System.EventHandler(this.MergeWithNextToolStripMenuItemClick); 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 // toolStripSeparator11
// //
this.toolStripSeparator11.Name = "toolStripSeparator11"; this.toolStripSeparator11.Name = "toolStripSeparator11";
@ -4629,6 +4626,13 @@ namespace Nikse.SubtitleEdit.Forms
this.addShotChangeToolStripMenuItem.Text = "Add shot change"; this.addShotChangeToolStripMenuItem.Text = "Add shot change";
this.addShotChangeToolStripMenuItem.Click += new System.EventHandler(this.AddShotChangeToolStripMenuItemClick); 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 // guessTimeCodesToolStripMenuItem
// //
this.guessTimeCodesToolStripMenuItem.Name = "guessTimeCodesToolStripMenuItem"; this.guessTimeCodesToolStripMenuItem.Name = "guessTimeCodesToolStripMenuItem";
@ -5522,14 +5526,14 @@ namespace Nikse.SubtitleEdit.Forms
this.timeUpDownStartTime.Size = new System.Drawing.Size(113, 23); this.timeUpDownStartTime.Size = new System.Drawing.Size(113, 23);
this.timeUpDownStartTime.TabIndex = 0; this.timeUpDownStartTime.TabIndex = 0;
this.timeUpDownStartTime.TabStop = false; this.timeUpDownStartTime.TabStop = false;
timeCode3.Hours = 0; timeCode15.Hours = 0;
timeCode3.Milliseconds = 0; timeCode15.Milliseconds = 0;
timeCode3.Minutes = 0; timeCode15.Minutes = 0;
timeCode3.Seconds = 0; timeCode15.Seconds = 0;
timeCode3.TimeSpan = System.TimeSpan.Parse("00:00:00"); timeCode15.TimeSpan = System.TimeSpan.Parse("00:00:00");
timeCode3.TotalMilliseconds = 0D; timeCode15.TotalMilliseconds = 0D;
timeCode3.TotalSeconds = 0D; timeCode15.TotalSeconds = 0D;
this.timeUpDownStartTime.TimeCode = timeCode3; this.timeUpDownStartTime.TimeCode = timeCode15;
this.timeUpDownStartTime.UseVideoOffset = false; this.timeUpDownStartTime.UseVideoOffset = false;
// //
// numericUpDownDuration // numericUpDownDuration
@ -5883,6 +5887,29 @@ namespace Nikse.SubtitleEdit.Forms
this.toolStripMenuItemShowVideoControls.Text = "Show video controls"; this.toolStripMenuItemShowVideoControls.Text = "Show video controls";
this.toolStripMenuItemShowVideoControls.Click += new System.EventHandler(this.ToolStripMenuItemShowVideoControlsClick); 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 // Main
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -5959,6 +5986,7 @@ namespace Nikse.SubtitleEdit.Forms
this.panelVideoPlayer.ResumeLayout(false); this.panelVideoPlayer.ResumeLayout(false);
this.contextMenuStripEmpty.ResumeLayout(false); this.contextMenuStripEmpty.ResumeLayout(false);
this.contextMenuStripShowVideoControls.ResumeLayout(false); this.contextMenuStripShowVideoControls.ResumeLayout(false);
this.contextMenuStripVideoFileName.ResumeLayout(false);
this.ResumeLayout(false); this.ResumeLayout(false);
this.PerformLayout(); this.PerformLayout();
@ -6504,5 +6532,8 @@ namespace Nikse.SubtitleEdit.Forms
private System.Windows.Forms.ToolStripButton toolStripButtonVideoOpen; private System.Windows.Forms.ToolStripButton toolStripButtonVideoOpen;
private System.Windows.Forms.ToolStripMenuItem runWhiperOnParagraphToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem runWhiperOnParagraphToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem textToSpeechAndAddToVideoToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem textToSpeechAndAddToVideoToolStripMenuItem;
private ContextMenuStrip contextMenuStripVideoFileName;
private ToolStripMenuItem videoInfoToolStripMenuItem;
private ToolStripMenuItem openContainingFolderToolStripMenuItem;
} }
} }

View File

@ -345,6 +345,7 @@ namespace Nikse.SubtitleEdit.Forms
UiUtil.InitializeSubtitleFont(textBoxListViewText); UiUtil.InitializeSubtitleFont(textBoxListViewText);
UiUtil.InitializeSubtitleFont(textBoxListViewTextOriginal); UiUtil.InitializeSubtitleFont(textBoxListViewTextOriginal);
UiUtil.InitializeSubtitleFont(SubtitleListview1); UiUtil.InitializeSubtitleFont(SubtitleListview1);
UiUtil.InitializeSubtitleFont(textBoxSource);
} }
private static string GetArgumentAfterColon(IEnumerable<string> commandLineArguments, string requestedArgumentName) private static string GetArgumentAfterColon(IEnumerable<string> commandLineArguments, string requestedArgumentName)
@ -5783,6 +5784,7 @@ namespace Nikse.SubtitleEdit.Forms
SubtitleListview1.BackColor = Configuration.Settings.General.SubtitleBackgroundColor; SubtitleListview1.BackColor = Configuration.Settings.General.SubtitleBackgroundColor;
UiUtil.InitializeSubtitleFont(SubtitleListview1); UiUtil.InitializeSubtitleFont(SubtitleListview1);
UiUtil.InitializeSubtitleFont(textBoxSource);
mediaPlayer.SetSubtitleFont(); mediaPlayer.SetSubtitleFont();
ShowSubtitle(); ShowSubtitle();
} }
@ -23572,7 +23574,9 @@ namespace Nikse.SubtitleEdit.Forms
private void SetAssaResolutionWithChecks() 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)) 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; return;
} }
@ -36780,41 +36821,23 @@ namespace Nikse.SubtitleEdit.Forms
MessageBox.Show(sb.ToString() + sbTrackInfo.ToString()); 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); e.Cancel = true;
return;
} }
if (RequireFfmpegOk()) openContainingFolderToolStripMenuItem.Text = _language.Menu.File.OpenContainingFolder;
videoInfoToolStripMenuItem.Text = _language.Menu.ContextMenu.MediaInfo;
}
private void openContainingFolderToolStripMenuItem_Click(object sender, EventArgs e)
{ {
using (var form = new TextToSpeech(_subtitle, GetCurrentSubtitleFormat(), _videoFileName, _videoInfo)) if (!string.IsNullOrEmpty(_videoFileName) && File.Exists(_videoFileName))
{ {
if (form.ShowDialog(this) == DialogResult.OK) UiUtil.OpenFolderFromFileName(_videoFileName);
{
var idx = FirstSelectedIndex;
_subtitle = form.EditedSubtitle;
SubtitleListview1.Fill(_subtitle, _subtitleOriginal);
_subtitleListViewIndex = -1;
SubtitleListview1.SelectIndexAndEnsureVisibleFaster(idx);
} }
} }
} }
});
}
}
} }

View File

@ -684,6 +684,12 @@
ZW1zBV9zaXplCF92ZXJzaW9uBwAABggIAgAAAAkDAAAAAAAAAAAAAAAPAwAAAAAAAAAGCw== ZW1zBV9zaXplCF92ZXJzaW9uBwAABggIAgAAAAkDAAAAAAAAAAAAAAAPAwAAAAAAAAAGCw==
</value> </value>
</data> </data>
<metadata name="contextMenuStripVideoFileName.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>929, 92</value>
</metadata>
<metadata name="toolStripWaveControls.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>652, 56</value>
</metadata>
<metadata name="toolStripWaveControls.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="toolStripWaveControls.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>652, 56</value> <value>652, 56</value>
</metadata> </metadata>
@ -769,12 +775,12 @@
<metadata name="imageListBookmarks.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="imageListBookmarks.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>981, 56</value> <value>981, 56</value>
</metadata> </metadata>
<metadata name="contextMenuStripTextBoxListView.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>668, 17</value>
</metadata>
<metadata name="contextMenuStripTextBoxSourceView.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="contextMenuStripTextBoxSourceView.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>193, 17</value> <value>193, 17</value>
</metadata> </metadata>
<metadata name="contextMenuStripTextBoxListView.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>668, 17</value>
</metadata>
<metadata name="contextMenuStripEmpty.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="contextMenuStripEmpty.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 95</value> <value>17, 95</value>
</metadata> </metadata>

View File

@ -346,18 +346,12 @@ namespace Nikse.SubtitleEdit.Forms
private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewFixes.Items) listViewFixes.CheckAll();
{
item.Checked = true;
}
} }
private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewFixes.Items) listViewFixes.InvertCheck();
{
item.Checked = !item.Checked;
}
} }
} }
} }

View File

@ -297,18 +297,12 @@ namespace Nikse.SubtitleEdit.Forms
private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewFixes.Items) listViewFixes.CheckAll();
{
item.Checked = true;
}
} }
private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewFixes.Items) listViewFixes.InvertCheck();
{
item.Checked = !item.Checked;
}
} }
private void checkBoxMakeDialog_CheckedChanged(object sender, EventArgs e) private void checkBoxMakeDialog_CheckedChanged(object sender, EventArgs e)

View File

@ -28,13 +28,15 @@ namespace Nikse.SubtitleEdit.Forms
private const int FunctionEven = 7; private const int FunctionEven = 7;
private const int FunctionDurationLessThan = 8; private const int FunctionDurationLessThan = 8;
private const int FunctionDurationGreaterThan = 9; private const int FunctionDurationGreaterThan = 9;
private const int FunctionExactlyOneLine = 10; private const int FunctionCpsLessThan = 10;
private const int FunctionExactlyTwoLines = 11; private const int FunctionCpsGreaterThan = 11;
private const int FunctionMoreThanTwoLines = 12; private const int FunctionExactlyOneLine = 12;
private const int FunctionBookmarked = 13; private const int FunctionExactlyTwoLines = 13;
private const int FunctionBlankLines = 14; private const int FunctionMoreThanTwoLines = 14;
private const int FunctionStyle = 15; private const int FunctionBookmarked = 15;
private const int FunctionActor = 16; private const int FunctionBlankLines = 16;
private const int FunctionStyle = 17;
private const int FunctionActor = 18;
private const string ContainsString = "Contains"; private const string ContainsString = "Contains";
private const string StartsWith = "Starts with"; private const string StartsWith = "Starts with";
@ -46,6 +48,8 @@ namespace Nikse.SubtitleEdit.Forms
private const string Even = "Even"; private const string Even = "Even";
private const string DurationLessThan = "Duration <"; private const string DurationLessThan = "Duration <";
private const string DurationGreaterThan = "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 ExactlyOneLine = "Exactly one line";
private const string ExactlyTwoLines = "Exactly two lines"; private const string ExactlyTwoLines = "Exactly two lines";
private const string MoreThanTwoLines = "More than 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.EvenLines);
comboBoxRule.Items.Add(LanguageSettings.Current.ModifySelection.DurationLessThan); comboBoxRule.Items.Add(LanguageSettings.Current.ModifySelection.DurationLessThan);
comboBoxRule.Items.Add(LanguageSettings.Current.ModifySelection.DurationGreaterThan); 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.ExactlyOneLine);
comboBoxRule.Items.Add(LanguageSettings.Current.ModifySelection.ExactlyTwoLines); comboBoxRule.Items.Add(LanguageSettings.Current.ModifySelection.ExactlyTwoLines);
comboBoxRule.Items.Add(LanguageSettings.Current.ModifySelection.MoreThanTwoLines); comboBoxRule.Items.Add(LanguageSettings.Current.ModifySelection.MoreThanTwoLines);
@ -142,6 +148,12 @@ namespace Nikse.SubtitleEdit.Forms
case DurationGreaterThan: case DurationGreaterThan:
comboBoxRule.SelectedIndex = FunctionDurationGreaterThan; comboBoxRule.SelectedIndex = FunctionDurationGreaterThan;
break; break;
case CpsLessThan:
comboBoxRule.SelectedIndex = FunctionCpsLessThan;
break;
case CpsGreaterThan:
comboBoxRule.SelectedIndex = FunctionCpsGreaterThan;
break;
case ExactlyOneLine: case ExactlyOneLine:
comboBoxRule.SelectedIndex = FunctionExactlyOneLine; comboBoxRule.SelectedIndex = FunctionExactlyOneLine;
break; break;
@ -226,6 +238,12 @@ namespace Nikse.SubtitleEdit.Forms
case FunctionDurationGreaterThan: case FunctionDurationGreaterThan:
Configuration.Settings.Tools.ModifySelectionRule = DurationGreaterThan; Configuration.Settings.Tools.ModifySelectionRule = DurationGreaterThan;
break; break;
case FunctionCpsLessThan:
Configuration.Settings.Tools.ModifySelectionRule = CpsLessThan;
break;
case FunctionCpsGreaterThan:
Configuration.Settings.Tools.ModifySelectionRule = CpsGreaterThan;
break;
case FunctionExactlyOneLine: case FunctionExactlyOneLine:
Configuration.Settings.Tools.ModifySelectionRule = ExactlyOneLine; Configuration.Settings.Tools.ModifySelectionRule = ExactlyOneLine;
break; 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 || if ((radioButtonSubtractFromSelection.Checked || radioButtonIntersect.Checked) && _subtitleListView.Items[i].Selected ||
!radioButtonSubtractFromSelection.Checked && !radioButtonIntersect.Checked) !radioButtonSubtractFromSelection.Checked && !radioButtonIntersect.Checked)
@ -397,6 +415,20 @@ namespace Nikse.SubtitleEdit.Forms
listViewItems.Add(MakeListViewItem(p, i)); 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) else if (comboBoxRule.SelectedIndex == FunctionExactlyOneLine)
{ {
if (p.Text.SplitToLines().Count == 1) if (p.Text.SplitToLines().Count == 1)
@ -504,10 +536,15 @@ namespace Nikse.SubtitleEdit.Forms
{ {
textBoxText.Visible = true; textBoxText.Visible = true;
listViewStyles.Visible = false; 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 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 // allocation regex option is already selected and user re-select it
textBoxText.ContextMenuStrip = textBoxText.ContextMenuStrip ?? textBoxText.ContextMenuStrip = textBoxText.ContextMenuStrip ??
FindReplaceDialogHelper.GetRegExContextMenu(new NativeTextBoxAdapter(textBoxText)); FindReplaceDialogHelper.GetRegExContextMenu(new NativeTextBoxAdapter(textBoxText));
@ -525,7 +562,11 @@ namespace Nikse.SubtitleEdit.Forms
textBoxText.ContextMenuStrip = null; textBoxText.ContextMenuStrip = null;
textBoxText.Visible = false; 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; checkBoxCaseSensitive.Enabled = false;
listViewStyles.Visible = false; listViewStyles.Visible = false;
@ -539,7 +580,7 @@ namespace Nikse.SubtitleEdit.Forms
numericUpDownDuration.Value = Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds; numericUpDownDuration.Value = Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds;
} }
} }
else else if (comboBoxRule.SelectedIndex == FunctionDurationGreaterThan)
{ {
if (numericUpDownDuration.Value == 0 && if (numericUpDownDuration.Value == 0 &&
Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds >= numericUpDownDuration.Minimum && Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds >= numericUpDownDuration.Minimum &&
@ -548,6 +589,14 @@ namespace Nikse.SubtitleEdit.Forms
numericUpDownDuration.Value = Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds; 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) else if (comboBoxRule.SelectedIndex == FunctionStyle)
{ {
@ -642,18 +691,12 @@ namespace Nikse.SubtitleEdit.Forms
private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewFixes.Items) listViewFixes.CheckAll();
{
item.Checked = true;
}
} }
private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewFixes.Items) listViewFixes.InvertCheck();
{
item.Checked = !item.Checked;
}
} }
private void ModifySelection_Resize(object sender, EventArgs e) private void ModifySelection_Resize(object sender, EventArgs e)

View File

@ -570,18 +570,12 @@ namespace Nikse.SubtitleEdit.Forms
private void buttonReplacesSelectAll_Click(object sender, EventArgs e) private void buttonReplacesSelectAll_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewFixes.Items) listViewFixes.CheckAll();
{
item.Checked = true;
}
} }
private void buttonReplacesInverseSelection_Click(object sender, EventArgs e) private void buttonReplacesInverseSelection_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewFixes.Items) listViewFixes.InvertCheck();
{
item.Checked = !item.Checked;
}
} }
private void contextMenuStrip1_Opening(object sender, System.ComponentModel.CancelEventArgs e) 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) private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewRules.Items) listViewRules.CheckAll();
{
item.Checked = true;
}
} }
private void inverseSelectionToolStripMenuItem_Click(object sender, EventArgs e) private void inverseSelectionToolStripMenuItem_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewRules.Items) listViewRules.InvertCheck();
{
item.Checked = !item.Checked;
}
} }
private void ContextMenuStripListViewFixesOpening(object sender, System.ComponentModel.CancelEventArgs e) private void ContextMenuStripListViewFixesOpening(object sender, System.ComponentModel.CancelEventArgs e)

View File

@ -136,18 +136,12 @@ namespace Nikse.SubtitleEdit.Forms
private void selectAllToolStripMenuItem_Click(object sender, EventArgs e) private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewExportStyles.Items) listViewExportStyles.CheckAll();
{
item.Checked = true;
}
} }
private void inverseSelectionToolStripMenuItem_Click(object sender, EventArgs e) private void inverseSelectionToolStripMenuItem_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewExportStyles.Items) listViewExportStyles.InvertCheck();
{
item.Checked = !item.Checked;
}
} }
} }
} }

View File

@ -328,12 +328,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
private void SelectAll_Click(object sender, EventArgs e) private void SelectAll_Click(object sender, EventArgs e)
{ {
listViewFonts.BeginUpdate(); listViewFonts.CheckAll();
foreach (ListViewItem fontItem in listViewFonts.Items)
{
fontItem.Checked = true;
}
listViewFonts.EndUpdate();
} }
public void InitializeDetectFont(BinaryOcrBitmap bob, string text) public void InitializeDetectFont(BinaryOcrBitmap bob, string text)

View File

@ -143,11 +143,7 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
private void buttonFixesSelectAll_Click(object sender, EventArgs e) private void buttonFixesSelectAll_Click(object sender, EventArgs e)
{ {
listView1.ItemChecked -= listView1_ItemChecked; listView1.ItemChecked -= listView1_ItemChecked;
listView1.CheckAll();
foreach (ListViewItem item in listView1.Items)
{
item.Checked = true;
}
foreach (ListViewData d in _data) foreach (ListViewData d in _data)
{ {

View File

@ -8600,6 +8600,13 @@ namespace Nikse.SubtitleEdit.Forms.Ocr
// ignored // ignored
} }
} }
e.Handled = true;
}
else if (e.KeyCode == Keys.Delete)
{
removeAllXToolStripMenuItem_Click(null, null);
e.Handled = true;
} }
} }

View File

@ -76,18 +76,12 @@ namespace Nikse.SubtitleEdit.Forms.Options
private void selectAllToolStripMenuItem_Click(object sender, EventArgs e) private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewExportStyles.Items) listViewExportStyles.CheckAll();
{
item.Checked = true;
}
} }
private void inverseSelectionToolStripMenuItem_Click(object sender, EventArgs e) private void inverseSelectionToolStripMenuItem_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewExportStyles.Items) listViewExportStyles.InvertCheck();
{
item.Checked = !item.Checked;
}
} }
} }
} }

View File

@ -718,10 +718,7 @@ namespace Nikse.SubtitleEdit.Forms
private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e)
{ {
listViewFixes.ItemChecked -= listViewFixes_ItemChecked; listViewFixes.ItemChecked -= listViewFixes_ItemChecked;
foreach (ListViewItem item in listViewFixes.Items) listViewFixes.CheckAll();
{
item.Checked = true;
}
listViewFixes.ItemChecked += listViewFixes_ItemChecked; listViewFixes.ItemChecked += listViewFixes_ItemChecked;
GeneratePreview(false); GeneratePreview(false);
} }
@ -729,10 +726,7 @@ namespace Nikse.SubtitleEdit.Forms
private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e)
{ {
listViewFixes.ItemChecked -= listViewFixes_ItemChecked; listViewFixes.ItemChecked -= listViewFixes_ItemChecked;
foreach (ListViewItem item in listViewFixes.Items) listViewFixes.InvertCheck();
{
item.Checked = !item.Checked;
}
listViewFixes.ItemChecked += listViewFixes_ItemChecked; listViewFixes.ItemChecked += listViewFixes_ItemChecked;
GeneratePreview(false); GeneratePreview(false);
} }

View File

@ -186,18 +186,12 @@ namespace Nikse.SubtitleEdit.Forms.Styles
private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewExportStyles.Items) listViewExportStyles.CheckAll();
{
item.Checked = true;
}
} }
private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewExportStyles.Items) listViewExportStyles.InvertCheck();
{
item.Checked = !item.Checked;
}
} }
} }
} }

View File

@ -704,6 +704,20 @@ namespace Nikse.SubtitleEdit.Forms.Translate
_autoTranslator = GetCurrentEngine(); _autoTranslator = GetCurrentEngine();
var engineType = _autoTranslator.GetType(); 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); SaveSettings(engineType);
buttonOK.Enabled = false; buttonOK.Enabled = false;

View File

@ -1,6 +1,6 @@
namespace Nikse.SubtitleEdit.Forms.Tts namespace Nikse.SubtitleEdit.Forms.Tts
{ {
partial class RegenerateAudioClip sealed partial class RegenerateAudioClip
{ {
/// <summary> /// <summary>
/// Required designer variable. /// Required designer variable.

View File

@ -5,7 +5,7 @@ using System.Windows.Forms;
namespace Nikse.SubtitleEdit.Forms.Tts namespace Nikse.SubtitleEdit.Forms.Tts
{ {
public partial class RegenerateAudioClip : Form public sealed partial class RegenerateAudioClip : Form
{ {
public TextToSpeech.FileNameAndSpeedFactor FileNameAndSpeedFactor { get; set; } public TextToSpeech.FileNameAndSpeedFactor FileNameAndSpeedFactor { get; set; }
@ -23,6 +23,10 @@ namespace Nikse.SubtitleEdit.Forms.Tts
_textToSpeech = textToSpeech; _textToSpeech = textToSpeech;
_index = idx; _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; buttonCancel.Text = LanguageSettings.Current.General.Cancel;
UiUtil.FixLargeFonts(this, buttonCancel); UiUtil.FixLargeFonts(this, buttonCancel);

View File

@ -24,6 +24,15 @@ namespace Nikse.SubtitleEdit.Forms.Tts
UiUtil.PreInitialize(this); UiUtil.PreInitialize(this);
InitializeComponent(); InitializeComponent();
UiUtil.FixFonts(this); 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; buttonOK.Text = LanguageSettings.Current.General.Ok;
UiUtil.FixLargeFonts(this, buttonOK); UiUtil.FixLargeFonts(this, buttonOK);

View File

@ -34,24 +34,29 @@
this.buttonGenerateTTS = new System.Windows.Forms.Button(); this.buttonGenerateTTS = new System.Windows.Forms.Button();
this.progressBar1 = new System.Windows.Forms.ProgressBar(); this.progressBar1 = new System.Windows.Forms.ProgressBar();
this.labelEngine = new System.Windows.Forms.Label(); 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.checkBoxShowPreview = new System.Windows.Forms.CheckBox();
this.labelApiKey = new System.Windows.Forms.Label(); 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.buttonTestVoice = new System.Windows.Forms.Button();
this.checkBoxAddToVideoFile = new System.Windows.Forms.CheckBox(); this.checkBoxAddToVideoFile = new System.Windows.Forms.CheckBox();
this.labelVoice = new System.Windows.Forms.Label(); 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.listViewActors = new System.Windows.Forms.ListView();
this.columnHeaderActor = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.columnHeaderActor = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeaderVoice = ((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.contextMenuStripActors = new System.Windows.Forms.ContextMenuStrip(this.components);
this.labelActors = new System.Windows.Forms.Label(); this.labelActors = new System.Windows.Forms.Label();
this.buttonCancel = new System.Windows.Forms.Button(); this.buttonCancel = new System.Windows.Forms.Button();
this.labelVoiceCount = new System.Windows.Forms.Label(); this.groupBoxSettings.SuspendLayout();
this.nikseTextBoxApiKey = new Nikse.SubtitleEdit.Controls.NikseTextBox(); this.contextMenuStripVoices.SuspendLayout();
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.SuspendLayout(); this.SuspendLayout();
// //
// buttonOK // buttonOK
@ -108,27 +113,106 @@
this.labelEngine.TabIndex = 14; this.labelEngine.TabIndex = 14;
this.labelEngine.Text = "Engine"; 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))); | System.Windows.Forms.AnchorStyles.Left)));
this.groupBoxMsSettings.Controls.Add(this.labelVoiceCount); this.groupBoxSettings.Controls.Add(this.labelRegion);
this.groupBoxMsSettings.Controls.Add(this.checkBoxShowPreview); this.groupBoxSettings.Controls.Add(this.nikseComboBoxRegion);
this.groupBoxMsSettings.Controls.Add(this.labelApiKey); this.groupBoxSettings.Controls.Add(this.labelVoiceCount);
this.groupBoxMsSettings.Controls.Add(this.nikseTextBoxApiKey); this.groupBoxSettings.Controls.Add(this.checkBoxShowPreview);
this.groupBoxMsSettings.Controls.Add(this.TextBoxTest); this.groupBoxSettings.Controls.Add(this.labelApiKey);
this.groupBoxMsSettings.Controls.Add(this.buttonTestVoice); this.groupBoxSettings.Controls.Add(this.nikseTextBoxApiKey);
this.groupBoxMsSettings.Controls.Add(this.checkBoxAddToVideoFile); this.groupBoxSettings.Controls.Add(this.TextBoxTest);
this.groupBoxMsSettings.Controls.Add(this.labelVoice); this.groupBoxSettings.Controls.Add(this.buttonTestVoice);
this.groupBoxMsSettings.Controls.Add(this.nikseComboBoxVoice); this.groupBoxSettings.Controls.Add(this.checkBoxAddToVideoFile);
this.groupBoxMsSettings.Controls.Add(this.labelEngine); this.groupBoxSettings.Controls.Add(this.labelVoice);
this.groupBoxMsSettings.Controls.Add(this.nikseComboBoxEngine); this.groupBoxSettings.Controls.Add(this.nikseComboBoxVoice);
this.groupBoxMsSettings.Location = new System.Drawing.Point(15, 12); this.groupBoxSettings.Controls.Add(this.labelEngine);
this.groupBoxMsSettings.Name = "groupBoxMsSettings"; this.groupBoxSettings.Controls.Add(this.nikseComboBoxEngine);
this.groupBoxMsSettings.Size = new System.Drawing.Size(391, 405); this.groupBoxSettings.Location = new System.Drawing.Point(15, 12);
this.groupBoxMsSettings.TabIndex = 1; this.groupBoxSettings.Name = "groupBoxSettings";
this.groupBoxMsSettings.TabStop = false; this.groupBoxSettings.Size = new System.Drawing.Size(391, 405);
this.groupBoxMsSettings.Text = "Settings"; 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 // checkBoxShowPreview
// //
@ -147,15 +231,37 @@
// //
this.labelApiKey.AutoSize = true; this.labelApiKey.AutoSize = true;
this.labelApiKey.ImeMode = System.Windows.Forms.ImeMode.NoControl; 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.Name = "labelApiKey";
this.labelApiKey.Size = new System.Drawing.Size(44, 13); this.labelApiKey.Size = new System.Drawing.Size(44, 13);
this.labelApiKey.TabIndex = 28; this.labelApiKey.TabIndex = 28;
this.labelApiKey.Text = "API key"; 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 // 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.Name = "buttonTestVoice";
this.buttonTestVoice.Size = new System.Drawing.Size(150, 23); this.buttonTestVoice.Size = new System.Drawing.Size(150, 23);
this.buttonTestVoice.TabIndex = 15; this.buttonTestVoice.TabIndex = 15;
@ -180,12 +286,80 @@
// //
this.labelVoice.AutoSize = true; this.labelVoice.AutoSize = true;
this.labelVoice.ImeMode = System.Windows.Forms.ImeMode.NoControl; 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.Name = "labelVoice";
this.labelVoice.Size = new System.Drawing.Size(34, 13); this.labelVoice.Size = new System.Drawing.Size(34, 13);
this.labelVoice.TabIndex = 16; this.labelVoice.TabIndex = 16;
this.labelVoice.Text = "Voice"; 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 // listViewActors
// //
this.listViewActors.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 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.UseVisualStyleBackColor = true;
this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click); 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 // TextToSpeech
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -336,13 +425,13 @@
this.Controls.Add(this.buttonCancel); this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.labelActors); this.Controls.Add(this.labelActors);
this.Controls.Add(this.listViewActors); this.Controls.Add(this.listViewActors);
this.Controls.Add(this.groupBoxMsSettings); this.Controls.Add(this.groupBoxSettings);
this.Controls.Add(this.progressBar1); this.Controls.Add(this.progressBar1);
this.Controls.Add(this.buttonGenerateTTS); this.Controls.Add(this.buttonGenerateTTS);
this.Controls.Add(this.labelProgress); this.Controls.Add(this.labelProgress);
this.Controls.Add(this.buttonOK); this.Controls.Add(this.buttonOK);
this.KeyPreview = true; this.KeyPreview = true;
this.MinimumSize = new System.Drawing.Size(827, 481); this.MinimumSize = new System.Drawing.Size(860, 520);
this.Name = "TextToSpeech"; this.Name = "TextToSpeech";
this.ShowIcon = false; this.ShowIcon = false;
this.ShowInTaskbar = false; this.ShowInTaskbar = false;
@ -354,8 +443,9 @@
this.ResizeEnd += new System.EventHandler(this.TextToSpeech_ResizeEnd); this.ResizeEnd += new System.EventHandler(this.TextToSpeech_ResizeEnd);
this.SizeChanged += new System.EventHandler(this.TextToSpeech_SizeChanged); this.SizeChanged += new System.EventHandler(this.TextToSpeech_SizeChanged);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextToSpeech_KeyDown); this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextToSpeech_KeyDown);
this.groupBoxMsSettings.ResumeLayout(false); this.groupBoxSettings.ResumeLayout(false);
this.groupBoxMsSettings.PerformLayout(); this.groupBoxSettings.PerformLayout();
this.contextMenuStripVoices.ResumeLayout(false);
this.ResumeLayout(false); this.ResumeLayout(false);
this.PerformLayout(); this.PerformLayout();
@ -368,7 +458,7 @@
private System.Windows.Forms.ProgressBar progressBar1; private System.Windows.Forms.ProgressBar progressBar1;
private Controls.NikseComboBox nikseComboBoxEngine; private Controls.NikseComboBox nikseComboBoxEngine;
private System.Windows.Forms.Label labelEngine; 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 System.Windows.Forms.Label labelVoice;
private Controls.NikseComboBox nikseComboBoxVoice; private Controls.NikseComboBox nikseComboBoxVoice;
private System.Windows.Forms.CheckBox checkBoxAddToVideoFile; private System.Windows.Forms.CheckBox checkBoxAddToVideoFile;
@ -384,5 +474,9 @@
private System.Windows.Forms.CheckBox checkBoxShowPreview; private System.Windows.Forms.CheckBox checkBoxShowPreview;
private System.Windows.Forms.Button buttonCancel; private System.Windows.Forms.Button buttonCancel;
private System.Windows.Forms.Label labelVoiceCount; 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;
} }
} }

View File

@ -33,7 +33,9 @@ namespace Nikse.SubtitleEdit.Forms.Tts
private bool _abort; private bool _abort;
private readonly List<string> _actors; private readonly List<string> _actors;
private readonly List<TextToSpeechEngine> _engines; private readonly List<TextToSpeechEngine> _engines;
private readonly List<PiperModel> _piperVoices;
private readonly List<ElevenLabModel> _elevenLabVoices; private readonly List<ElevenLabModel> _elevenLabVoices;
private readonly List<AzureVoiceModel> _azureVoices;
private bool _actorsOn; private bool _actorsOn;
private bool _converting; 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 public enum TextToSpeechEngineId
{ {
Piper, Piper,
@ -72,6 +88,7 @@ namespace Nikse.SubtitleEdit.Forms.Tts
Coqui, Coqui,
MsSpeechSynthesizer, MsSpeechSynthesizer,
ElevenLabs, ElevenLabs,
AzureTextToSpeech,
} }
public TextToSpeech(Subtitle subtitle, SubtitleFormat subtitleFormat, string videoFileName, VideoInfo videoInfo) public TextToSpeech(Subtitle subtitle, SubtitleFormat subtitleFormat, string videoFileName, VideoInfo videoInfo)
@ -84,7 +101,9 @@ namespace Nikse.SubtitleEdit.Forms.Tts
_subtitleFormat = subtitleFormat; _subtitleFormat = subtitleFormat;
_videoFileName = videoFileName; _videoFileName = videoFileName;
_videoInfo = videoInfo; _videoInfo = videoInfo;
_piperVoices = new List<PiperModel>();
_elevenLabVoices = new List<ElevenLabModel>(); _elevenLabVoices = new List<ElevenLabModel>();
_azureVoices = new List<AzureVoiceModel>();
_actors = _subtitle.Paragraphs _actors = _subtitle.Paragraphs
.Where(p => !string.IsNullOrEmpty(p.Actor)) .Where(p => !string.IsNullOrEmpty(p.Actor))
.Select(p => p.Actor) .Select(p => p.Actor)
@ -92,12 +111,15 @@ namespace Nikse.SubtitleEdit.Forms.Tts
.ToList(); .ToList();
Text = LanguageSettings.Current.TextToSpeech.Title; Text = LanguageSettings.Current.TextToSpeech.Title;
groupBoxSettings.Text = LanguageSettings.Current.Settings.Title;
labelVoice.Text = LanguageSettings.Current.TextToSpeech.Voice; labelVoice.Text = LanguageSettings.Current.TextToSpeech.Voice;
labelApiKey.Text = LanguageSettings.Current.VobSubOcr.ApiKey; labelApiKey.Text = LanguageSettings.Current.VobSubOcr.ApiKey;
buttonTestVoice.Text = LanguageSettings.Current.TextToSpeech.TestVoice; buttonTestVoice.Text = LanguageSettings.Current.TextToSpeech.TestVoice;
labelActors.Text = LanguageSettings.Current.TextToSpeech.ActorInfo; labelActors.Text = LanguageSettings.Current.TextToSpeech.ActorInfo;
checkBoxAddToVideoFile.Text = LanguageSettings.Current.TextToSpeech.AddAudioToVideo; checkBoxAddToVideoFile.Text = LanguageSettings.Current.TextToSpeech.AddAudioToVideo;
buttonGenerateTTS.Text = LanguageSettings.Current.TextToSpeech.GenerateSpeech; buttonGenerateTTS.Text = LanguageSettings.Current.TextToSpeech.GenerateSpeech;
labelRegion.Text = LanguageSettings.Current.General.Region;
checkBoxShowPreview.Text = LanguageSettings.Current.TextToSpeech.ReviewAudioClips;
buttonOK.Text = LanguageSettings.Current.General.Ok; buttonOK.Text = LanguageSettings.Current.General.Ok;
buttonCancel.Text = LanguageSettings.Current.General.Cancel; buttonCancel.Text = LanguageSettings.Current.General.Cancel;
UiUtil.FixLargeFonts(this, buttonOK); UiUtil.FixLargeFonts(this, buttonOK);
@ -108,13 +130,14 @@ namespace Nikse.SubtitleEdit.Forms.Tts
_engines = new List<TextToSpeechEngine>(); _engines = new List<TextToSpeechEngine>();
_engines.Add(new TextToSpeechEngine(TextToSpeechEngineId.Piper, "Piper (fast/good)", _engines.Count)); _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)); _engines.Add(new TextToSpeechEngine(TextToSpeechEngineId.Coqui, "Coqui AI TTS (only one voice)", _engines.Count));
if (Configuration.IsRunningOnWindows) if (Configuration.IsRunningOnWindows)
{ {
_engines.Add(new TextToSpeechEngine(TextToSpeechEngineId.MsSpeechSynthesizer, "Microsoft SpeechSynthesizer (very fast/robotic)", _engines.Count)); _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.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<ActorAndVoice>(); _actorAndVoices = new List<ActorAndVoice>();
nikseComboBoxEngine.DropDownStyle = ComboBoxStyle.DropDownList; nikseComboBoxEngine.DropDownStyle = ComboBoxStyle.DropDownList;
@ -135,22 +158,25 @@ namespace Nikse.SubtitleEdit.Forms.Tts
labelActors.Visible = false; labelActors.Visible = false;
listViewActors.Visible = false; listViewActors.Visible = false;
nikseComboBoxEngine_SelectedIndexChanged(null, null);
if (!SubtitleFormatHasActors() || !_actors.Any()) if (!SubtitleFormatHasActors() || !_actors.Any())
{ {
var w = groupBoxMsSettings.Width + 100; var w = groupBoxSettings.Width + 100;
var right = buttonCancel.Right; var right = buttonCancel.Right;
groupBoxMsSettings.Left = progressBar1.Left; groupBoxSettings.Left = progressBar1.Left;
groupBoxMsSettings.Width = right - progressBar1.Left; groupBoxSettings.Width = right - progressBar1.Left;
groupBoxMsSettings.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom; groupBoxSettings.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom;
Width = w; Width = w;
MinimumSize = new Size(w, MinimumSize.Height); MinimumSize = new Size(w, MinimumSize.Height);
Width = w; Width = w;
} }
nikseComboBoxEngine_SelectedIndexChanged(null, null);
nikseComboBoxEngine.SelectedIndexChanged += nikseComboBoxEngine_SelectedIndexChanged;
nikseComboBoxVoice.Text = Configuration.Settings.Tools.TextToSpeechLastVoice; nikseComboBoxVoice.Text = Configuration.Settings.Tools.TextToSpeechLastVoice;
checkBoxAddToVideoFile.Checked = Configuration.Settings.Tools.TextToSpeechAddToVideoFile;
checkBoxShowPreview.Checked = Configuration.Settings.Tools.TextToSpeechPreview;
} }
private void SetActor(ActorAndVoice actor) private void SetActor(ActorAndVoice actor)
@ -307,6 +333,12 @@ namespace Nikse.SubtitleEdit.Forms.Tts
return result; return result;
} }
if (engine.Id == TextToSpeechEngineId.AzureTextToSpeech)
{
var result = await GenerateParagraphAudioAzure(subtitle, showProgressBar, overrideFileName);
return result;
}
return false; return false;
} }
@ -594,7 +626,6 @@ namespace Nikse.SubtitleEdit.Forms.Tts
progressBar1.Value = 0; progressBar1.Value = 0;
progressBar1.Maximum = subtitle.Paragraphs.Count; progressBar1.Maximum = subtitle.Paragraphs.Count;
progressBar1.Visible = showProgressBar; progressBar1.Visible = showProgressBar;
var voices = PiperModels.GetVoices();
for (var index = 0; index < subtitle.Paragraphs.Count; index++) 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)) if (_actorAndVoices.Count > 0 && !string.IsNullOrEmpty(p.Actor))
{ {
var f = _actorAndVoices.FirstOrDefault(x => x.Actor == p.Actor); var f = _actorAndVoices.FirstOrDefault(x => x.Actor == p.Actor);
if (f != null && !string.IsNullOrEmpty(f.Voice)) 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; return true;
} }
private async Task<List<AzureVoiceModel>> 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<AzureVoiceModel>();
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<AzureVoiceModel>();
}
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<bool> 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 = $"<speak version='1.0' xml:lang='en-US'><voice xml:lang='en-US' xml:gender='{voice.Gender}' name='{voice.ShortName}'>{System.Net.WebUtility.HtmlEncode(p.Text)}</voice></speak>";
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) private void buttonOK_Click(object sender, EventArgs e)
{ {
EditedSubtitle = _subtitle; EditedSubtitle = _subtitle;
@ -913,6 +1109,8 @@ namespace Nikse.SubtitleEdit.Forms.Tts
labelApiKey.Visible = false; labelApiKey.Visible = false;
nikseTextBoxApiKey.Visible = false; nikseTextBoxApiKey.Visible = false;
labelRegion.Visible = false;
nikseComboBoxRegion.Visible = false;
labelVoice.Text = LanguageSettings.Current.TextToSpeech.Voice; labelVoice.Text = LanguageSettings.Current.TextToSpeech.Voice;
if (SubtitleFormatHasActors() && _actors.Any()) if (SubtitleFormatHasActors() && _actors.Any())
@ -937,7 +1135,12 @@ namespace Nikse.SubtitleEdit.Forms.Tts
if (engine.Id == TextToSpeechEngineId.Piper) 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()); nikseComboBoxVoice.Items.Add(voice.ToString());
} }
@ -983,7 +1186,7 @@ namespace Nikse.SubtitleEdit.Forms.Tts
if (_elevenLabVoices.Count == 0) if (_elevenLabVoices.Count == 0)
{ {
_elevenLabVoices.AddRange(GetElevenLabVoices()); _elevenLabVoices.AddRange(GetElevenLabVoices(true));
} }
foreach (var voice in _elevenLabVoices) 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) if (nikseComboBoxVoice.Items.Count > 0)
{ {
nikseComboBoxVoice.SelectedIndex = 0; nikseComboBoxVoice.SelectedIndex = 0;
@ -1025,7 +1244,7 @@ namespace Nikse.SubtitleEdit.Forms.Tts
if (engine.Id == TextToSpeechEngineId.Piper) if (engine.Id == TextToSpeechEngineId.Piper)
{ {
var voices = PiperModels.GetVoices(); var voices = _piperVoices;
foreach (var voiceLanguage in voices foreach (var voiceLanguage in voices
.GroupBy(p => p.Language) .GroupBy(p => p.Language)
.OrderBy(p => p.Key)) .OrderBy(p => p.Key))
@ -1062,10 +1281,101 @@ namespace Nikse.SubtitleEdit.Forms.Tts
parent.DropDownItems.Add(tsi); parent.DropDownItems.Add(tsi);
} }
if (Configuration.Settings.General.UseDarkTheme)
{
DarkTheme.SetDarkTheme(parent); 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<ToolStripItem>(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<ToolStripItem>(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);
}
}
}
}
}
else if (engine.Id == TextToSpeechEngineId.ElevenLabs) else if (engine.Id == TextToSpeechEngineId.ElevenLabs)
{ {
var voices = _elevenLabVoices; var voices = _elevenLabVoices;
@ -1105,12 +1415,16 @@ namespace Nikse.SubtitleEdit.Forms.Tts
parent.DropDownItems.Add(tsi); parent.DropDownItems.Add(tsi);
} }
if (Configuration.Settings.General.UseDarkTheme)
{
DarkTheme.SetDarkTheme(parent); DarkTheme.SetDarkTheme(parent);
} }
} }
} }
}
else else
{ {
var tsiList = new List<ToolStripItem>(nikseComboBoxVoice.Items.Count);
for (var index = 0; index < nikseComboBoxVoice.Items.Count; index++) for (var index = 0; index < nikseComboBoxVoice.Items.Count; index++)
{ {
var item = nikseComboBoxVoice.Items[index]; var item = nikseComboBoxVoice.Items[index];
@ -1123,8 +1437,10 @@ namespace Nikse.SubtitleEdit.Forms.Tts
var a = (ActorAndVoice)(x as ToolStripItem).Tag; var a = (ActorAndVoice)(x as ToolStripItem).Tag;
SetActor(a); SetActor(a);
}; };
contextMenuStripActors.Items.Add(tsi); tsiList.Add(tsi);
} }
contextMenuStripActors.Items.AddRange(tsiList.ToArray());
} }
labelActors.Visible = true; labelActors.Visible = true;
@ -1134,7 +1450,104 @@ namespace Nikse.SubtitleEdit.Forms.Tts
} }
} }
private List<ElevenLabModel> GetElevenLabVoices() private List<PiperModel> 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<PiperModel>();
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<ElevenLabModel> GetElevenLabVoices(bool useCache)
{ {
var ttsPath = Path.Combine(Configuration.DataDirectory, "TextToSpeech"); var ttsPath = Path.Combine(Configuration.DataDirectory, "TextToSpeech");
if (!Directory.Exists(ttsPath)) 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<ElevenLabModel>();
}
File.WriteAllBytes(jsonFileName, bytes);
}
if (File.Exists(jsonFileName)) if (File.Exists(jsonFileName))
{ {
var json = File.ReadAllText(jsonFileName); var json = File.ReadAllText(jsonFileName);
@ -1332,9 +1772,16 @@ namespace Nikse.SubtitleEdit.Forms.Tts
{ {
Configuration.Settings.Tools.TextToSpeechElevenLabsApiKey = nikseTextBoxApiKey.Text; 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.TextToSpeechEngine = engine.Id.ToString();
Configuration.Settings.Tools.TextToSpeechLastVoice = nikseComboBoxVoice.Text; 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) private void TextToSpeech_KeyDown(object sender, KeyEventArgs e)
@ -1356,21 +1803,26 @@ namespace Nikse.SubtitleEdit.Forms.Tts
public string GetParagraphAudio(Paragraph paragraph) public string GetParagraphAudio(Paragraph paragraph)
{ {
if (_actorsOn) if (_actorsOn && _actorAndVoices.Count > 0 && !string.IsNullOrEmpty(paragraph.Actor))
{
var f = _actorAndVoices.FirstOrDefault(x => x.Actor == paragraph.Actor);
if (f != null && !string.IsNullOrEmpty(f.Voice))
{ {
var engine = _engines.First(p => p.Index == nikseComboBoxEngine.SelectedIndex); var engine = _engines.First(p => p.Index == nikseComboBoxEngine.SelectedIndex);
if (engine.Id == TextToSpeechEngineId.Piper) if (engine.Id == TextToSpeechEngineId.Piper)
{ {
var voices = PiperModels.GetVoices(); return _piperVoices[f.VoiceIndex].ToString();
var voice = voices.First(x => x.ToString() == nikseComboBoxVoice.Text);
if (_actorAndVoices.Count > 0 && !string.IsNullOrEmpty(paragraph.Actor))
{
var f = _actorAndVoices.FirstOrDefault(x => x.Actor == paragraph.Actor);
if (f != null && !string.IsNullOrEmpty(f.Voice))
{
return voices[f.VoiceIndex].Voice;
} }
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; nikseComboBoxEngine.DropDownWidth = nikseComboBoxEngine.Width;
nikseComboBoxVoice.DropDownWidth = nikseComboBoxVoice.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;
}
}
} }
} }

View File

@ -117,6 +117,9 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<metadata name="contextMenuStripVoices.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>200, 17</value>
</metadata>
<metadata name="contextMenuStripActors.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="contextMenuStripActors.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value> <value>17, 17</value>
</metadata> </metadata>

View File

@ -145,18 +145,12 @@ namespace Nikse.SubtitleEdit.Forms.VTT
private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewExportStyles.Items) listViewExportStyles.CheckAll();
{
item.Checked = true;
}
} }
private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewExportStyles.Items) listViewExportStyles.InvertCheck();
{
item.Checked = !item.Checked;
}
} }
} }
} }

View File

@ -57,18 +57,12 @@ namespace Nikse.SubtitleEdit.Forms.VTT
private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e) private void toolStripMenuItemSelectAll_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewExportStyles.Items) listViewExportStyles.CheckAll();
{
item.Checked = true;
}
} }
private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e) private void toolStripMenuItemInverseSelection_Click(object sender, EventArgs e)
{ {
foreach (ListViewItem item in listViewExportStyles.Items) listViewExportStyles.InvertCheck();
{
item.Checked = !item.Checked;
}
} }
private void listViewExportStyles_SelectedIndexChanged(object sender, EventArgs e) private void listViewExportStyles_SelectedIndexChanged(object sender, EventArgs e)

View File

@ -1447,6 +1447,7 @@ Go to "Indstillinger -&gt; Indstillinger -&gt; Værktøj" for at indtaste din Bi
<RemoveOrExportShotChanges>Fjern/eksporter sceneændringer...</RemoveOrExportShotChanges> <RemoveOrExportShotChanges>Fjern/eksporter sceneændringer...</RemoveOrExportShotChanges>
<WaveformBatchGenerate>Batch generer bølgeformer...</WaveformBatchGenerate> <WaveformBatchGenerate>Batch generer bølgeformer...</WaveformBatchGenerate>
<ShowHideWaveformAndSpectrogram>Vis/skjul bølgeform og spektrogram</ShowHideWaveformAndSpectrogram> <ShowHideWaveformAndSpectrogram>Vis/skjul bølgeform og spektrogram</ShowHideWaveformAndSpectrogram>
<TextToSpeechAndAddToVideo>Tekst til tale og føj til video...</TextToSpeechAndAddToVideo>
<UnDockVideoControls>Pop video vinduer ud</UnDockVideoControls> <UnDockVideoControls>Pop video vinduer ud</UnDockVideoControls>
<ReDockVideoControls>Saml video vinduer</ReDockVideoControls> <ReDockVideoControls>Saml video vinduer</ReDockVideoControls>
</Video> </Video>
@ -2120,6 +2121,8 @@ Hvis du har redigeret denne fil med Subtitle Edit du måske finde en backup via
<EvenLines>Lige linjer</EvenLines> <EvenLines>Lige linjer</EvenLines>
<DurationLessThan>Varighed mindre end</DurationLessThan> <DurationLessThan>Varighed mindre end</DurationLessThan>
<DurationGreaterThan>Varighed større end</DurationGreaterThan> <DurationGreaterThan>Varighed større end</DurationGreaterThan>
<CpsLessThan>CPS mindre end</CpsLessThan>
<CpsGreaterThan>CPS større end</CpsGreaterThan>
<ExactlyOneLine>Præcis én linje</ExactlyOneLine> <ExactlyOneLine>Præcis én linje</ExactlyOneLine>
<ExactlyTwoLines>Præcis to linjer</ExactlyTwoLines> <ExactlyTwoLines>Præcis to linjer</ExactlyTwoLines>
<MoreThanTwoLines>Mere end to linjer</MoreThanTwoLines> <MoreThanTwoLines>Mere end to linjer</MoreThanTwoLines>
@ -3146,6 +3149,23 @@ Fortsæt?</RestoreDefaultSettingsMsg>
<Info>Et synkronisering punkt vil justere positioner, to eller flere synkroniserings punkter vil justere position og hastighed</Info> <Info>Et synkronisering punkt vil justere positioner, to eller flere synkroniserings punkter vil justere position og hastighed</Info>
<ApplySync>Anvend</ApplySync> <ApplySync>Anvend</ApplySync>
</PointSync> </PointSync>
<TextToSpeech>
<Title>Tekst til tale</Title>
<Voice>Stemme</Voice>
<TestVoice>Test stemme</TestVoice>
<DefaultVoice>Standardstemme</DefaultVoice>
<AddAudioToVideo>Tilføj lyd til videofil (ny fil)</AddAudioToVideo>
<GenerateSpeech>Generer tale fra tekst</GenerateSpeech>
<ActorInfo>Højreklik for at tildele skuespiller til stemme</ActorInfo>
<AdjustingSpeedXOfY>Justerer hastighed: {0} / {1}...</AdjustingSpeedXOfY>
<MergingAudioTrackXOfY>Samler lydspor: {0} / {1}...</MergingAudioTrackXOfY>
<GeneratingSpeechFromTextXOfY>Genererer tale fra tekst: {0} / {1}...</GeneratingSpeechFromTextXOfY>
<ReviewAudioClips>Gennemgå lydklip</ReviewAudioClips>
<ReviewInfo>Gennemgå og rediger/fjern lydklip</ReviewInfo>
<Play>Spil</Play>
<AutoContinue>Auto-fortsæt</AutoContinue>
<Regenerate>Regenerer</Regenerate>
</TextToSpeech>
<TimedTextSmpteTiming> <TimedTextSmpteTiming>
<Title>SMPTE timing</Title> <Title>SMPTE timing</Title>
<UseSmpteTiming>Vil du bruge SMPTE-timing til aktuelle undertekster?</UseSmpteTiming> <UseSmpteTiming>Vil du bruge SMPTE-timing til aktuelle undertekster?</UseSmpteTiming>

View File

@ -3,7 +3,7 @@
<General> <General>
<Title>Subtitle Edit</Title> <Title>Subtitle Edit</Title>
<Version>4.0.5</Version> <Version>4.0.5</Version>
<TranslatedBy>Tradotto da NAMP e bovirus - Data traduzione: 15.04.2024</TranslatedBy> <TranslatedBy>Tradotto da NAMP e bovirus - Data traduzione: 29.04.2024</TranslatedBy>
<CultureName>it-IT</CultureName> <CultureName>it-IT</CultureName>
<HelpFile /> <HelpFile />
<Ok>OK</Ok> <Ok>OK</Ok>
@ -1610,6 +1610,7 @@ Per usare una chiave API inserisci la chiave API di traduzione di Google in "Opz
<GoToSourceView>Vista sorgente</GoToSourceView> <GoToSourceView>Vista sorgente</GoToSourceView>
<GoToListView>Vista elenco</GoToListView> <GoToListView>Vista elenco</GoToListView>
<ExtractAudio>Estrai audio...</ExtractAudio> <ExtractAudio>Estrai audio...</ExtractAudio>
<MediaInfo>Info media</MediaInfo>
</ContextMenu> </ContextMenu>
</Menu> </Menu>
<Controls> <Controls>
@ -2129,6 +2130,8 @@ Vuoi scaricare mpv e youtuibe-dl e continuare?</VideoFromUrlRequirements>
<EvenLines>Righe uguali</EvenLines> <EvenLines>Righe uguali</EvenLines>
<DurationLessThan>Durata inferiore a</DurationLessThan> <DurationLessThan>Durata inferiore a</DurationLessThan>
<DurationGreaterThan>Durata maggiore di</DurationGreaterThan> <DurationGreaterThan>Durata maggiore di</DurationGreaterThan>
<CpsLessThan>CPS inferiore a</CpsLessThan>
<CpsGreaterThan>CPS superiore a</CpsGreaterThan>
<ExactlyOneLine>Esattamente una linea</ExactlyOneLine> <ExactlyOneLine>Esattamente una linea</ExactlyOneLine>
<ExactlyTwoLines>Esattamente due linee</ExactlyTwoLines> <ExactlyTwoLines>Esattamente due linee</ExactlyTwoLines>
<MoreThanTwoLines>Più di due righe</MoreThanTwoLines> <MoreThanTwoLines>Più di due righe</MoreThanTwoLines>
@ -3166,6 +3169,11 @@ Vuoi continuare?</RestoreDefaultSettingsMsg>
<AdjustingSpeedXOfY>Regolazione velocità: {0} / {1}...</AdjustingSpeedXOfY> <AdjustingSpeedXOfY>Regolazione velocità: {0} / {1}...</AdjustingSpeedXOfY>
<MergingAudioTrackXOfY>Unione traccia audio: {0} / {1}...</MergingAudioTrackXOfY> <MergingAudioTrackXOfY>Unione traccia audio: {0} / {1}...</MergingAudioTrackXOfY>
<GeneratingSpeechFromTextXOfY>Generazione parlato dal testo: {0} / {1}...</GeneratingSpeechFromTextXOfY> <GeneratingSpeechFromTextXOfY>Generazione parlato dal testo: {0} / {1}...</GeneratingSpeechFromTextXOfY>
<ReviewAudioClips>Rivedi clip audio</ReviewAudioClips>
<ReviewInfo>Rivedi e modifica/rimuovi clip audio</ReviewInfo>
<Play>Riproduci</Play>
<AutoContinue>Continua automaticamente</AutoContinue>
<Regenerate>Rigenera</Regenerate>
</TextToSpeech> </TextToSpeech>
<TimedTextSmpteTiming> <TimedTextSmpteTiming>
<Title>Tempistica SMPTE</Title> <Title>Tempistica SMPTE</Title>

View File

@ -1453,6 +1453,7 @@ Gå till "Alternativ -&gt; Inställningar -&gt; Verktyg" för att ange din nycke
<RemoveOrExportShotChanges>Ta bort/exportera bildändringar...</RemoveOrExportShotChanges> <RemoveOrExportShotChanges>Ta bort/exportera bildändringar...</RemoveOrExportShotChanges>
<WaveformBatchGenerate>Batch genererar vågformdata...</WaveformBatchGenerate> <WaveformBatchGenerate>Batch genererar vågformdata...</WaveformBatchGenerate>
<ShowHideWaveformAndSpectrogram>Visa/dölj ljudformat och spektrogram</ShowHideWaveformAndSpectrogram> <ShowHideWaveformAndSpectrogram>Visa/dölj ljudformat och spektrogram</ShowHideWaveformAndSpectrogram>
<TextToSpeechAndAddToVideo>Text till tal och lägg till video...</TextToSpeechAndAddToVideo>
<UnDockVideoControls>Avdocka videokontrollerna</UnDockVideoControls> <UnDockVideoControls>Avdocka videokontrollerna</UnDockVideoControls>
<ReDockVideoControls>Docka videokontrollerna</ReDockVideoControls> <ReDockVideoControls>Docka videokontrollerna</ReDockVideoControls>
</Video> </Video>
@ -2129,6 +2130,8 @@ Ladda ner och fortsätta?</VideoFromUrlRequirements>
<EvenLines>Jämna radnummer</EvenLines> <EvenLines>Jämna radnummer</EvenLines>
<DurationLessThan>Varaktighet kortare än</DurationLessThan> <DurationLessThan>Varaktighet kortare än</DurationLessThan>
<DurationGreaterThan>Varaktighet längre än</DurationGreaterThan> <DurationGreaterThan>Varaktighet längre än</DurationGreaterThan>
<CpsLessThan>CPS mindre än</CpsLessThan>
<CpsGreaterThan>CPS större än</CpsGreaterThan>
<ExactlyOneLine>Exakt en rad</ExactlyOneLine> <ExactlyOneLine>Exakt en rad</ExactlyOneLine>
<ExactlyTwoLines>Exakt två rader</ExactlyTwoLines> <ExactlyTwoLines>Exakt två rader</ExactlyTwoLines>
<MoreThanTwoLines>Mer än två rader</MoreThanTwoLines> <MoreThanTwoLines>Mer än två rader</MoreThanTwoLines>
@ -3156,6 +3159,23 @@ och N bryter</WrapStyle2>
<Info>En synkpunkt kommer att justera positionen. två eller flera synkroniseringspunkter kommer att justera position och hastighet</Info> <Info>En synkpunkt kommer att justera positionen. två eller flera synkroniseringspunkter kommer att justera position och hastighet</Info>
<ApplySync>Verkställ</ApplySync> <ApplySync>Verkställ</ApplySync>
</PointSync> </PointSync>
<TextToSpeech>
<Title>Text till tal</Title>
<Voice>Röst</Voice>
<TestVoice>Testa röst</TestVoice>
<DefaultVoice>Standardröst</DefaultVoice>
<AddAudioToVideo>Lägg till ljud till videofil (ny fil)</AddAudioToVideo>
<GenerateSpeech>Generera tal från text</GenerateSpeech>
<ActorInfo>Högerklicka för att tilldela skådespelare till röst</ActorInfo>
<AdjustingSpeedXOfY>Justerar hastighet: {0} / {1}...</AdjustingSpeedXOfY>
<MergingAudioTrackXOfY>Slår ihop ljudspår: {0} / {1}...</MergingAudioTrackXOfY>
<GeneratingSpeechFromTextXOfY>Genererar tal från text: {0} / {1}...</GeneratingSpeechFromTextXOfY>
<ReviewAudioClips>Granska ljudklipp</ReviewAudioClips>
<ReviewInfo>Granska och redigera/ta bort ljudklipp</ReviewInfo>
<Play>Spela</Play>
<AutoContinue>Auto-fortsätt</AutoContinue>
<Regenerate>Regenerera</Regenerate>
</TextToSpeech>
<TimedTextSmpteTiming> <TimedTextSmpteTiming>
<Title>SMPTE-timing</Title> <Title>SMPTE-timing</Title>
<UseSmpteTiming>Använd SMPTE-timing för aktuell undertext?</UseSmpteTiming> <UseSmpteTiming>Använd SMPTE-timing för aktuell undertext?</UseSmpteTiming>

View File

@ -2117,6 +2117,8 @@ Command line: {1} {2}
<EvenLines>匹配行</EvenLines> <EvenLines>匹配行</EvenLines>
<DurationLessThan>时长小于</DurationLessThan> <DurationLessThan>时长小于</DurationLessThan>
<DurationGreaterThan>时长大于</DurationGreaterThan> <DurationGreaterThan>时长大于</DurationGreaterThan>
<CpsLessThan>CPS 小于</CpsLessThan>
<CpsGreaterThan>CP S大于</CpsGreaterThan>
<ExactlyOneLine>正好一行</ExactlyOneLine> <ExactlyOneLine>正好一行</ExactlyOneLine>
<ExactlyTwoLines>正好两行</ExactlyTwoLines> <ExactlyTwoLines>正好两行</ExactlyTwoLines>
<MoreThanTwoLines>超过两行</MoreThanTwoLines> <MoreThanTwoLines>超过两行</MoreThanTwoLines>

View File

@ -2210,6 +2210,7 @@ namespace Nikse.SubtitleEdit.Logic
GoToSourceView = "Go to source view", GoToSourceView = "Go to source view",
GoToListView = "Go to list view", GoToListView = "Go to list view",
ExtractAudio = "Extract audio...", ExtractAudio = "Extract audio...",
MediaInfo = "Media information",
} }
}, },
@ -2461,6 +2462,8 @@ namespace Nikse.SubtitleEdit.Logic
EvenLines = "Even-numbered lines", EvenLines = "Even-numbered lines",
DurationLessThan = "Duration less than", DurationLessThan = "Duration less than",
DurationGreaterThan = "Duration greater than", DurationGreaterThan = "Duration greater than",
CpsLessThan = "CPS less than",
CpsGreaterThan = "CPS greater than",
ExactlyOneLine = "Exactly one line", ExactlyOneLine = "Exactly one line",
ExactlyTwoLines = "Exactly two lines", ExactlyTwoLines = "Exactly two lines",
MoreThanTwoLines = "More than two lines", MoreThanTwoLines = "More than two lines",
@ -3563,6 +3566,11 @@ can edit in same subtitle file (collaboration)",
AdjustingSpeedXOfY = "Adjusting speed: {0} / {1}...", AdjustingSpeedXOfY = "Adjusting speed: {0} / {1}...",
MergingAudioTrackXOfY = "Merging audio track: {0} / {1}...", MergingAudioTrackXOfY = "Merging audio track: {0} / {1}...",
GeneratingSpeechFromTextXOfY = "Generating speech from text: {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 TimedTextSmpteTiming = new LanguageStructure.TimedTextSmpteTiming

View File

@ -5170,6 +5170,9 @@ namespace Nikse.SubtitleEdit.Logic
case "Main/Menu/ContextMenu/ExtractAudio": case "Main/Menu/ContextMenu/ExtractAudio":
language.Main.Menu.ContextMenu.ExtractAudio = reader.Value; language.Main.Menu.ContextMenu.ExtractAudio = reader.Value;
break; break;
case "Main/Menu/ContextMenu/MediaInfo":
language.Main.Menu.ContextMenu.MediaInfo = reader.Value;
break;
case "Main/Controls/SubtitleFormat": case "Main/Controls/SubtitleFormat":
language.Main.Controls.SubtitleFormat = reader.Value; language.Main.Controls.SubtitleFormat = reader.Value;
break; break;
@ -5770,6 +5773,12 @@ namespace Nikse.SubtitleEdit.Logic
case "ModifySelection/DurationGreaterThan": case "ModifySelection/DurationGreaterThan":
language.ModifySelection.DurationGreaterThan = reader.Value; language.ModifySelection.DurationGreaterThan = reader.Value;
break; break;
case "ModifySelection/CpsLessThan":
language.ModifySelection.CpsLessThan = reader.Value;
break;
case "ModifySelection/CpsGreaterThan":
language.ModifySelection.CpsGreaterThan = reader.Value;
break;
case "ModifySelection/ExactlyOneLine": case "ModifySelection/ExactlyOneLine":
language.ModifySelection.ExactlyOneLine = reader.Value; language.ModifySelection.ExactlyOneLine = reader.Value;
break; break;
@ -8671,6 +8680,21 @@ namespace Nikse.SubtitleEdit.Logic
case "TextToSpeech/GeneratingSpeechFromTextXOfY": case "TextToSpeech/GeneratingSpeechFromTextXOfY":
language.TextToSpeech.GeneratingSpeechFromTextXOfY = reader.Value; language.TextToSpeech.GeneratingSpeechFromTextXOfY = reader.Value;
break; 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": case "TimedTextSmpteTiming/Title":
language.TimedTextSmpteTiming.Title = reader.Value; language.TimedTextSmpteTiming.Title = reader.Value;
break; break;

View File

@ -2015,6 +2015,7 @@
public string GoToSourceView { get; set; } public string GoToSourceView { get; set; }
public string GoToListView { get; set; } public string GoToListView { get; set; }
public string ExtractAudio { get; set; } public string ExtractAudio { get; set; }
public string MediaInfo { get; set; }
} }
public FileMenu File { get; set; } public FileMenu File { get; set; }
@ -2271,6 +2272,8 @@
public string EvenLines { get; set; } public string EvenLines { get; set; }
public string DurationLessThan { get; set; } public string DurationLessThan { get; set; }
public string DurationGreaterThan { get; set; } public string DurationGreaterThan { get; set; }
public string CpsLessThan { get; set; }
public string CpsGreaterThan { get; set; }
public string ExactlyOneLine { get; set; } public string ExactlyOneLine { get; set; }
public string ExactlyTwoLines { get; set; } public string ExactlyTwoLines { get; set; }
public string MoreThanTwoLines { get; set; } public string MoreThanTwoLines { get; set; }
@ -3372,6 +3375,11 @@
public string AdjustingSpeedXOfY { get; set; } public string AdjustingSpeedXOfY { get; set; }
public string MergingAudioTrackXOfY { get; set; } public string MergingAudioTrackXOfY { get; set; }
public string GeneratingSpeechFromTextXOfY { 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 public class TimedTextSmpteTiming

View File

@ -13,7 +13,8 @@ namespace Nikse.SubtitleEdit.Logic
public bool IsDisplayFileSize { get; set; } public bool IsDisplayFileSize { get; set; }
public bool Descending { 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) public int Compare(object o1, object o2)
{ {
@ -32,7 +33,7 @@ namespace Nikse.SubtitleEdit.Logic
var s1 = lvi1.SubItems[ColumnNumber].Text; var s1 = lvi1.SubItems[ColumnNumber].Text;
var s2 = lvi2.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(s1, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var i1) &&
int.TryParse(s2, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var i2)) 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 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);
} }
} }
} }

View File

@ -1121,6 +1121,36 @@ namespace Nikse.SubtitleEdit.Logic
public static void AutoSizeLastColumn(this ListView listView) => public static void AutoSizeLastColumn(this ListView listView) =>
listView.Columns[listView.Columns.Count - 1].Width = -2; 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) public static void SelectAll(this ListView lv)
{ {
lv.BeginUpdate(); lv.BeginUpdate();

View File

@ -271,7 +271,7 @@ namespace Nikse.SubtitleEdit.Logic
StartInfo = StartInfo =
{ {
FileName = GetFfmpegLocation(), 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, UseShellExecute = false,
CreateNoWindow = true, CreateNoWindow = true,
WorkingDirectory = Path.GetDirectoryName(assaSubtitleFileName) ?? string.Empty, WorkingDirectory = Path.GetDirectoryName(assaSubtitleFileName) ?? string.Empty,

Binary file not shown.

Binary file not shown.

View File

@ -2454,7 +2454,9 @@
<EmbeddedResource Include="Resources\HunspellBackupDictionaries.xml.gz" /> <EmbeddedResource Include="Resources\HunspellBackupDictionaries.xml.gz" />
<EmbeddedResource Include="Resources\TesseractDictionaries.xml.gz" /> <EmbeddedResource Include="Resources\TesseractDictionaries.xml.gz" />
<EmbeddedResource Include="Resources\eleven-labs-voices.zip" /> <EmbeddedResource Include="Resources\eleven-labs-voices.zip" />
<EmbeddedResource Include="Resources\AzureVoices.zip" />
<None Include="Resources\nOCR_TesseractHelper.xml.gz" /> <None Include="Resources\nOCR_TesseractHelper.xml.gz" />
<EmbeddedResource Include="Resources\PiperVoices.zip" />
<None Include="Resources\SMPTE-428-7-2007-DCST.xsd"> <None Include="Resources\SMPTE-428-7-2007-DCST.xsd">
<SubType>Designer</SubType> <SubType>Designer</SubType>
</None> </None>