From 34862e4d2d664211a1a59ebeaa098abd00509acd Mon Sep 17 00:00:00 2001 From: niksedk Date: Sat, 11 Mar 2023 10:44:38 +0100 Subject: [PATCH] Work on #6725 --- LanguageBaseEnglish.xml | 10 +++- src/libse/Common/SeLogger.cs | 5 +- src/libse/Common/Settings.cs | 11 +++++ src/ui/Forms/GenerateVideoWithSoftSubs.cs | 57 +++++++++++++++++++---- src/ui/Forms/Main.cs | 3 +- src/ui/Logic/Language.cs | 13 +++++- src/ui/Logic/LanguageDeserializer.cs | 22 ++++++++- src/ui/Logic/LanguageStructure.cs | 12 ++++- src/ui/Logic/VideoPreviewGenerator.cs | 4 ++ 9 files changed, 119 insertions(+), 18 deletions(-) diff --git a/LanguageBaseEnglish.xml b/LanguageBaseEnglish.xml index 0e46b027e..dd4cd300d 100644 --- a/LanguageBaseEnglish.xml +++ b/LanguageBaseEnglish.xml @@ -882,6 +882,14 @@ Read more info (web)? Get start position Get end position + + Generate video with embedded subtitles + Input video file + Set language... + Toggle forced + Toggle default + "{0}" generated with embedded subtitles + Need dictionaries? Subtitle Edit's spell check is based on the NHunspell engine which @@ -1283,7 +1291,7 @@ To use an API key, go to "Options -> Settings -> Tools" to enter your Goog Generate text from video... Generate blank video... Generate video with burned-in subtitle... - Generate video with embedded subtitles... + Generate video with embedded subtitles... Audio to text ({0})... Import chapters from video Generate/import shot changes... diff --git a/src/libse/Common/SeLogger.cs b/src/libse/Common/SeLogger.cs index 8d67fcda2..68027f4a1 100644 --- a/src/libse/Common/SeLogger.cs +++ b/src/libse/Common/SeLogger.cs @@ -8,6 +8,8 @@ namespace Nikse.SubtitleEdit.Core.Common public static class SeLogger { + public static string ErrorFile => Path.Combine(Configuration.DataDirectory, "error_log.txt"); + public static void Error(Exception exception, string message = null) { if (exception == null) @@ -17,8 +19,7 @@ namespace Nikse.SubtitleEdit.Core.Common try { - var filePath = Path.Combine(Configuration.DataDirectory, "error_log.txt"); - using (var writer = new StreamWriter(filePath, true, Encoding.UTF8)) + using (var writer = new StreamWriter(ErrorFile, true, Encoding.UTF8)) { writer.WriteLine("-----------------------------------------------------------------------------"); writer.WriteLine($"Date: {DateTime.Now.ToString(CultureInfo.InvariantCulture)}"); diff --git a/src/libse/Common/Settings.cs b/src/libse/Common/Settings.cs index e21c9ec0b..8198a7d25 100644 --- a/src/libse/Common/Settings.cs +++ b/src/libse/Common/Settings.cs @@ -418,6 +418,10 @@ namespace Nikse.SubtitleEdit.Core.Common public bool GenVideoNonAssaBox { get; set; } public bool GenVideoNonAssaAlignRight { get; set; } public bool GenVideoNonAssaFixRtlUnicode { get; set; } + + public string GenVideoEmbedOutputExt { get; set; } + + public bool VoskPostProcessing { get; set; } public string VoskModel { get; set; } public string WhisperChoice { get; set; } @@ -6249,6 +6253,12 @@ $HorzAlign = Center settings.Tools.GenVideoNonAssaFixRtlUnicode = Convert.ToBoolean(subNode.InnerText, CultureInfo.InvariantCulture); } + subNode = node.SelectSingleNode("GenVideoEmbedOutputExt"); + if (subNode != null) + { + settings.Tools.GenVideoEmbedOutputExt = subNode.InnerText; + } + subNode = node.SelectSingleNode("VoskPostProcessing"); if (subNode != null) { @@ -10612,6 +10622,7 @@ $HorzAlign = Center textWriter.WriteElementString("GenVideoNonAssaBox", settings.Tools.GenVideoNonAssaBox.ToString(CultureInfo.InvariantCulture)); textWriter.WriteElementString("GenVideoNonAssaAlignRight", settings.Tools.GenVideoNonAssaAlignRight.ToString(CultureInfo.InvariantCulture)); textWriter.WriteElementString("GenVideoNonAssaFixRtlUnicode", settings.Tools.GenVideoNonAssaFixRtlUnicode.ToString(CultureInfo.InvariantCulture)); + textWriter.WriteElementString("GenVideoEmbedOutputExt", settings.Tools.GenVideoEmbedOutputExt); textWriter.WriteElementString("VoskPostProcessing", settings.Tools.VoskPostProcessing.ToString(CultureInfo.InvariantCulture)); textWriter.WriteElementString("VoskModel", settings.Tools.VoskModel); textWriter.WriteElementString("WhisperChoice", settings.Tools.WhisperChoice); diff --git a/src/ui/Forms/GenerateVideoWithSoftSubs.cs b/src/ui/Forms/GenerateVideoWithSoftSubs.cs index ba30aa028..623328530 100644 --- a/src/ui/Forms/GenerateVideoWithSoftSubs.cs +++ b/src/ui/Forms/GenerateVideoWithSoftSubs.cs @@ -1,5 +1,7 @@ using Nikse.SubtitleEdit.Core.Common; -using Nikse.SubtitleEdit.Core.SubtitleFormats; +using Nikse.SubtitleEdit.Core.ContainerFormats.Matroska; +using Nikse.SubtitleEdit.Core.ContainerFormats.Mp4; +using Nikse.SubtitleEdit.Core.ContainerFormats.Mp4.Boxes; using Nikse.SubtitleEdit.Logic; using System; using System.Collections.Generic; @@ -10,9 +12,6 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Windows.Forms; -using Nikse.SubtitleEdit.Core.ContainerFormats.Matroska; -using Nikse.SubtitleEdit.Core.ContainerFormats.Mp4; -using Nikse.SubtitleEdit.Core.ContainerFormats.Mp4.Boxes; namespace Nikse.SubtitleEdit.Forms { @@ -36,9 +35,20 @@ namespace Nikse.SubtitleEdit.Forms UiUtil.FixFonts(this); _videoInfo = videoInfo; - //TODO: Text = LanguageSettings.Current.GenerateVideoWithBurnedInSubs.Title; _subtitle = new Subtitle(subtitle); _inputVideoFileName = inputVideoFileName; + + Text = LanguageSettings.Current.GenerateVideoWithEmbeddedSubs.Title; + labelInputVideoFile.Text = LanguageSettings.Current.GenerateVideoWithEmbeddedSubs.InputVideoFile; + + buttonAddSubtitles.Text = LanguageSettings.Current.DvdSubRip.Add; + ButtonRemoveSubtitles.Text = LanguageSettings.Current.SubStationAlphaStyles.Remove; + buttonClear.Text = LanguageSettings.Current.SubStationAlphaStyles.RemoveAll; + ButtonMoveSubUp.Text = LanguageSettings.Current.DvdSubRip.MoveUp; + ButtonMoveSubDown.Text = LanguageSettings.Current.DvdSubRip.MoveDown; + buttonToggleForced.Text = LanguageSettings.Current.GenerateVideoWithEmbeddedSubs.ToggleForced; + buttonSetDefault.Text = LanguageSettings.Current.GenerateVideoWithEmbeddedSubs.ToggleDefault; + buttonSetLanguage.Text = LanguageSettings.Current.GenerateVideoWithEmbeddedSubs.SetLanguage; buttonGenerate.Text = LanguageSettings.Current.Watermark.Generate; buttonCancel.Text = LanguageSettings.Current.General.Cancel; @@ -59,6 +69,12 @@ namespace Nikse.SubtitleEdit.Forms var fileName = Path.Combine(dir, nameOnly); AddListViewItem(fileName); + + if (listViewSubtitles.Items.Count > 0) + { + listViewSubtitles.Items[0].Selected = true; + listViewSubtitles.Items[0].Focused = true; + } } } @@ -245,7 +261,7 @@ namespace Nikse.SubtitleEdit.Forms using (var saveDialog = new SaveFileDialog { FileName = SuggestNewVideoFileName(), - Filter = "Matroska|*.mkv|WebM|*.webm|MP4|*.mp4", + Filter = GetTargetVideoFilter(), AddExtension = true }) { @@ -276,6 +292,7 @@ namespace Nikse.SubtitleEdit.Forms _log.AppendLine("Target file name: " + VideoFileName); groupBoxSettings.Enabled = false; + buttonGenerate.Enabled = false; var stopWatch = Stopwatch.StartNew(); @@ -292,9 +309,11 @@ namespace Nikse.SubtitleEdit.Forms if (!File.Exists(VideoFileName) || new FileInfo(VideoFileName).Length == 0) { - SeLogger.Error(Environment.NewLine + "Generate hard subbed video failed: " + Environment.NewLine + _log); - MessageBox.Show("Test"); - //DialogResult = DialogResult.Cancel; + SeLogger.Error(Environment.NewLine + "Generate embedded video failed: " + Environment.NewLine + _log); + MessageBox.Show("Generate embedded video failed" + Environment.NewLine + + "For more info see the error log: " + SeLogger.ErrorFile); + buttonGenerate.Enabled = true; + groupBoxSettings.Enabled = true; return; } @@ -304,6 +323,21 @@ namespace Nikse.SubtitleEdit.Forms } } + private static string GetTargetVideoFilter() + { + if (Configuration.Settings.Tools.GenVideoEmbedOutputExt == ".mp4") + { + return "MP4|*.mp4|Matroska|*.mkv|WebM|*.webm"; + } + + if (Configuration.Settings.Tools.GenVideoEmbedOutputExt == ".webm") + { + return "WebM|*.webm|Matroska|*.mkv|MP4|*.mp4"; + } + + return "Matroska|*.mkv|WebM|*.webm|MP4|*.mp4"; + } + private string SuggestNewVideoFileName() { var fileName = Path.GetFileNameWithoutExtension(_inputVideoFileName); @@ -392,7 +426,10 @@ namespace Nikse.SubtitleEdit.Forms private void GenerateVideoWithHardSubs_FormClosing(object sender, FormClosingEventArgs e) { - //Configuration.Settings.Tools.GenVideoFontName = comboBoxSubtitleFont.Text; + if (!string.IsNullOrEmpty(VideoFileName)) + { + Configuration.Settings.Tools.GenVideoEmbedOutputExt = Path.GetExtension(VideoFileName).ToLowerInvariant(); + } } private void GenerateVideoWithHardSubs_Shown(object sender, EventArgs e) diff --git a/src/ui/Forms/Main.cs b/src/ui/Forms/Main.cs index c655ec171..8ce8df782 100644 --- a/src/ui/Forms/Main.cs +++ b/src/ui/Forms/Main.cs @@ -1757,6 +1757,7 @@ namespace Nikse.SubtitleEdit.Forms openSecondSubtitleToolStripMenuItem.Text = _language.Menu.Video.OpenSecondSubtitle; generateBlankVideoToolStripMenuItem.Text = _language.Menu.Video.GenerateBlankVideo; generateVideoWithHardcodedSubtitleToolStripMenuItem.Text = _language.Menu.Video.GenerateVideoWithBurnedInSub; + generateVideoWithHardcodedSubtitleToolStripMenuItem.Text = _language.Menu.Video.GenerateVideoWithEmbeddedSubs; videoaudioToTextToolStripMenuItem.Text = string.Format(_language.Menu.Video.VideoAudioToTextX, "Vosk/Kaldi"); audioToTextWhisperTolStripMenuItem.Text = string.Format(_language.Menu.Video.VideoAudioToTextX, "Whisper"); @@ -34649,7 +34650,7 @@ namespace Nikse.SubtitleEdit.Forms } var encodingTime = new TimeCode(form.MillisecondsEncoding).ToString(); - using (var f = new ExportPngXmlDialogOpenFolder(string.Format(LanguageSettings.Current.GenerateVideoWithBurnedInSubs.XGeneratedWithBurnedInSubsInX, Path.GetFileName(form.VideoFileName), encodingTime), Path.GetDirectoryName(form.VideoFileName), form.VideoFileName)) + using (var f = new ExportPngXmlDialogOpenFolder(string.Format(LanguageSettings.Current.GenerateVideoWithEmbeddedSubs.XGeneratedWithEmbeddedSubs, Path.GetFileName(form.VideoFileName)), Path.GetDirectoryName(form.VideoFileName), form.VideoFileName)) { f.ShowDialog(this); } diff --git a/src/ui/Logic/Language.cs b/src/ui/Logic/Language.cs index e8df3fa1b..4b6df8a15 100644 --- a/src/ui/Logic/Language.cs +++ b/src/ui/Logic/Language.cs @@ -60,6 +60,7 @@ namespace Nikse.SubtitleEdit.Logic public LanguageStructure.FixCommonErrors FixCommonErrors; public LanguageStructure.GenerateBlankVideo GenerateBlankVideo; public LanguageStructure.GenerateVideoWithBurnedInSubs GenerateVideoWithBurnedInSubs; + public LanguageStructure.GenerateVideoWithEmbeddedSubs GenerateVideoWithEmbeddedSubs; public LanguageStructure.GetDictionaries GetDictionaries; public LanguageStructure.GetTesseractDictionaries GetTesseractDictionaries; public LanguageStructure.GoogleTranslate GoogleTranslate; @@ -1110,6 +1111,16 @@ namespace Nikse.SubtitleEdit.Logic GetEndPosition = "Get end position", }; + GenerateVideoWithEmbeddedSubs = new LanguageStructure.GenerateVideoWithEmbeddedSubs + { + Title = "Generate video with embedded subtitles", + InputVideoFile = "Input video file", + ToggleForced = "Toggle forced", + ToggleDefault = "Toggle default", + SetLanguage = "Set language...", + XGeneratedWithEmbeddedSubs = "\"{0}\" generated with embedded subtitles", + }; + GetDictionaries = new LanguageStructure.GetDictionaries { Title = "Need dictionaries?", @@ -1827,7 +1838,7 @@ namespace Nikse.SubtitleEdit.Logic SmptTimeMode = "SMPTE timing (non integer frame rate)", GenerateTextFromVideo = "Generate text from video...", GenerateBlankVideo = "Generate blank video...", - GenerateVideoWithEmbeddedSub = "Generate video with embedded subtitles...", + GenerateVideoWithEmbeddedSubs = "Generate video with embedded subtitles...", GenerateVideoWithBurnedInSub = "Generate video with burned-in subtitle...", VideoAudioToTextX = "Audio to text ({0})...", ImportChaptersFromVideo = "Import chapters from video", diff --git a/src/ui/Logic/LanguageDeserializer.cs b/src/ui/Logic/LanguageDeserializer.cs index 977fc3fec..03b284b6f 100644 --- a/src/ui/Logic/LanguageDeserializer.cs +++ b/src/ui/Logic/LanguageDeserializer.cs @@ -2338,6 +2338,24 @@ namespace Nikse.SubtitleEdit.Logic case "GenerateVideoWithBurnedInSubs/GetEndPosition": language.GenerateVideoWithBurnedInSubs.GetEndPosition = reader.Value; break; + case "GenerateVideoWithEmbeddedSubs/Title": + language.GenerateVideoWithEmbeddedSubs.Title = reader.Value; + break; + case "GenerateVideoWithEmbeddedSubs/InputVideoFile": + language.GenerateVideoWithEmbeddedSubs.InputVideoFile = reader.Value; + break; + case "GenerateVideoWithEmbeddedSubs/SetLanguage": + language.GenerateVideoWithEmbeddedSubs.SetLanguage = reader.Value; + break; + case "GenerateVideoWithEmbeddedSubs/ToggleForced": + language.GenerateVideoWithEmbeddedSubs.ToggleForced = reader.Value; + break; + case "GenerateVideoWithEmbeddedSubs/ToggleDefault": + language.GenerateVideoWithEmbeddedSubs.ToggleDefault = reader.Value; + break; + case "GenerateVideoWithEmbeddedSubs/XGeneratedWithEmbeddedSubs": + language.GenerateVideoWithEmbeddedSubs.XGeneratedWithEmbeddedSubs = reader.Value; + break; case "GetDictionaries/Title": language.GetDictionaries.Title = reader.Value; break; @@ -4270,8 +4288,8 @@ namespace Nikse.SubtitleEdit.Logic case "Main/Menu/Video/GenerateVideoWithBurnedInSub": language.Main.Menu.Video.GenerateVideoWithBurnedInSub = reader.Value; break; - case "Main/Menu/Video/GenerateVideoWithEmbeddedSub": - language.Main.Menu.Video.GenerateVideoWithEmbeddedSub = reader.Value; + case "Main/Menu/Video/GenerateVideoWithEmbeddedSubs": + language.Main.Menu.Video.GenerateVideoWithEmbeddedSubs = reader.Value; break; case "Main/Menu/Video/VideoAudioToTextX": language.Main.Menu.Video.VideoAudioToTextX = reader.Value; diff --git a/src/ui/Logic/LanguageStructure.cs b/src/ui/Logic/LanguageStructure.cs index 4603fe842..97ef8291e 100644 --- a/src/ui/Logic/LanguageStructure.cs +++ b/src/ui/Logic/LanguageStructure.cs @@ -970,6 +970,16 @@ namespace Nikse.SubtitleEdit.Logic public string GetEndPosition { get; set; } } + public class GenerateVideoWithEmbeddedSubs + { + public string Title { get; set; } + public string InputVideoFile { get; set; } + public string SetLanguage { get; set; } + public string ToggleForced { get; set; } + public string ToggleDefault { get; set; } + public string XGeneratedWithEmbeddedSubs { get; set; } + } + public class GetDictionaries { public string Title { get; set; } @@ -1677,7 +1687,7 @@ namespace Nikse.SubtitleEdit.Logic public string GenerateTextFromVideo { get; set; } public string GenerateBlankVideo { get; set; } public string GenerateVideoWithBurnedInSub { get; set; } - public string GenerateVideoWithEmbeddedSub { get; set; } + public string GenerateVideoWithEmbeddedSubs { get; set; } public string VideoAudioToTextX { get; set; } public string ImportChaptersFromVideo { get; set; } public string GenerateImportShotChanges { get; set; } diff --git a/src/ui/Logic/VideoPreviewGenerator.cs b/src/ui/Logic/VideoPreviewGenerator.cs index 6fbbb7df9..39e260fee 100644 --- a/src/ui/Logic/VideoPreviewGenerator.cs +++ b/src/ui/Logic/VideoPreviewGenerator.cs @@ -336,6 +336,10 @@ namespace Nikse.SubtitleEdit.Logic { subsFormat += $" -c:s:s:{count - 1} ass"; } + else if (softSub.SubtitleFormat.GetType() == typeof(SubStationAlpha)) + { + subsFormat += $" -c:s:s:{count - 1} ssa"; + } else if (softSub.SubtitleFormat.GetType() == typeof(WebVTT) || softSub.SubtitleFormat.GetType() == typeof(WebVTTFileWithLineNumber)) {