Testing tts

This commit is contained in:
Nikolaj Olsson 2024-04-08 22:22:00 +02:00
parent a4db942d37
commit 3ab1074e71
4 changed files with 523 additions and 48 deletions

View File

@ -19027,7 +19027,7 @@ namespace Nikse.SubtitleEdit.Forms
} }
else if (e.Modifiers == (Keys.Alt | Keys.Shift | Keys.Control) && e.KeyCode == Keys.T) else if (e.Modifiers == (Keys.Alt | Keys.Shift | Keys.Control) && e.KeyCode == Keys.T)
{ {
using (var form = new TextToSpeech(_subtitle, _videoFileName)) using (var form = new TextToSpeech(_subtitle, _videoFileName, _videoInfo))
{ {
if (form.ShowDialog(this) != DialogResult.OK) if (form.ShowDialog(this) != DialogResult.OK)
{ {

View File

@ -29,9 +29,15 @@
private void InitializeComponent() private void InitializeComponent()
{ {
this.buttonOK = new System.Windows.Forms.Button(); this.buttonOK = new System.Windows.Forms.Button();
this.labelDescription = new System.Windows.Forms.Label(); this.labelProgress = new System.Windows.Forms.Label();
this.button1 = new System.Windows.Forms.Button(); this.buttonGenerateTTS = new System.Windows.Forms.Button();
this.textBox1 = new Nikse.SubtitleEdit.Controls.NikseTextBox(); this.progressBar1 = new System.Windows.Forms.ProgressBar();
this.labelEngine = new System.Windows.Forms.Label();
this.groupBoxMsSettings = new System.Windows.Forms.GroupBox();
this.labelMsVoice = new System.Windows.Forms.Label();
this.nikseComboBoxVoice = new Nikse.SubtitleEdit.Controls.NikseComboBox();
this.nikseComboBoxEngine = new Nikse.SubtitleEdit.Controls.NikseComboBox();
this.groupBoxMsSettings.SuspendLayout();
this.SuspendLayout(); this.SuspendLayout();
// //
// buttonOK // buttonOK
@ -46,50 +52,144 @@
this.buttonOK.UseVisualStyleBackColor = true; this.buttonOK.UseVisualStyleBackColor = true;
this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click); this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click);
// //
// labelDescription // labelProgress
// //
this.labelDescription.AutoSize = true; this.labelProgress.AutoSize = true;
this.labelDescription.ImeMode = System.Windows.Forms.ImeMode.NoControl; this.labelProgress.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.labelDescription.Location = new System.Drawing.Point(9, 33); this.labelProgress.Location = new System.Drawing.Point(12, 384);
this.labelDescription.Name = "labelDescription"; this.labelProgress.Name = "labelProgress";
this.labelDescription.Size = new System.Drawing.Size(76, 13); this.labelProgress.Size = new System.Drawing.Size(70, 13);
this.labelDescription.TabIndex = 9; this.labelProgress.TabIndex = 9;
this.labelDescription.Text = "Name of voice"; this.labelProgress.Text = "labelProgress";
// //
// button1 // buttonGenerateTTS
// //
this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.buttonGenerateTTS.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.button1.ImeMode = System.Windows.Forms.ImeMode.NoControl; this.buttonGenerateTTS.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.button1.Location = new System.Drawing.Point(12, 75); this.buttonGenerateTTS.Location = new System.Drawing.Point(571, 374);
this.button1.Name = "button1"; this.buttonGenerateTTS.Name = "buttonGenerateTTS";
this.button1.Size = new System.Drawing.Size(75, 23); this.buttonGenerateTTS.Size = new System.Drawing.Size(228, 23);
this.button1.TabIndex = 11; this.buttonGenerateTTS.TabIndex = 11;
this.button1.Text = "Go"; this.buttonGenerateTTS.Text = "Generate speech from text";
this.button1.UseVisualStyleBackColor = true; this.buttonGenerateTTS.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click); this.buttonGenerateTTS.Click += new System.EventHandler(this.ButtonGenerateTtsClick);
// //
// textBox1 // progressBar1
// //
this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right))); | System.Windows.Forms.AnchorStyles.Right)));
this.textBox1.FocusedColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215))))); this.progressBar1.Location = new System.Drawing.Point(12, 407);
this.textBox1.Location = new System.Drawing.Point(12, 49); this.progressBar1.Name = "progressBar1";
this.textBox1.Name = "textBox1"; this.progressBar1.Size = new System.Drawing.Size(706, 23);
this.textBox1.Size = new System.Drawing.Size(229, 20); this.progressBar1.TabIndex = 12;
this.textBox1.TabIndex = 10; //
this.textBox1.Text = "Hello, how are you?"; // labelEngine
//
this.labelEngine.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.labelEngine.AutoSize = true;
this.labelEngine.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.labelEngine.Location = new System.Drawing.Point(405, 12);
this.labelEngine.Name = "labelEngine";
this.labelEngine.Size = new System.Drawing.Size(40, 13);
this.labelEngine.TabIndex = 14;
this.labelEngine.Text = "Engine";
//
// groupBoxMsSettings
//
this.groupBoxMsSettings.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Right)));
this.groupBoxMsSettings.Controls.Add(this.labelMsVoice);
this.groupBoxMsSettings.Controls.Add(this.nikseComboBoxVoice);
this.groupBoxMsSettings.Location = new System.Drawing.Point(408, 57);
this.groupBoxMsSettings.Name = "groupBoxMsSettings";
this.groupBoxMsSettings.Size = new System.Drawing.Size(391, 311);
this.groupBoxMsSettings.TabIndex = 15;
this.groupBoxMsSettings.TabStop = false;
this.groupBoxMsSettings.Text = "Settings";
//
// labelMsVoice
//
this.labelMsVoice.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.labelMsVoice.AutoSize = true;
this.labelMsVoice.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.labelMsVoice.Location = new System.Drawing.Point(14, 25);
this.labelMsVoice.Name = "labelMsVoice";
this.labelMsVoice.Size = new System.Drawing.Size(34, 13);
this.labelMsVoice.TabIndex = 16;
this.labelMsVoice.Text = "Voice";
//
// nikseComboBoxVoice
//
this.nikseComboBoxVoice.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | 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 = 195;
this.nikseComboBoxVoice.FormattingEnabled = false;
this.nikseComboBoxVoice.Location = new System.Drawing.Point(17, 41);
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 = 15;
this.nikseComboBoxVoice.UsePopupWindow = false;
//
// nikseComboBoxEngine
//
this.nikseComboBoxEngine.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | 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 = 195;
this.nikseComboBoxEngine.FormattingEnabled = false;
this.nikseComboBoxEngine.Location = new System.Drawing.Point(408, 28);
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(391, 23);
this.nikseComboBoxEngine.TabIndex = 13;
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);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(811, 442); this.ClientSize = new System.Drawing.Size(811, 442);
this.Controls.Add(this.button1); this.Controls.Add(this.groupBoxMsSettings);
this.Controls.Add(this.textBox1); this.Controls.Add(this.labelEngine);
this.Controls.Add(this.labelDescription); this.Controls.Add(this.nikseComboBoxEngine);
this.Controls.Add(this.progressBar1);
this.Controls.Add(this.buttonGenerateTTS);
this.Controls.Add(this.labelProgress);
this.Controls.Add(this.buttonOK); this.Controls.Add(this.buttonOK);
this.KeyPreview = true;
this.MinimumSize = new System.Drawing.Size(827, 481);
this.Name = "TextToSpeech"; this.Name = "TextToSpeech";
this.Text = "TextToSpeach"; this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Text to speach";
this.groupBoxMsSettings.ResumeLayout(false);
this.groupBoxMsSettings.PerformLayout();
this.ResumeLayout(false); this.ResumeLayout(false);
this.PerformLayout(); this.PerformLayout();
@ -97,8 +197,13 @@
#endregion #endregion
private System.Windows.Forms.Button buttonOK; private System.Windows.Forms.Button buttonOK;
private Controls.NikseTextBox textBox1; private System.Windows.Forms.Label labelProgress;
private System.Windows.Forms.Label labelDescription; private System.Windows.Forms.Button buttonGenerateTTS;
private System.Windows.Forms.Button button1; private System.Windows.Forms.ProgressBar progressBar1;
private Controls.NikseComboBox nikseComboBoxEngine;
private System.Windows.Forms.Label labelEngine;
private System.Windows.Forms.GroupBox groupBoxMsSettings;
private System.Windows.Forms.Label labelMsVoice;
private Controls.NikseComboBox nikseComboBoxVoice;
} }
} }

