diff --git a/LanguageMaster.xml b/LanguageMaster.xml index 35e05d957..b2577e4b2 100644 --- a/LanguageMaster.xml +++ b/LanguageMaster.xml @@ -802,6 +802,8 @@ Note: Do check free disk space. Note: Advanced Substation Alpha supported. "{0}" generated with burned-in subtitle. + Time remaining: {0} seconds + Time remaining: {0} minutes and {1} seconds Need dictionaries? @@ -1267,6 +1269,7 @@ To use an API key go to "Options -> Settings -> Tools" to enter your Googl Help Show/hide waveform Show/hide video + Advanced Sub Station Alpha draw Size all columns to fit diff --git a/src/ui/Forms/GenerateVideoWithHardSubs.Designer.cs b/src/ui/Forms/GenerateVideoWithHardSubs.Designer.cs index f6fbe75df..e2eba244d 100644 --- a/src/ui/Forms/GenerateVideoWithHardSubs.Designer.cs +++ b/src/ui/Forms/GenerateVideoWithHardSubs.Designer.cs @@ -29,6 +29,7 @@ namespace Nikse.SubtitleEdit.Forms /// private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); this.progressBar1 = new System.Windows.Forms.ProgressBar(); this.buttonOK = new System.Windows.Forms.Button(); this.buttonCancel = new System.Windows.Forms.Button(); @@ -36,16 +37,26 @@ namespace Nikse.SubtitleEdit.Forms this.labelInfo = new System.Windows.Forms.Label(); this.numericUpDownFontSize = new System.Windows.Forms.NumericUpDown(); this.labelFontSize = new System.Windows.Forms.Label(); + this.timer1 = new System.Windows.Forms.Timer(this.components); + this.labelProgress = new System.Windows.Forms.Label(); + this.groupBoxSettings = new System.Windows.Forms.GroupBox(); + this.labelX = new System.Windows.Forms.Label(); + this.labelResolution = new System.Windows.Forms.Label(); + this.numericUpDownHeight = new System.Windows.Forms.NumericUpDown(); + this.numericUpDownWidth = new System.Windows.Forms.NumericUpDown(); ((System.ComponentModel.ISupportInitialize)(this.numericUpDownFontSize)).BeginInit(); + this.groupBoxSettings.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numericUpDownHeight)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.numericUpDownWidth)).BeginInit(); this.SuspendLayout(); // // progressBar1 // this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.progressBar1.Location = new System.Drawing.Point(12, 135); + this.progressBar1.Location = new System.Drawing.Point(12, 199); this.progressBar1.Name = "progressBar1"; - this.progressBar1.Size = new System.Drawing.Size(405, 23); + this.progressBar1.Size = new System.Drawing.Size(434, 11); this.progressBar1.TabIndex = 22; this.progressBar1.Visible = false; // @@ -53,7 +64,7 @@ namespace Nikse.SubtitleEdit.Forms // this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.buttonOK.ImeMode = System.Windows.Forms.ImeMode.NoControl; - this.buttonOK.Location = new System.Drawing.Point(423, 135); + this.buttonOK.Location = new System.Drawing.Point(452, 199); this.buttonOK.Name = "buttonOK"; this.buttonOK.Size = new System.Drawing.Size(121, 23); this.buttonOK.TabIndex = 23; @@ -66,7 +77,7 @@ namespace Nikse.SubtitleEdit.Forms this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.buttonCancel.ImeMode = System.Windows.Forms.ImeMode.NoControl; - this.buttonCancel.Location = new System.Drawing.Point(550, 135); + this.buttonCancel.Location = new System.Drawing.Point(579, 199); this.buttonCancel.Name = "buttonCancel"; this.buttonCancel.Size = new System.Drawing.Size(75, 23); this.buttonCancel.TabIndex = 24; @@ -78,7 +89,7 @@ namespace Nikse.SubtitleEdit.Forms // this.labelPleaseWait.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.labelPleaseWait.AutoSize = true; - this.labelPleaseWait.Location = new System.Drawing.Point(12, 119); + this.labelPleaseWait.Location = new System.Drawing.Point(12, 183); this.labelPleaseWait.Name = "labelPleaseWait"; this.labelPleaseWait.Size = new System.Drawing.Size(70, 13); this.labelPleaseWait.TabIndex = 25; @@ -89,13 +100,13 @@ namespace Nikse.SubtitleEdit.Forms this.labelInfo.AutoSize = true; this.labelInfo.Location = new System.Drawing.Point(15, 29); this.labelInfo.Name = "labelInfo"; - this.labelInfo.Size = new System.Drawing.Size(215, 13); + this.labelInfo.Size = new System.Drawing.Size(220, 13); this.labelInfo.TabIndex = 26; - this.labelInfo.Text = "This will save video x with burned-in subtitle."; + this.labelInfo.Text = "This will save video x with burned-in subtitles."; // // numericUpDownFontSize // - this.numericUpDownFontSize.Location = new System.Drawing.Point(472, 40); + this.numericUpDownFontSize.Location = new System.Drawing.Point(88, 33); this.numericUpDownFontSize.Maximum = new decimal(new int[] { 1000, 0, @@ -118,19 +129,126 @@ namespace Nikse.SubtitleEdit.Forms // labelFontSize // this.labelFontSize.AutoSize = true; - this.labelFontSize.Location = new System.Drawing.Point(472, 21); + this.labelFontSize.Location = new System.Drawing.Point(19, 35); this.labelFontSize.Name = "labelFontSize"; this.labelFontSize.Size = new System.Drawing.Size(49, 13); this.labelFontSize.TabIndex = 28; this.labelFontSize.Text = "Font size"; // + // timer1 + // + this.timer1.Interval = 1000; + this.timer1.Tick += new System.EventHandler(this.timer1_Tick); + // + // labelProgress + // + this.labelProgress.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.labelProgress.AutoSize = true; + this.labelProgress.Location = new System.Drawing.Point(15, 213); + this.labelProgress.Name = "labelProgress"; + this.labelProgress.Size = new System.Drawing.Size(88, 13); + this.labelProgress.TabIndex = 29; + this.labelProgress.Text = "Remaining time..."; + // + // groupBoxSettings + // + 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.Right))); + this.groupBoxSettings.Controls.Add(this.labelX); + this.groupBoxSettings.Controls.Add(this.labelResolution); + this.groupBoxSettings.Controls.Add(this.numericUpDownHeight); + this.groupBoxSettings.Controls.Add(this.numericUpDownWidth); + this.groupBoxSettings.Controls.Add(this.numericUpDownFontSize); + this.groupBoxSettings.Controls.Add(this.labelFontSize); + this.groupBoxSettings.Location = new System.Drawing.Point(18, 58); + this.groupBoxSettings.Name = "groupBoxSettings"; + this.groupBoxSettings.Size = new System.Drawing.Size(636, 107); + this.groupBoxSettings.TabIndex = 30; + this.groupBoxSettings.TabStop = false; + this.groupBoxSettings.Text = "Settings"; + // + // labelX + // + this.labelX.AutoSize = true; + this.labelX.Location = new System.Drawing.Point(158, 65); + this.labelX.Name = "labelX"; + this.labelX.Size = new System.Drawing.Size(12, 13); + this.labelX.TabIndex = 31; + this.labelX.Text = "x"; + // + // labelResolution + // + this.labelResolution.AutoSize = true; + this.labelResolution.Location = new System.Drawing.Point(19, 65); + this.labelResolution.Name = "labelResolution"; + this.labelResolution.Size = new System.Drawing.Size(57, 13); + this.labelResolution.TabIndex = 29; + this.labelResolution.Text = "Resolution"; + // + // numericUpDownHeight + // + this.numericUpDownHeight.Increment = new decimal(new int[] { + 2, + 0, + 0, + 0}); + this.numericUpDownHeight.Location = new System.Drawing.Point(176, 63); + this.numericUpDownHeight.Maximum = new decimal(new int[] { + 50000, + 0, + 0, + 0}); + this.numericUpDownHeight.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.numericUpDownHeight.Name = "numericUpDownHeight"; + this.numericUpDownHeight.Size = new System.Drawing.Size(64, 20); + this.numericUpDownHeight.TabIndex = 32; + this.numericUpDownHeight.Value = new decimal(new int[] { + 720, + 0, + 0, + 0}); + this.numericUpDownHeight.ValueChanged += new System.EventHandler(this.numericUpDownHeight_ValueChanged); + // + // numericUpDownWidth + // + this.numericUpDownWidth.Increment = new decimal(new int[] { + 2, + 0, + 0, + 0}); + this.numericUpDownWidth.Location = new System.Drawing.Point(88, 63); + this.numericUpDownWidth.Maximum = new decimal(new int[] { + 50000, + 0, + 0, + 0}); + this.numericUpDownWidth.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.numericUpDownWidth.Name = "numericUpDownWidth"; + this.numericUpDownWidth.Size = new System.Drawing.Size(64, 20); + this.numericUpDownWidth.TabIndex = 30; + this.numericUpDownWidth.Value = new decimal(new int[] { + 1280, + 0, + 0, + 0}); + this.numericUpDownWidth.ValueChanged += new System.EventHandler(this.numericUpDownWidth_ValueChanged); + // // GenerateVideoWithHardSubs // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(637, 170); - this.Controls.Add(this.labelFontSize); - this.Controls.Add(this.numericUpDownFontSize); + this.ClientSize = new System.Drawing.Size(666, 234); + this.Controls.Add(this.groupBoxSettings); + this.Controls.Add(this.labelProgress); this.Controls.Add(this.labelInfo); this.Controls.Add(this.labelPleaseWait); this.Controls.Add(this.progressBar1); @@ -145,6 +263,10 @@ namespace Nikse.SubtitleEdit.Forms this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "GenerateVideoWithHardSubs"; ((System.ComponentModel.ISupportInitialize)(this.numericUpDownFontSize)).EndInit(); + this.groupBoxSettings.ResumeLayout(false); + this.groupBoxSettings.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numericUpDownHeight)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.numericUpDownWidth)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -159,5 +281,12 @@ namespace Nikse.SubtitleEdit.Forms private System.Windows.Forms.Label labelInfo; private System.Windows.Forms.NumericUpDown numericUpDownFontSize; private System.Windows.Forms.Label labelFontSize; + private System.Windows.Forms.Timer timer1; + private System.Windows.Forms.Label labelProgress; + private System.Windows.Forms.GroupBox groupBoxSettings; + private System.Windows.Forms.Label labelX; + private System.Windows.Forms.Label labelResolution; + private System.Windows.Forms.NumericUpDown numericUpDownHeight; + private System.Windows.Forms.NumericUpDown numericUpDownWidth; } } \ No newline at end of file diff --git a/src/ui/Forms/GenerateVideoWithHardSubs.cs b/src/ui/Forms/GenerateVideoWithHardSubs.cs index eebc265a7..92aea94b5 100644 --- a/src/ui/Forms/GenerateVideoWithHardSubs.cs +++ b/src/ui/Forms/GenerateVideoWithHardSubs.cs @@ -2,7 +2,9 @@ using Nikse.SubtitleEdit.Core.SubtitleFormats; using Nikse.SubtitleEdit.Logic; using System; +using System.Diagnostics; using System.IO; +using System.Text.RegularExpressions; using System.Windows.Forms; namespace Nikse.SubtitleEdit.Forms @@ -10,16 +12,22 @@ namespace Nikse.SubtitleEdit.Forms public sealed partial class GenerateVideoWithHardSubs : Form { private bool _abort; - private Subtitle _assaSubtitle; - private string _inputVideoFileName; + private readonly Subtitle _assaSubtitle; + private readonly VideoInfo _videoInfo; + private readonly string _inputVideoFileName; + private static readonly Regex FrameFinderRegex = new Regex(@"[Ff]rame=\s*\d+", RegexOptions.Compiled); + private long _processedFrames; + private long _startTicks; + private long _totalFrames; public string VideoFileName { get; private set; } - public GenerateVideoWithHardSubs(Subtitle assaSubtitle, string inputVideoFileName, int? fontSize) + public GenerateVideoWithHardSubs(Subtitle assaSubtitle, string inputVideoFileName, VideoInfo videoInfo, int? fontSize) { UiUtil.PreInitialize(this); InitializeComponent(); UiUtil.FixFonts(this); + _videoInfo = videoInfo; Text = LanguageSettings.Current.GenerateVideoWithBurnedInSubs.Title; labelInfo.Text = LanguageSettings.Current.GenerateVideoWithBurnedInSubs.Info; _assaSubtitle = assaSubtitle; @@ -30,15 +38,24 @@ namespace Nikse.SubtitleEdit.Forms buttonCancel.Text = LanguageSettings.Current.General.Cancel; progressBar1.Visible = false; labelPleaseWait.Visible = false; + labelProgress.Text = string.Empty; + numericUpDownWidth.Value = _videoInfo.Width; + numericUpDownHeight.Value = _videoInfo.Height; if (fontSize.HasValue) { numericUpDownFontSize.Value = fontSize.Value; + + var left = Math.Max(labelResolution.Left + labelResolution.Width, labelFontSize.Left + labelFontSize.Width) + 5; + numericUpDownFontSize.Left = left; + numericUpDownWidth.Left = left; + labelX.Left = numericUpDownWidth.Left + numericUpDownWidth.Width + 3; + numericUpDownHeight.Left = labelX.Left + labelX.Width + 3; } else { - labelFontSize.Visible = false; - numericUpDownFontSize.Visible = false; + groupBoxSettings.Visible = false; + Height -= groupBoxSettings.Height - 20; } } @@ -51,6 +68,24 @@ namespace Nikse.SubtitleEdit.Forms } } + private void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine) + { + if (string.IsNullOrWhiteSpace(outLine.Data)) + { + return; + } + + var match = FrameFinderRegex.Match(outLine.Data); + if (match.Success) + { + var arr = match.Value.Split('='); + if (arr.Length > 0 && long.TryParse(arr[1], out var f)) + { + _processedFrames = f; + } + } + } + private void buttonOK_Click(object sender, EventArgs e) { buttonOK.Enabled = false; @@ -93,19 +128,30 @@ namespace Nikse.SubtitleEdit.Forms } } - SubtitleFormat format = new AdvancedSubStationAlpha(); - var assaTempFileName = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".ass"); + var format = new AdvancedSubStationAlpha(); + var assaTempFileName = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".ass"); File.WriteAllText(assaTempFileName, format.ToText(_assaSubtitle, null)); - progressBar1.Style = ProgressBarStyle.Marquee; + groupBoxSettings.Enabled = false; + progressBar1.Maximum = (int)_videoInfo.TotalFrames; progressBar1.Visible = true; labelPleaseWait.Visible = true; var process = VideoPreviewGenerator.GenerateHardcodedVideoFile( _inputVideoFileName, assaTempFileName, - VideoFileName); + VideoFileName, + (int)numericUpDownWidth.Value, + (int)numericUpDownHeight.Value, + OutputHandler); process.Start(); + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + + _totalFrames = (long)_videoInfo.TotalFrames; + _startTicks = DateTime.UtcNow.Ticks; + timer1.Start(); + while (!process.HasExited) { System.Threading.Thread.Sleep(100); @@ -114,10 +160,15 @@ namespace Nikse.SubtitleEdit.Forms { process.Kill(); } + + progressBar1.Value = (int)_processedFrames; } progressBar1.Visible = false; labelPleaseWait.Visible = false; + timer1.Stop(); + labelProgress.Text = string.Empty; + groupBoxSettings.Enabled = true; try { @@ -130,5 +181,48 @@ namespace Nikse.SubtitleEdit.Forms DialogResult = _abort ? DialogResult.Cancel : DialogResult.OK; } + + private void timer1_Tick(object sender, EventArgs e) + { + if (_processedFrames <= 0 || _videoInfo.TotalFrames <= 0) + { + return; + } + + var durationMs = (DateTime.UtcNow.Ticks - _startTicks) / 10_000; + var msPerFrame = (float)durationMs / _processedFrames; + var estimatedTotalMs = msPerFrame * _totalFrames; + var estimatedLeft = ToProgressTime(estimatedTotalMs - durationMs); + labelProgress.Text = estimatedLeft; + } + + private string ToProgressTime(float estimatedTotalMs) + { + var timeCode = new TimeCode(estimatedTotalMs); + if (timeCode.TotalSeconds < 60) + { + return string.Format(LanguageSettings.Current.GenerateVideoWithBurnedInSubs.TimeRemainingSeconds, (int)Math.Round(timeCode.TotalSeconds)); + } + + return string.Format(LanguageSettings.Current.GenerateVideoWithBurnedInSubs.TimeRemainingMinutesAndSeconds, timeCode.Minutes + timeCode.Hours * 60, timeCode.Seconds); + } + + private void numericUpDownWidth_ValueChanged(object sender, EventArgs e) + { + var v = (int)numericUpDownWidth.Value; + if (v % 2 == 1) + { + numericUpDownWidth.Value++; + } + } + + private void numericUpDownHeight_ValueChanged(object sender, EventArgs e) + { + var v = (int)numericUpDownHeight.Value; + if (v % 2 == 1) + { + numericUpDownHeight.Value++; + } + } } } diff --git a/src/ui/Forms/GenerateVideoWithHardSubs.resx b/src/ui/Forms/GenerateVideoWithHardSubs.resx index 1af7de150..1f666f268 100644 --- a/src/ui/Forms/GenerateVideoWithHardSubs.resx +++ b/src/ui/Forms/GenerateVideoWithHardSubs.resx @@ -117,4 +117,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + \ No newline at end of file diff --git a/src/ui/Forms/Main.cs b/src/ui/Forms/Main.cs index 8516e83a4..542528f21 100644 --- a/src/ui/Forms/Main.cs +++ b/src/ui/Forms/Main.cs @@ -31679,7 +31679,7 @@ namespace Nikse.SubtitleEdit.Forms sub.Header = AdvancedSubStationAlpha.AddTagToHeader("PlayResX", "PlayResX: " + _videoInfo.Width.ToString(CultureInfo.InvariantCulture), "[Script Info]", sub.Header); sub.Header = AdvancedSubStationAlpha.AddTagToHeader("PlayResY", "PlayResY: " + _videoInfo.Height.ToString(CultureInfo.InvariantCulture), "[Script Info]", sub.Header); - using (var form = new GenerateVideoWithHardSubs(sub, VideoFileName, fontSize)) + using (var form = new GenerateVideoWithHardSubs(sub, VideoFileName, _videoInfo, fontSize)) { var result = form.ShowDialog(this); if (result != DialogResult.OK) diff --git a/src/ui/Logic/Language.cs b/src/ui/Logic/Language.cs index 95097e1b8..d944b3b0b 100644 --- a/src/ui/Logic/Language.cs +++ b/src/ui/Logic/Language.cs @@ -1018,7 +1018,9 @@ namespace Nikse.SubtitleEdit.Logic { Title = "Generate video with burned-in subtile", Info = "Will generate a video file with burned-in subtitle.\r\n\r\nNote: Advanced Substation Alpha supported.", - XGeneratedWithBurnedInSubs = "\"{0}\" generated with burned-in subtitle." + XGeneratedWithBurnedInSubs = "\"{0}\" generated with burned-in subtitle.", + TimeRemainingSeconds = "Time remaining: {0} seconds", + TimeRemainingMinutesAndSeconds = "Time remaining: {0} minutes and {1} seconds", }; GetDictionaries = new LanguageStructure.GetDictionaries diff --git a/src/ui/Logic/LanguageDeserializer.cs b/src/ui/Logic/LanguageDeserializer.cs index 0133c8a27..939fa3f63 100644 --- a/src/ui/Logic/LanguageDeserializer.cs +++ b/src/ui/Logic/LanguageDeserializer.cs @@ -2125,6 +2125,12 @@ namespace Nikse.SubtitleEdit.Logic case "GenerateVideoWithBurnedInSubs/XGeneratedWithBurnedInSubs": language.GenerateVideoWithBurnedInSubs.XGeneratedWithBurnedInSubs = reader.Value; break; + case "GenerateVideoWithBurnedInSubs/TimeRemainingSeconds": + language.GenerateVideoWithBurnedInSubs.TimeRemainingSeconds = reader.Value; + break; + case "GenerateVideoWithBurnedInSubs/TimeRemainingMinutesAndSeconds": + language.GenerateVideoWithBurnedInSubs.TimeRemainingMinutesAndSeconds = reader.Value; + break; case "GetDictionaries/Title": language.GetDictionaries.Title = reader.Value; break; @@ -4162,6 +4168,9 @@ namespace Nikse.SubtitleEdit.Logic case "Main/Menu/ToolBar/ShowHideVideo": language.Main.Menu.ToolBar.ShowHideVideo = reader.Value; break; + case "Main/Menu/ToolBar/AssaDraw": + language.Main.Menu.ToolBar.AssaDraw = reader.Value; + break; case "Main/Menu/ContextMenu/SizeAllColumnsToFit": language.Main.Menu.ContextMenu.SizeAllColumnsToFit = reader.Value; break; diff --git a/src/ui/Logic/LanguageStructure.cs b/src/ui/Logic/LanguageStructure.cs index 9a5255778..3ed812371 100644 --- a/src/ui/Logic/LanguageStructure.cs +++ b/src/ui/Logic/LanguageStructure.cs @@ -883,6 +883,8 @@ public string Title { get; set; } public string Info { get; set; } public string XGeneratedWithBurnedInSubs { get; set; } + public string TimeRemainingSeconds { get; set; } + public string TimeRemainingMinutesAndSeconds { get; set; } } public class GetDictionaries diff --git a/src/ui/Logic/VideoPreviewGenerator.cs b/src/ui/Logic/VideoPreviewGenerator.cs index 2c7032893..0e705a3da 100644 --- a/src/ui/Logic/VideoPreviewGenerator.cs +++ b/src/ui/Logic/VideoPreviewGenerator.cs @@ -32,7 +32,7 @@ namespace Nikse.SubtitleEdit.Logic } } - public static Process GenerateVideoFile(string previewFileName, int seconds, int width, int height, Color color, bool checkered, decimal frameRate) + public static Process GenerateVideoFile(string previewFileName, int seconds, int width, int height, Color color, bool checkered, decimal frameRate, DataReceivedEventHandler dataReceivedHandler = null) { Process processMakeVideo; @@ -49,16 +49,29 @@ namespace Nikse.SubtitleEdit.Logic processMakeVideo = GetFFmpegProcess(color, previewFileName, width, height, seconds, frameRate); } + SetupDataReceiveHandler(dataReceivedHandler, processMakeVideo); + return processMakeVideo; } + private static void SetupDataReceiveHandler(DataReceivedEventHandler dataReceivedHandler, Process processMakeVideo) + { + if (dataReceivedHandler != null) + { + processMakeVideo.StartInfo.RedirectStandardOutput = true; + processMakeVideo.StartInfo.RedirectStandardError = true; + processMakeVideo.OutputDataReceived += dataReceivedHandler; + processMakeVideo.ErrorDataReceived += dataReceivedHandler; + } + } + /// /// Generate a video with a burned-in Advanced Sub Station Alpha subtitle. /// /// Source video file name /// Source subtitle file name /// Output video file name with burned-in subtitle - public static Process GenerateHardcodedVideoFile(string inputVideoFileName, string assaSubtitleFileName, string outputVideoFileName) + public static Process GenerateHardcodedVideoFile(string inputVideoFileName, string assaSubtitleFileName, string outputVideoFileName, int width, int height, DataReceivedEventHandler dataReceivedHandler = null) { var ffmpegLocation = Configuration.Settings.General.FFmpegLocation; if (!Configuration.IsRunningOnWindows && (string.IsNullOrEmpty(ffmpegLocation) || !File.Exists(ffmpegLocation))) @@ -66,17 +79,21 @@ namespace Nikse.SubtitleEdit.Logic ffmpegLocation = "ffmpeg"; } - return new Process + var processMakeVideo = new Process { StartInfo = { FileName = ffmpegLocation, - Arguments = $"-i \"{inputVideoFileName}\" -vf \"ass={Path.GetFileName(assaSubtitleFileName)}\" -strict -2 \"{outputVideoFileName}\"", + Arguments = $"-i \"{inputVideoFileName}\" -vf \"ass={Path.GetFileName(assaSubtitleFileName)}\" -strict -2 -s {width}x{height} \"{outputVideoFileName}\" -v quiet -stats", UseShellExecute = false, CreateNoWindow = true, WorkingDirectory = Path.GetDirectoryName(assaSubtitleFileName), } }; + + SetupDataReceiveHandler(dataReceivedHandler, processMakeVideo); + + return processMakeVideo; } private static Process GetFFmpegProcess(string imageFileName, string outputFileName, int videoWidth, int videoHeight, int seconds, decimal frameRate)