From 1a6d3bf01b33b134a31566c64fb7b103435b9ffd Mon Sep 17 00:00:00 2001 From: Nikolaj Olsson Date: Wed, 28 Aug 2024 18:44:47 +0200 Subject: [PATCH] Fix for batch translate via Ollama - thx Anon1337Elite :) Fix #8771 --- src/libse/AutoTranslate/OllamaTranslate.cs | 2 +- src/libse/Settings/Settings.cs | 7 +++ src/libse/Settings/ToolsSettings.cs | 2 + src/ui/Forms/BatchConvert.Designer.cs | 41 +++++++++++++++- src/ui/Forms/BatchConvert.cs | 55 +++++++++++++++++++--- 5 files changed, 98 insertions(+), 9 deletions(-) diff --git a/src/libse/AutoTranslate/OllamaTranslate.cs b/src/libse/AutoTranslate/OllamaTranslate.cs index 70e1847ed..dc6653bb8 100644 --- a/src/libse/AutoTranslate/OllamaTranslate.cs +++ b/src/libse/AutoTranslate/OllamaTranslate.cs @@ -61,7 +61,7 @@ namespace Nikse.SubtitleEdit.Core.AutoTranslate var input = "{ " + modelJson + " \"prompt\": \"" + prompt + "\\n\\n" + Json.EncodeJsonText(text.Trim()) + "\", \"stream\": false }"; var content = new StringContent(input, Encoding.UTF8); content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); - var result = await _httpClient.PostAsync(string.Empty, content, cancellationToken); + var result = await _httpClient.PostAsync(string.Empty, content, cancellationToken).ConfigureAwait(false); var bytes = await result.Content.ReadAsByteArrayAsync(); var json = Encoding.UTF8.GetString(bytes).Trim(); if (!result.IsSuccessStatusCode) diff --git a/src/libse/Settings/Settings.cs b/src/libse/Settings/Settings.cs index 871c4559c..8a21f443b 100644 --- a/src/libse/Settings/Settings.cs +++ b/src/libse/Settings/Settings.cs @@ -2942,6 +2942,12 @@ namespace Nikse.SubtitleEdit.Core.Settings settings.Tools.BatchConvertOcrLanguage = subNode.InnerText; } + subNode = node.SelectSingleNode("BatchConvertTranslateEngine"); + if (subNode != null) + { + settings.Tools.BatchConvertTranslateEngine = subNode.InnerText; + } + subNode = node.SelectSingleNode("WaveformBatchLastFolder"); if (subNode != null) { @@ -9096,6 +9102,7 @@ namespace Nikse.SubtitleEdit.Core.Settings textWriter.WriteElementString("BatchConvertMkvLanguageCodeStyle", settings.Tools.BatchConvertMkvLanguageCodeStyle); textWriter.WriteElementString("BatchConvertOcrEngine", settings.Tools.BatchConvertOcrEngine); textWriter.WriteElementString("BatchConvertOcrLanguage", settings.Tools.BatchConvertOcrLanguage); + textWriter.WriteElementString("BatchConvertTranslateEngine", settings.Tools.BatchConvertTranslateEngine); textWriter.WriteElementString("WaveformBatchLastFolder", settings.Tools.WaveformBatchLastFolder); textWriter.WriteElementString("ModifySelectionRule", settings.Tools.ModifySelectionRule); textWriter.WriteElementString("ModifySelectionText", settings.Tools.ModifySelectionText); diff --git a/src/libse/Settings/ToolsSettings.cs b/src/libse/Settings/ToolsSettings.cs index 16c40b45a..05c1cffbd 100644 --- a/src/libse/Settings/ToolsSettings.cs +++ b/src/libse/Settings/ToolsSettings.cs @@ -198,6 +198,7 @@ namespace Nikse.SubtitleEdit.Core.Settings public string BatchConvertMkvLanguageCodeStyle { get; set; } public string BatchConvertOcrEngine { get; set; } public string BatchConvertOcrLanguage { get; set; } + public string BatchConvertTranslateEngine { get; set; } public string WaveformBatchLastFolder { get; set; } public string ModifySelectionText { get; set; } public string ModifySelectionRule { get; set; } @@ -526,6 +527,7 @@ namespace Nikse.SubtitleEdit.Core.Settings BatchConvertTsScreenHeight = 1080; BatchConvertOcrEngine = "Tesseract"; BatchConvertOcrLanguage = "en"; + BatchConvertTranslateEngine = LibreTranslate.StaticName; BatchConvertTsOverrideHAlign = "center"; // left center right BatchConvertTsOverrideHMargin = 5; // pct BatchConvertTsFileNameAppend = ".{two-letter-country-code}"; diff --git a/src/ui/Forms/BatchConvert.Designer.cs b/src/ui/Forms/BatchConvert.Designer.cs index b0729b11d..d4ae6dccc 100644 --- a/src/ui/Forms/BatchConvert.Designer.cs +++ b/src/ui/Forms/BatchConvert.Designer.cs @@ -200,6 +200,8 @@ namespace Nikse.SubtitleEdit.Forms this.progressBar1 = new System.Windows.Forms.ProgressBar(); this.labelStatus = new Nikse.SubtitleEdit.Controls.NikseLabel(); this.labelError = new Nikse.SubtitleEdit.Controls.NikseLabel(); + this.nikseComboBoxTranslateModel = new Nikse.SubtitleEdit.Controls.NikseComboBox(); + this.nikseLabelModel = new Nikse.SubtitleEdit.Controls.NikseLabel(); this.groupBoxConvertOptions.SuspendLayout(); this.groupBoxAutoTranslate.SuspendLayout(); this.contextMenuStripOptions.SuspendLayout(); @@ -284,6 +286,8 @@ namespace Nikse.SubtitleEdit.Forms // // groupBoxAutoTranslate // + this.groupBoxAutoTranslate.Controls.Add(this.nikseLabelModel); + this.groupBoxAutoTranslate.Controls.Add(this.nikseComboBoxTranslateModel); this.groupBoxAutoTranslate.Controls.Add(this.labelTarget); this.groupBoxAutoTranslate.Controls.Add(this.comboBoxTarget); this.groupBoxAutoTranslate.Controls.Add(this.labelSource); @@ -2361,7 +2365,7 @@ namespace Nikse.SubtitleEdit.Forms this.comboBoxFilter.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBoxFilter.DropDownWidth = 335; this.comboBoxFilter.FormattingEnabled = true; - this.comboBoxFilter.Items.AddRange(new object[] { + this.comboBoxFilter.Items.AddRange(new string[] { "All files", "SubRip .srt files without BOM header", "Files with subtitle with more than two lines", @@ -2576,6 +2580,39 @@ namespace Nikse.SubtitleEdit.Forms this.labelError.TabIndex = 10; this.labelError.Text = "labelError"; // + // nikseComboBoxTranslateModel + // + this.nikseComboBoxTranslateModel.BackColor = System.Drawing.SystemColors.Window; + this.nikseComboBoxTranslateModel.BackColorDisabled = System.Drawing.Color.FromArgb(((int)(((byte)(240)))), ((int)(((byte)(240)))), ((int)(((byte)(240))))); + this.nikseComboBoxTranslateModel.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(171)))), ((int)(((byte)(173)))), ((int)(((byte)(179))))); + this.nikseComboBoxTranslateModel.BorderColorDisabled = System.Drawing.Color.FromArgb(((int)(((byte)(120)))), ((int)(((byte)(120)))), ((int)(((byte)(120))))); + this.nikseComboBoxTranslateModel.ButtonForeColor = System.Drawing.SystemColors.ControlText; + this.nikseComboBoxTranslateModel.ButtonForeColorDown = System.Drawing.Color.Orange; + this.nikseComboBoxTranslateModel.ButtonForeColorOver = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(120)))), ((int)(((byte)(215))))); + this.nikseComboBoxTranslateModel.DropDownHeight = 400; + this.nikseComboBoxTranslateModel.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDown; + this.nikseComboBoxTranslateModel.DropDownWidth = 221; + this.nikseComboBoxTranslateModel.FormattingEnabled = true; + this.nikseComboBoxTranslateModel.Location = new System.Drawing.Point(11, 169); + this.nikseComboBoxTranslateModel.MaxLength = 32767; + this.nikseComboBoxTranslateModel.Name = "nikseComboBoxTranslateModel"; + this.nikseComboBoxTranslateModel.SelectedIndex = -1; + this.nikseComboBoxTranslateModel.SelectedItem = null; + this.nikseComboBoxTranslateModel.SelectedText = ""; + this.nikseComboBoxTranslateModel.Size = new System.Drawing.Size(221, 21); + this.nikseComboBoxTranslateModel.TabIndex = 116; + this.nikseComboBoxTranslateModel.TabStop = false; + this.nikseComboBoxTranslateModel.UsePopupWindow = false; + // + // nikseLabelModel + // + this.nikseLabelModel.AutoSize = true; + this.nikseLabelModel.Location = new System.Drawing.Point(11, 153); + this.nikseLabelModel.Name = "nikseLabelModel"; + this.nikseLabelModel.Size = new System.Drawing.Size(39, 13); + this.nikseLabelModel.TabIndex = 117; + this.nikseLabelModel.Text = "Model:"; + // // BatchConvert // this.AllowDrop = true; @@ -2821,5 +2858,7 @@ namespace Nikse.SubtitleEdit.Forms private Controls.NikseComboBox comboBoxTarget; private Nikse.SubtitleEdit.Controls.NikseLabel labelSource; private Controls.NikseComboBox comboBoxSource; + private Controls.NikseLabel nikseLabelModel; + private Controls.NikseComboBox nikseComboBoxTranslateModel; } } \ No newline at end of file diff --git a/src/ui/Forms/BatchConvert.cs b/src/ui/Forms/BatchConvert.cs index 3b211dffb..08da6248a 100644 --- a/src/ui/Forms/BatchConvert.cs +++ b/src/ui/Forms/BatchConvert.cs @@ -413,6 +413,9 @@ namespace Nikse.SubtitleEdit.Forms checkBoxDrawing.Text = LanguageSettings.Current.AssaResolutionChanger.ChangeResolutionDrawing; labelSource.Text = LanguageSettings.Current.GoogleTranslate.From; labelTarget.Text = LanguageSettings.Current.GoogleTranslate.To; + nikseLabelModel.Text = LanguageSettings.Current.AudioToText.Model; + nikseLabelModel.Visible = false; + nikseComboBoxTranslateModel.Visible = false; groupBoxAutoTranslate.Text = LanguageSettings.Current.Main.VideoControls.AutoTranslate; labelSource.Left = comboBoxSource.Left - labelSource.Width - 5; @@ -733,13 +736,14 @@ namespace Nikse.SubtitleEdit.Forms _autoTranslatorEngines = new List { // only add local APIs new LibreTranslate(), + new OllamaTranslate(), new NoLanguageLeftBehindServe(), new NoLanguageLeftBehindApi(), - new OllamaTranslate(), }; nikseComboBoxEngine.Items.Clear(); nikseComboBoxEngine.Items.AddRange(_autoTranslatorEngines.Select(p => p.Name).ToArray()); nikseComboBoxEngine.SelectedIndex = 0; + nikseComboBoxEngine.Text = Configuration.Settings.Tools.BatchConvertTranslateEngine; var targetLanguageIsoCode = AutoTranslate.EvaluateDefaultTargetLanguageCode(CultureInfo.CurrentCulture.TwoLetterISOLanguageName); AutoTranslate.SelectLanguageCode(comboBoxTarget, targetLanguageIsoCode); } @@ -1735,7 +1739,7 @@ namespace Nikse.SubtitleEdit.Forms { try { - var res = RunAutoTranslate(subtitle).Result; + var res = RunAutoTranslate(subtitle); subtitle = res.Subtitle; } catch (Exception exception) @@ -1789,7 +1793,7 @@ namespace Nikse.SubtitleEdit.Forms { try { - var res = RunAutoTranslate(subtitle).Result; + var res = RunAutoTranslate(subtitle); subtitle = res.Subtitle; } catch (Exception exception) @@ -1922,7 +1926,7 @@ namespace Nikse.SubtitleEdit.Forms { try { - var res = RunAutoTranslate(parameter.Subtitle).Result; + var res = RunAutoTranslate(parameter.Subtitle); parameter.Subtitle = res.Subtitle; var newFileName = FileNameHelper.GetFileNameWithTargetLanguage(parameter.FileName, null, null, parameter.Format, res.Source.TwoLetterIsoLanguageName, res.Target.TwoLetterIsoLanguageName); @@ -1971,7 +1975,7 @@ namespace Nikse.SubtitleEdit.Forms public TranslationPair Target { get; set; } } - private async Task RunAutoTranslate(Subtitle subtitle) + private TranslateResult RunAutoTranslate(Subtitle subtitle) { var engine = GetCurrentEngine(); engine.Initialize(); @@ -2007,22 +2011,37 @@ namespace Nikse.SubtitleEdit.Forms engine.Name == NoLanguageLeftBehindApi.StaticName || // NLLB seems to miss some text... engine.Name == NoLanguageLeftBehindServe.StaticName; + if (_autoTranslator.Name == OllamaTranslate.StaticName && !string.IsNullOrEmpty(nikseComboBoxTranslateModel.Text)) + { + Configuration.Settings.Tools.OllamaModel = nikseComboBoxTranslateModel.Text; + } + + _autoTranslator.Initialize(); + var index = 0; while (index < subtitle.Paragraphs.Count && !_abort) { Application.DoEvents(); - var linesMergedAndTranslated = await MergeAndSplitHelper.MergeAndTranslateIfPossible(subtitle, translatedSubtitle, source, target, index, engine, forceSingleLineMode, CancellationToken.None); + + var task = Task.Run(async () => await MergeAndSplitHelper.MergeAndTranslateIfPossible(subtitle, translatedSubtitle, source, target, index, engine, forceSingleLineMode, CancellationToken.None).ConfigureAwait(false)); + task.Wait(); + + var linesMergedAndTranslated = task.Result; if (linesMergedAndTranslated > 0) { index += linesMergedAndTranslated; continue; } + forceSingleLineMode = true; var p = subtitle.Paragraphs[index]; var f = new Formatting(); var unformattedText = f.SetTagsAndReturnTrimmed(p.Text, source.Code); - var translation = await _autoTranslator.Translate(unformattedText, source.Code, target.Code, CancellationToken.None); + var task2 = Task.Run(async () => await _autoTranslator.Translate(unformattedText, source.Code, target.Code, CancellationToken.None).ConfigureAwait(false)); + task2.Wait(); + + var translation = task2.Result; translation = translation .Replace("
", Environment.NewLine) .Replace("
", Environment.NewLine); @@ -3536,6 +3555,7 @@ namespace Nikse.SubtitleEdit.Forms Configuration.Settings.Tools.BatchConvertOcrEngine = _ocrEngine; Configuration.Settings.Tools.BatchConvertOcrLanguage = _ocrLanguage; + Configuration.Settings.Tools.BatchConvertTranslateEngine = nikseComboBoxEngine.Text; UpdateRtlSettings(); } @@ -4207,6 +4227,9 @@ namespace Nikse.SubtitleEdit.Forms comboBoxSource.SelectedIndex = 0; FillComboWithLanguages(comboBoxTarget, _autoTranslator.GetSupportedTargetLanguages()); + + var targetLanguageIsoCode = AutoTranslate.EvaluateDefaultTargetLanguageCode(CultureInfo.CurrentCulture.TwoLetterISOLanguageName); + AutoTranslate.SelectLanguageCode(comboBoxTarget, targetLanguageIsoCode); } public static void FillComboWithLanguages(NikseComboBox comboBox, IEnumerable languages) @@ -4228,6 +4251,24 @@ namespace Nikse.SubtitleEdit.Forms { _autoTranslator = GetCurrentEngine(); linkLabelPoweredBy.Text = string.Format(LanguageSettings.Current.GoogleTranslate.PoweredByX, _autoTranslator.Name); + + if (_autoTranslator.Name == OllamaTranslate.StaticName) + { + var models = Configuration.Settings.Tools.OllamaModels.Split(',').ToList(); + nikseComboBoxTranslateModel.Items.Clear(); + foreach (var model in models) + { + nikseComboBoxTranslateModel.Items.Add(model); + } + nikseComboBoxTranslateModel.Text = Configuration.Settings.Tools.OllamaModel; + nikseLabelModel.Visible = true; + nikseComboBoxTranslateModel.Visible = true; + } + else + { + nikseLabelModel.Visible = false; + nikseComboBoxTranslateModel.Visible = false; + } } private IAutoTranslator GetCurrentEngine()