View File

@ -1,5 +1,10 @@
using Nikse.SubtitleEdit.Logic; using Nikse.SubtitleEdit.Core.Common;
using Nikse.SubtitleEdit.Logic;
using System; using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Speech.Synthesis; using System.Speech.Synthesis;
using System.Windows.Forms; using System.Windows.Forms;
@ -7,33 +12,322 @@ namespace Nikse.SubtitleEdit.Forms
{ {
public partial class TextToSpeech : Form public partial class TextToSpeech : Form
{ {
public TextToSpeech(Core.Common.Subtitle subtitle, string videoFileName) private readonly Subtitle _subtitle;
private readonly string _videoFileName;
private readonly VideoInfo _videoInfo;
private string _waveFolder;
public TextToSpeech(Subtitle subtitle, string videoFileName, VideoInfo videoInfo)
{ {
UiUtil.PreInitialize(this); UiUtil.PreInitialize(this);
InitializeComponent(); InitializeComponent();
UiUtil.FixFonts(this); UiUtil.FixFonts(this);
_subtitle = subtitle;
_videoFileName = videoFileName;
_videoInfo = videoInfo;
buttonOK.Text = LanguageSettings.Current.General.Ok; buttonOK.Text = LanguageSettings.Current.General.Ok;
UiUtil.FixLargeFonts(this, buttonOK); UiUtil.FixLargeFonts(this, buttonOK);
progressBar1.Visible = false;
labelProgress.Text = string.Empty;
nikseComboBoxEngine.DropDownStyle = ComboBoxStyle.DropDownList;
nikseComboBoxEngine.Items.Clear();
nikseComboBoxEngine.Items.Add("Microsoft SpeechSynthesizer (fast/robotic)");
nikseComboBoxEngine.Items.Add("Tortoise TTS (very slow/very good)");
nikseComboBoxEngine.Items.Add("Mimic3");
nikseComboBoxEngine.SelectedIndex = 0;
} }
private void button1_Click(object sender, EventArgs e) private void ButtonGenerateTtsClick(object sender, EventArgs e)
{ {
var text = textBox1.Text; _waveFolder = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(_waveFolder);
using (SpeechSynthesizer synth = new SpeechSynthesizer()) if (nikseComboBoxEngine.SelectedIndex == 0)
{ {
synth.SetOutputToWaveFile(@"C:\data\Sample.wav"); GenerateParagraphAudioMs();
synth.SelectVoiceByHints(VoiceGender.Male, VoiceAge.Adult); }
else if (nikseComboBoxEngine.SelectedIndex == 1)
{
GenerateParagraphAudioTortoiseTts();
}
var fileNames = FixParagraphAudioSpeed();
// rename result file
var tempAudioFile = MergeAudioParagraphs(fileNames);
var resultAudioFileName = Path.Combine(Path.GetDirectoryName(tempAudioFile), Path.GetFileNameWithoutExtension(_videoFileName) + ".wav");
File.Move(tempAudioFile, resultAudioFileName);
Cleanup(_waveFolder, resultAudioFileName);
UiUtil.OpenFolder(_waveFolder);
}
private static void Cleanup(string waveFolder, string resultAudioFile)
{
foreach (var fileName in Directory.GetFiles(waveFolder, "*.wav"))
{
if (!fileName.Equals(resultAudioFile, StringComparison.OrdinalIgnoreCase))
{
File.Delete(fileName);
}
}
}
private List<string> FixParagraphAudioSpeed()
{
var fileNames = new List<string>(_subtitle.Paragraphs.Count);
labelProgress.Text = "Adjusting speed...";
labelProgress.Refresh();
Application.DoEvents();
progressBar1.Value = 0;
progressBar1.Maximum = _subtitle.Paragraphs.Count;
progressBar1.Visible = true;
for (var index = 0; index < _subtitle.Paragraphs.Count; index++)
{
progressBar1.Value = index + 1;
labelProgress.Text = $"Adjusting speed: {index + 1} / {_subtitle.Paragraphs.Count}...";
var p = _subtitle.Paragraphs[index];
var next = _subtitle.GetParagraphOrDefault(index + 1);
var pFileName = Path.Combine(_waveFolder, index + ".wav");
var addDuration = 0d;
if (next != null && p.EndTime.TotalMilliseconds < next.StartTime.TotalMilliseconds)
{
var diff = next.StartTime.TotalMilliseconds - p.EndTime.TotalMilliseconds;
addDuration = Math.Max(1000, diff);
}
var outputFileName1 = Path.Combine(_waveFolder, index + "_u.wav");
var trimProcess = VideoPreviewGenerator.TrimSilenceStartAndEnd(pFileName, outputFileName1);
trimProcess.Start();
trimProcess.WaitForExit();
var waveInfo = UiUtil.GetVideoInfo(outputFileName1);
if (waveInfo.TotalMilliseconds <= p.DurationTotalMilliseconds + addDuration)
{
fileNames.Add(outputFileName1);
continue;
}
var factor = waveInfo.TotalMilliseconds / (p.DurationTotalMilliseconds + addDuration);
var outputFileName2 = Path.Combine(_waveFolder, index + "_t.wav");
fileNames.Add(outputFileName2);
var mergeProcess = VideoPreviewGenerator.ChangeSpeed(outputFileName1, outputFileName2, (float)factor);
mergeProcess.Start();
mergeProcess.WaitForExit();
}
return fileNames;
}
private string MergeAudioParagraphs(List<string> fileNames)
{
labelProgress.Text = "Merging audio track...";
labelProgress.Refresh();
Application.DoEvents();
var silenceFileName = Path.Combine(_waveFolder, "silence.wav");
var silenceProcess = VideoPreviewGenerator.GenerateEmptyAudio(silenceFileName, (float)_videoInfo.TotalSeconds);
silenceProcess.Start();
silenceProcess.WaitForExit();
progressBar1.Value = 0;
progressBar1.Maximum = _subtitle.Paragraphs.Count;
progressBar1.Visible = true;
var inputFileName = silenceFileName;
var outputFileName = string.Empty;
for (var index = 0; index < fileNames.Count; index++)
{
progressBar1.Value = index + 1;
labelProgress.Text = $"Merging audio track: {index + 1} / {_subtitle.Paragraphs.Count}...";
var p = _subtitle.Paragraphs[index];
var pFileName = fileNames[index];
outputFileName = Path.Combine(_waveFolder, $"silence{index}.wav");
var mergeProcess = VideoPreviewGenerator.MergeAudioTracks(inputFileName, pFileName, outputFileName, (float)p.StartTime.TotalSeconds);
inputFileName = outputFileName;
mergeProcess.Start();
mergeProcess.WaitForExit();
}
progressBar1.Visible = false;
labelProgress.Text = string.Empty;
return outputFileName;
}
private void GenerateParagraphAudioMs()
{
progressBar1.Value = 0;
progressBar1.Maximum = _subtitle.Paragraphs.Count;
progressBar1.Visible = true;
using (var synthesizer = new SpeechSynthesizer())
{
VoiceInfo voiceInfo = null;
var vs = synthesizer.GetInstalledVoices().Where(p => p.Enabled).ToList();
for (var index = 0; index < vs.Count; index++)
{
var v = vs[index];
if (index == nikseComboBoxVoice.SelectedIndex)
{
synthesizer.SelectVoice(v.VoiceInfo.Name);
voiceInfo = v.VoiceInfo;
}
}
for (var index = 0; index < _subtitle.Paragraphs.Count; index++)
{
progressBar1.Value = index + 1;
labelProgress.Text = $"Generating audio texts: {index + 1} / {_subtitle.Paragraphs.Count}...";
var p = _subtitle.Paragraphs[index];
synthesizer.SetOutputToWaveFile(Path.Combine(_waveFolder, index + ".wav"));
var builder = new PromptBuilder(); var builder = new PromptBuilder();
builder.AppendText(text); if (voiceInfo != null)
synth.Speak(builder); {
builder.StartVoice(voiceInfo);
} }
builder.AppendText(p.Text);
if (voiceInfo != null)
{
builder.EndVoice();
}
synthesizer.Speak(builder);
progressBar1.Refresh();
labelProgress.Refresh();
Application.DoEvents();
}
}
progressBar1.Visible = false;
labelProgress.Text = string.Empty;
}
private bool GenerateParagraphAudioTortoiseTts()
{
var pythonFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
"AppData",
"Local",
"Programs",
"Python");
var pyFileName = "do_tts.py";
var voice = nikseComboBoxVoice.Text;
var files = Directory.EnumerateFiles(pythonFolder, pyFileName, SearchOption.AllDirectories).ToList();
if (files.Count == 0)
{
MessageBox.Show($"{pyFileName} not found under {pythonFolder}");
return false;
}
var pythonFolderVersionFolder = files[0].Substring(pythonFolder.Length).Split(new char[] { Path.DirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries);
var pythonExe = Path.Combine(pythonFolder, pythonFolderVersionFolder[0], "python.exe");
if (!File.Exists(pythonExe))
{
pythonExe = "python.exe";
}
progressBar1.Value = 0;
progressBar1.Maximum = _subtitle.Paragraphs.Count;
progressBar1.Visible = true;
for (var index = 0; index < _subtitle.Paragraphs.Count; index++)
{
progressBar1.Value = index + 1;
labelProgress.Text = $"Generating audio texts: {index + 1} / {_subtitle.Paragraphs.Count}...";
var p = _subtitle.Paragraphs[index];
var outputFileName = Path.Combine(_waveFolder, index + ".wav");
var processTortoiseTts = new Process
{
StartInfo =
{
WorkingDirectory = Path.GetDirectoryName(files[0]),
FileName = pythonExe,
Arguments = $"do_tts.py --output_path \"{_waveFolder}\" --preset ultra_fast --voice {voice} --text \"{p.Text.RemoveChar('"')}\"",
UseShellExecute = false,
CreateNoWindow = true,
}
};
processTortoiseTts.Start();
processTortoiseTts.WaitForExit();
var inputFile = Path.Combine(_waveFolder, $"{voice}_0_2.wav");
File.Move(inputFile, outputFileName);
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)
{ {
DialogResult = DialogResult.OK; DialogResult = DialogResult.OK;
} }
private void nikseComboBoxEngine_SelectedIndexChanged(object sender, EventArgs e)
{
nikseComboBoxVoice.Items.Clear();
if (nikseComboBoxEngine.SelectedIndex == 0)
{
using (var synthesizer = new SpeechSynthesizer())
{
foreach (var v in synthesizer.GetInstalledVoices())
{
if (v.Enabled)
{
nikseComboBoxVoice.Items.Add(v.VoiceInfo.Name);
}
}
}
}
if (nikseComboBoxEngine.SelectedIndex == 1)
{
nikseComboBoxVoice.Items.Add("angie");
nikseComboBoxVoice.Items.Add("applejack");
nikseComboBoxVoice.Items.Add("daniel");
nikseComboBoxVoice.Items.Add("deniro");
nikseComboBoxVoice.Items.Add("emma");
nikseComboBoxVoice.Items.Add("freeman");
nikseComboBoxVoice.Items.Add("geralt");
nikseComboBoxVoice.Items.Add("halle");
nikseComboBoxVoice.Items.Add("jlaw");
nikseComboBoxVoice.Items.Add("lj");
nikseComboBoxVoice.Items.Add("mol");
nikseComboBoxVoice.Items.Add("myself");
nikseComboBoxVoice.Items.Add("pat");
nikseComboBoxVoice.Items.Add("pat2");
nikseComboBoxVoice.Items.Add("rainbow");
nikseComboBoxVoice.Items.Add("Update rainbow");
nikseComboBoxVoice.Items.Add("snakes");
nikseComboBoxVoice.Items.Add("tim_reynolds");
nikseComboBoxVoice.Items.Add("tom");
nikseComboBoxVoice.Items.Add("weaver");
nikseComboBoxVoice.Items.Add("william");
}
if (nikseComboBoxVoice.Items.Count > 0)
{
nikseComboBoxVoice.SelectedIndex = 0;
}
}
} }
} }

View File

@ -75,6 +75,42 @@ namespace Nikse.SubtitleEdit.Logic
return processMakeVideo; return processMakeVideo;
} }
public static Process GenerateEmptyAudio(string outputFileName, float seconds, DataReceivedEventHandler dataReceivedHandler = null)
{
var processMakeVideo = new Process
{
StartInfo =
{
FileName = GetFfmpegLocation(),
Arguments = $"-f lavfi -i anullsrc -t {seconds.ToString(CultureInfo.InvariantCulture)} \"{outputFileName}\"",
UseShellExecute = false,
CreateNoWindow = true
}
};
SetupDataReceiveHandler(dataReceivedHandler, processMakeVideo);
return processMakeVideo;
}
public static Process MergeAudioTracks(string inputFileName1, string inputFileName2, string outputFileName, float startSeconds, DataReceivedEventHandler dataReceivedHandler = null)
{
var processMakeVideo = new Process
{
StartInfo =
{
FileName = GetFfmpegLocation(),
Arguments = $"-i \"{inputFileName1}\" -i \"{inputFileName2}\" -filter_complex \"aevalsrc=0:d={startSeconds.ToString(CultureInfo.InvariantCulture)}[s1];[s1][1:a]concat=n=2:v=0:a=1[ac1];[0:a][ac1]amix=2:normalize=false[aout]\" -map [aout] \"{outputFileName}\"",
UseShellExecute = false,
CreateNoWindow = true
}
};
SetupDataReceiveHandler(dataReceivedHandler, processMakeVideo);
return processMakeVideo;
}
private static void SetupDataReceiveHandler(DataReceivedEventHandler dataReceivedHandler, Process processMakeVideo) private static void SetupDataReceiveHandler(DataReceivedEventHandler dataReceivedHandler, Process processMakeVideo)
{ {
if (dataReceivedHandler != null) if (dataReceivedHandler != null)
@ -546,5 +582,45 @@ namespace Nikse.SubtitleEdit.Logic
SetupDataReceiveHandler(outputHandler, processMakeVideo); SetupDataReceiveHandler(outputHandler, processMakeVideo);
return processMakeVideo; return processMakeVideo;
} }
public static Process ChangeSpeed(string inputFileName, string outputFileName, float inputSpeed, DataReceivedEventHandler dataReceivedHandler = null)
{
var speed = Math.Max(0.5f, inputSpeed);
speed = Math.Min(100, speed);
speed = (float)Math.Round(speed, 3, MidpointRounding.AwayFromZero);
var processMakeVideo = new Process
{
StartInfo =
{
FileName = GetFfmpegLocation(),
Arguments = $"-i \"{inputFileName}\" -filter:a \"atempo={speed.ToString(CultureInfo.InvariantCulture)}\" \"{outputFileName}\"",
UseShellExecute = false,
CreateNoWindow = true
}
};
SetupDataReceiveHandler(dataReceivedHandler, processMakeVideo);
return processMakeVideo;
}
public static Process TrimSilenceStartAndEnd(string inputFileName, string outputFileName, DataReceivedEventHandler dataReceivedHandler = null)
{
var processMakeVideo = new Process
{
StartInfo =
{
FileName = GetFfmpegLocation(),
Arguments = $"-i \"{inputFileName}\" -af silenceremove=start_periods=1:start_silence=0.01,areverse,silenceremove=start_periods=1:start_silence=0.01,areverse \"{outputFileName}\"",
UseShellExecute = false,
CreateNoWindow = true
}
};
SetupDataReceiveHandler(dataReceivedHandler, processMakeVideo);
return processMakeVideo;
}
} }
} }