From 503c61cb38c5ba0b0e527279a853d3fcf29264fe Mon Sep 17 00:00:00 2001 From: McoreD Date: Tue, 6 May 2014 19:23:12 +0800 Subject: [PATCH] Added FFmpeg recorder support Screen Recorder tab now has a checkBox: Run CLI afterwards so that you may execute your favourite Command Line Interface (e.g. x264.exe, ffmpeg.exe) to encode what has been recorded by ShareX. You may choose Video for Windows (VfW), FFmpeg or Animated Gif to record your screen. VfW will allow you to create uncompressed AVI streams or compressed streams using x264VfW etcc; FFmpeg will allow you to create MPEG4 streams - this is handy if you do not have Administrator access to install x264VfW to compress your streams. Run CLI afterwards checkBox is disabled for Animated GIF until we actually see a CLI that could take GIF and output to a movie file. --- HelpersLib/Enums.cs | 6 +- ScreenCaptureLib/AVICache.cs | 43 +---- ScreenCaptureLib/FFmpegRecorder.cs | 133 ++++++++++++++ ScreenCaptureLib/ImageRecorder.cs | 82 +++++++++ ScreenCaptureLib/ScreenCaptureLib.csproj | 8 + ScreenCaptureLib/ScreenRecorder.cs | 64 ++++--- ShareX/Forms/ScreenRecordForm.cs | 36 ++-- ShareX/Forms/TaskSettingsForm.Designer.cs | 200 ++++++++++++---------- ShareX/Forms/TaskSettingsForm.cs | 11 +- ShareX/TaskSettings.cs | 1 + 10 files changed, 409 insertions(+), 175 deletions(-) create mode 100644 ScreenCaptureLib/FFmpegRecorder.cs create mode 100644 ScreenCaptureLib/ImageRecorder.cs diff --git a/HelpersLib/Enums.cs b/HelpersLib/Enums.cs index 0bfa99f36..43c63f6c1 100644 --- a/HelpersLib/Enums.cs +++ b/HelpersLib/Enums.cs @@ -225,10 +225,10 @@ public enum ScreenRecordOutput { [Description("Animated GIF")] GIF, - [Description("AVI")] + [Description("Video for Windows (VfW)")] AVI, - [Description("AVI CLI encoder")] - AVICommandLine + [Description("FFmpeg")] + FFmpeg, } public enum DownloaderFormStatus diff --git a/ScreenCaptureLib/AVICache.cs b/ScreenCaptureLib/AVICache.cs index f22f766e4..ea679ed1e 100644 --- a/ScreenCaptureLib/AVICache.cs +++ b/ScreenCaptureLib/AVICache.cs @@ -31,15 +31,9 @@ You should have received a copy of the GNU General Public License namespace ScreenCaptureLib { - public class AVICache : IDisposable + public class AVICache : ImageRecorder { - public bool IsWorking { get; private set; } - public AVIOptions Options { get; set; } - private AVIWriter aviWriter; - private Task task; - private BlockingCollection imageQueue; - private int position; public AVICache(AVIOptions options) { @@ -50,7 +44,7 @@ public AVICache(AVIOptions options) imageQueue = new BlockingCollection(); } - private void StartConsumerThread() + protected override void StartConsumerThread() { if (!IsWorking) { @@ -95,43 +89,14 @@ private void StartConsumerThread() } } - public void AddImageAsync(Image img) - { - if (!IsWorking) - { - StartConsumerThread(); - } - - /*if (imageQueue.Count > 0) - { - Debug.WriteLine("ImageQueue count: " + imageQueue.Count); - }*/ - - imageQueue.Add(img); - } - - public void Finish() - { - if (IsWorking) - { - imageQueue.CompleteAdding(); - task.Wait(); - } - - Dispose(); - } - - public void Dispose() + public override void Dispose() { if (aviWriter != null) { aviWriter.Dispose(); } - if (imageQueue != null) - { - imageQueue.Dispose(); - } + base.Dispose(); } } } \ No newline at end of file diff --git a/ScreenCaptureLib/FFmpegRecorder.cs b/ScreenCaptureLib/FFmpegRecorder.cs new file mode 100644 index 000000000..2dbc1a1bc --- /dev/null +++ b/ScreenCaptureLib/FFmpegRecorder.cs @@ -0,0 +1,133 @@ +#region License Information (GPL v3) + +/* + ShareX - A program that allows you to take screenshots and share any file type + Copyright (C) 2008-2014 ShareX Developers + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Optionally you can also view the license at . +*/ + +#endregion License Information (GPL v3) + +using AForge.Video.FFMPEG; +using HelpersLib; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace ScreenCaptureLib +{ + public class FFmpegRecorder : ImageRecorder + { + private VideoFileWriter ffmpegWriter; + + private static readonly string[] ffMpegFiles = new string[] { "avcodec-53.dll", + "avdevice-53.dll", + "avfilter-2.dll", + "avformat-53.dll", + "avutil-51.dll", + "swresample-0.dll", + "swscale-2.dll" }; + + public FFmpegRecorder(AVIOptions options) + { + Options = options; + + Helpers.CreateDirectoryIfNotExist(Options.OutputPath); + ffmpegWriter = new VideoFileWriter(); + ffmpegWriter.Open(options.OutputPath, options.Size.Width, options.Size.Height, options.FPS, AForge.Video.FFMPEG.VideoCodec.MPEG4); + imageQueue = new BlockingCollection(); + } + + protected override void StartConsumerThread() + { + if (!IsWorking) + { + IsWorking = true; + + task = TaskEx.Run(() => + { + try + { + position = 0; + + while (!imageQueue.IsCompleted) + { + Image img = null; + + try + { + img = imageQueue.Take(); + + if (img != null) + { + //using (new DebugTimer("Frame saved")) + ffmpegWriter.WriteVideoFrame((Bitmap)img); + + position++; + } + } + catch (InvalidOperationException) + { + } + finally + { + if (img != null) img.Dispose(); + } + } + } + finally + { + IsWorking = false; + } + }); + } + } + + public override void Dispose() + { + if (ffmpegWriter != null) + { + ffmpegWriter.Dispose(); + } + + if (imageQueue != null) + { + imageQueue.Dispose(); + } + } + + public static bool HasDependencies() + { + foreach (string fn in ffMpegFiles) + { + string fp = Path.Combine(Application.StartupPath, fn); + if (!File.Exists(fp)) + { + return false; + } + } + return true; + } + } +} \ No newline at end of file diff --git a/ScreenCaptureLib/ImageRecorder.cs b/ScreenCaptureLib/ImageRecorder.cs new file mode 100644 index 000000000..567b7c99a --- /dev/null +++ b/ScreenCaptureLib/ImageRecorder.cs @@ -0,0 +1,82 @@ +#region License Information (GPL v3) + +/* + ShareX - A program that allows you to take screenshots and share any file type + Copyright (C) 2008-2014 ShareX Developers + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Optionally you can also view the license at . +*/ + +#endregion License Information (GPL v3) + +using HelpersLib; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ScreenCaptureLib +{ + public abstract class ImageRecorder : IDisposable + { + public bool IsWorking { get; protected set; } + public AVIOptions Options { get; set; } + + protected Task task; + protected BlockingCollection imageQueue; + protected int position; + + public void AddImageAsync(Image img) + { + if (!IsWorking) + { + StartConsumerThread(); + } + + /*if (imageQueue.Count > 0) + { + Debug.WriteLine("ImageQueue count: " + imageQueue.Count); + }*/ + + imageQueue.Add(img); + } + + protected abstract void StartConsumerThread(); + + public void Finish() + { + if (IsWorking) + { + imageQueue.CompleteAdding(); + task.Wait(); + } + + Dispose(); + } + + public virtual void Dispose() + { + if (imageQueue != null) + { + imageQueue.Dispose(); + } + } + } +} \ No newline at end of file diff --git a/ScreenCaptureLib/ScreenCaptureLib.csproj b/ScreenCaptureLib/ScreenCaptureLib.csproj index 4232745e3..4e863a66f 100644 --- a/ScreenCaptureLib/ScreenCaptureLib.csproj +++ b/ScreenCaptureLib/ScreenCaptureLib.csproj @@ -41,6 +41,12 @@ Off + + ..\Lib\AForge.Video.dll + + + ..\Lib\AForge.Video.FFMPEG.dll + False ..\packages\AsyncBridge.Net35.0.2.0\lib\net35-Client\AsyncBridge.Net35.dll @@ -57,6 +63,7 @@ + Form @@ -69,6 +76,7 @@ Form + True diff --git a/ScreenCaptureLib/ScreenRecorder.cs b/ScreenCaptureLib/ScreenRecorder.cs index 63273d211..9ccb2f5ac 100644 --- a/ScreenCaptureLib/ScreenRecorder.cs +++ b/ScreenCaptureLib/ScreenRecorder.cs @@ -98,7 +98,7 @@ private set private float durationSeconds; private Rectangle captureRectangle; private HardDiskCache hdCache; - private AVICache aviCache; + private ImageRecorder imageRecorder; private bool stopRequest; public ScreenRecorder(int fps, float durationSeconds, Rectangle captureRectangle, string cachePath, ScreenRecordOutput outputType, AVICOMPRESSOPTIONS compressOptions) @@ -114,21 +114,35 @@ public ScreenRecorder(int fps, float durationSeconds, Rectangle captureRectangle CachePath = cachePath; OutputType = outputType; - if (OutputType == ScreenRecordOutput.AVI || OutputType == ScreenRecordOutput.AVICommandLine) + switch (OutputType) { - Options = new AVIOptions - { - CompressOptions = compressOptions, - FPS = FPS, - OutputPath = CachePath, - Size = CaptureRectangle.Size - }; - - aviCache = new AVICache(Options); + case ScreenRecordOutput.AVI: + case ScreenRecordOutput.FFmpeg: + Options = new AVIOptions + { + CompressOptions = compressOptions, + FPS = FPS, + OutputPath = CachePath, + Size = CaptureRectangle.Size + }; + break; + case ScreenRecordOutput.GIF: + hdCache = new HardDiskCache(CachePath); + break; + default: + throw new Exception("Not all possible ScreenRecordOutput types are handled."); } - else if (OutputType == ScreenRecordOutput.GIF) + + if (Options != null) { - hdCache = new HardDiskCache(CachePath); + if (OutputType == ScreenRecordOutput.AVI) + { + imageRecorder = new AVICache(Options); + } + else if (OutputType == ScreenRecordOutput.FFmpeg) + { + imageRecorder = new FFmpegRecorder(Options); + } } } @@ -152,9 +166,9 @@ public void StartRecording() Image img = Screenshot.CaptureRectangle(CaptureRectangle); //DebugHelper.WriteLine("Screen capture: " + (int)timer.ElapsedMilliseconds); - if (OutputType == ScreenRecordOutput.AVI || OutputType == ScreenRecordOutput.AVICommandLine) + if (OutputType == ScreenRecordOutput.AVI || OutputType == ScreenRecordOutput.FFmpeg) { - aviCache.AddImageAsync(img); + imageRecorder.AddImageAsync(img); } else if (OutputType == ScreenRecordOutput.GIF) { @@ -176,13 +190,17 @@ public void StartRecording() } } - if (OutputType == ScreenRecordOutput.AVI || OutputType == ScreenRecordOutput.AVICommandLine) + switch (OutputType) { - aviCache.Finish(); - } - else if (OutputType == ScreenRecordOutput.GIF) - { - hdCache.Finish(); + case ScreenRecordOutput.AVI: + case ScreenRecordOutput.FFmpeg: + imageRecorder.Finish(); + break; + case ScreenRecordOutput.GIF: + hdCache.Finish(); + break; + default: + throw new Exception("Not all possible ScreenRecordOutput types are handled."); } } @@ -245,9 +263,9 @@ public void Dispose() hdCache.Dispose(); } - if (aviCache != null) + if (imageRecorder != null) { - aviCache.Dispose(); + imageRecorder.Dispose(); } } } diff --git a/ShareX/Forms/ScreenRecordForm.cs b/ShareX/Forms/ScreenRecordForm.cs index a01762d73..e062ccc19 100644 --- a/ShareX/Forms/ScreenRecordForm.cs +++ b/ShareX/Forms/ScreenRecordForm.cs @@ -82,7 +82,7 @@ private void SelectRegion() public async void StartRecording(TaskSettings TaskSettings) { - if (TaskSettings.CaptureSettings.ScreenRecordOutput == ScreenRecordOutput.AVICommandLine) + if (TaskSettings.CaptureSettings.RunScreencastCLI) { if (!Program.Settings.VideoEncoders.IsValidIndex(TaskSettings.CaptureSettings.VideoEncoderSelected)) { @@ -96,6 +96,14 @@ public async void StartRecording(TaskSettings TaskSettings) return; } } + else if (TaskSettings.CaptureSettings.ScreenRecordOutput == ScreenRecordOutput.FFmpeg && !FFmpegRecorder.HasDependencies()) + { + if (MessageBox.Show("FFmpeg files are not present. Would you like to download them?", Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.Yes) + { + Helpers.OpenURL("http://aforgeffmpeg.codeplex.com"); + } + return; + } SelectRegion(); Screenshot.CaptureCursor = TaskSettings.CaptureSettings.ShowCursor; @@ -120,7 +128,8 @@ public async void StartRecording(TaskSettings TaskSettings) await TaskEx.Run(() => { - if (TaskSettings.CaptureSettings.ScreenRecordOutput == ScreenRecordOutput.AVI) + if (TaskSettings.CaptureSettings.ScreenRecordOutput == ScreenRecordOutput.AVI || + TaskSettings.CaptureSettings.ScreenRecordOutput == ScreenRecordOutput.FFmpeg) { path = Path.Combine(TaskSettings.CaptureFolder, TaskHelpers.GetFilename(TaskSettings, "avi")); } @@ -149,23 +158,22 @@ await TaskEx.Run(() => }); } - if (screenRecorder != null && TaskSettings.CaptureSettings.ScreenRecordOutput != ScreenRecordOutput.AVI) + if (screenRecorder != null) { TrayIcon.Icon = Resources.camcorder__pencil.ToIcon(); await TaskEx.Run(() => { - switch (TaskSettings.CaptureSettings.ScreenRecordOutput) + if (TaskSettings.CaptureSettings.ScreenRecordOutput == ScreenRecordOutput.GIF) { - case ScreenRecordOutput.GIF: - path = Path.Combine(TaskSettings.CaptureFolder, TaskHelpers.GetFilename(TaskSettings, "gif")); - screenRecorder.SaveAsGIF(path, TaskSettings.ImageSettings.ImageGIFQuality); - break; - case ScreenRecordOutput.AVICommandLine: - VideoEncoder encoder = Program.Settings.VideoEncoders[TaskSettings.CaptureSettings.VideoEncoderSelected]; - path = Path.Combine(TaskSettings.CaptureFolder, TaskHelpers.GetFilename(TaskSettings, encoder.OutputExtension)); - screenRecorder.EncodeUsingCommandLine(encoder, path); - break; + path = Path.Combine(TaskSettings.CaptureFolder, TaskHelpers.GetFilename(TaskSettings, "gif")); + screenRecorder.SaveAsGIF(path, TaskSettings.ImageSettings.ImageGIFQuality); + } + else if (TaskSettings.CaptureSettings.RunScreencastCLI) + { + VideoEncoder encoder = Program.Settings.VideoEncoders[TaskSettings.CaptureSettings.VideoEncoderSelected]; + path = Path.Combine(TaskSettings.CaptureFolder, TaskHelpers.GetFilename(TaskSettings, encoder.OutputExtension)); + screenRecorder.EncodeUsingCommandLine(encoder, path); } }); } @@ -174,7 +182,7 @@ await TaskEx.Run(() => { if (screenRecorder != null) { - if (TaskSettings.CaptureSettings.ScreenRecordOutput == ScreenRecordOutput.AVICommandLine && + if (TaskSettings.CaptureSettings.RunScreencastCLI && !string.IsNullOrEmpty(screenRecorder.CachePath) && File.Exists(screenRecorder.CachePath)) { File.Delete(screenRecorder.CachePath); diff --git a/ShareX/Forms/TaskSettingsForm.Designer.cs b/ShareX/Forms/TaskSettingsForm.Designer.cs index 37a1917ea..7c78f0018 100644 --- a/ShareX/Forms/TaskSettingsForm.Designer.cs +++ b/ShareX/Forms/TaskSettingsForm.Designer.cs @@ -41,16 +41,12 @@ private void InitializeComponent() this.tpTask = new System.Windows.Forms.TabPage(); this.chkOverrideFTP = new System.Windows.Forms.CheckBox(); this.cboFTPaccounts = new System.Windows.Forms.ComboBox(); - this.btnAfterCapture = new HelpersLib.MenuButton(); - this.btnAfterUpload = new HelpersLib.MenuButton(); - this.btnDestinations = new HelpersLib.MenuButton(); this.cmsDestinations = new System.Windows.Forms.ContextMenuStrip(this.components); this.tsmiImageUploaders = new System.Windows.Forms.ToolStripMenuItem(); this.tsmiTextUploaders = new System.Windows.Forms.ToolStripMenuItem(); this.tsmiFileUploaders = new System.Windows.Forms.ToolStripMenuItem(); this.tsmiURLShorteners = new System.Windows.Forms.ToolStripMenuItem(); this.tsmiSocialServices = new System.Windows.Forms.ToolStripMenuItem(); - this.btnTask = new HelpersLib.MenuButton(); this.tpGeneral = new System.Windows.Forms.TabPage(); this.panelGeneral = new System.Windows.Forms.Panel(); this.lblAfterTaskNotification = new System.Windows.Forms.Label(); @@ -125,10 +121,6 @@ private void InitializeComponent() this.tpActions = new System.Windows.Forms.TabPage(); this.pActions = new System.Windows.Forms.Panel(); this.btnActionsAdd = new System.Windows.Forms.Button(); - this.lvActions = new HelpersLib.MyListView(); - this.chActionsName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.chActionsPath = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.chActionsArgs = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.btnActionsEdit = new System.Windows.Forms.Button(); this.btnActionsRemove = new System.Windows.Forms.Button(); this.chkUseDefaultActions = new System.Windows.Forms.CheckBox(); @@ -161,6 +153,15 @@ private void InitializeComponent() this.tpAdvanced = new System.Windows.Forms.TabPage(); this.pgTaskSettings = new System.Windows.Forms.PropertyGrid(); this.chkUseDefaultAdvancedSettings = new System.Windows.Forms.CheckBox(); + this.chkRunScreencastCLI = new System.Windows.Forms.CheckBox(); + this.btnAfterCapture = new HelpersLib.MenuButton(); + this.btnAfterUpload = new HelpersLib.MenuButton(); + this.btnDestinations = new HelpersLib.MenuButton(); + this.btnTask = new HelpersLib.MenuButton(); + this.lvActions = new HelpersLib.MyListView(); + this.chActionsName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.chActionsPath = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.chActionsArgs = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.tcHotkeySettings.SuspendLayout(); this.tpTask.SuspendLayout(); this.cmsDestinations.SuspendLayout(); @@ -323,42 +324,6 @@ private void InitializeComponent() this.cboFTPaccounts.TabIndex = 13; this.cboFTPaccounts.SelectedIndexChanged += new System.EventHandler(this.cboFTPaccounts_SelectedIndexChanged); // - // btnAfterCapture - // - this.btnAfterCapture.Location = new System.Drawing.Point(6, 93); - this.btnAfterCapture.Menu = this.cmsAfterCapture; - this.btnAfterCapture.Name = "btnAfterCapture"; - this.btnAfterCapture.Size = new System.Drawing.Size(506, 23); - this.btnAfterCapture.TabIndex = 4; - this.btnAfterCapture.Text = "After capture..."; - this.btnAfterCapture.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.btnAfterCapture.UseMnemonic = false; - this.btnAfterCapture.UseVisualStyleBackColor = true; - // - // btnAfterUpload - // - this.btnAfterUpload.Location = new System.Drawing.Point(6, 149); - this.btnAfterUpload.Menu = this.cmsAfterUpload; - this.btnAfterUpload.Name = "btnAfterUpload"; - this.btnAfterUpload.Size = new System.Drawing.Size(506, 23); - this.btnAfterUpload.TabIndex = 6; - this.btnAfterUpload.Text = "After upload..."; - this.btnAfterUpload.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.btnAfterUpload.UseMnemonic = false; - this.btnAfterUpload.UseVisualStyleBackColor = true; - // - // btnDestinations - // - this.btnDestinations.Location = new System.Drawing.Point(6, 205); - this.btnDestinations.Menu = this.cmsDestinations; - this.btnDestinations.Name = "btnDestinations"; - this.btnDestinations.Size = new System.Drawing.Size(506, 23); - this.btnDestinations.TabIndex = 8; - this.btnDestinations.Text = "Destinations..."; - this.btnDestinations.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.btnDestinations.UseMnemonic = false; - this.btnDestinations.UseVisualStyleBackColor = true; - // // cmsDestinations // this.cmsDestinations.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -405,18 +370,6 @@ private void InitializeComponent() this.tsmiSocialServices.Size = new System.Drawing.Size(212, 22); this.tsmiSocialServices.Text = "Social networking services"; // - // btnTask - // - this.btnTask.Location = new System.Drawing.Point(6, 37); - this.btnTask.Menu = this.cmsTask; - this.btnTask.Name = "btnTask"; - this.btnTask.Size = new System.Drawing.Size(506, 23); - this.btnTask.TabIndex = 2; - this.btnTask.Text = "Task..."; - this.btnTask.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.btnTask.UseMnemonic = false; - this.btnTask.UseVisualStyleBackColor = true; - // // tpGeneral // this.tpGeneral.Controls.Add(this.panelGeneral); @@ -1106,6 +1059,7 @@ private void InitializeComponent() // // tpScreenRecorder // + this.tpScreenRecorder.Controls.Add(this.chkRunScreencastCLI); this.tpScreenRecorder.Controls.Add(this.lblScreenRecorderCLI); this.tpScreenRecorder.Controls.Add(this.btnScreenRecorderAVIOptions); this.tpScreenRecorder.Controls.Add(this.btnEncoderConfig); @@ -1137,7 +1091,7 @@ private void InitializeComponent() // // btnScreenRecorderAVIOptions // - this.btnScreenRecorderAVIOptions.Location = new System.Drawing.Point(200, 11); + this.btnScreenRecorderAVIOptions.Location = new System.Drawing.Point(232, 11); this.btnScreenRecorderAVIOptions.Name = "btnScreenRecorderAVIOptions"; this.btnScreenRecorderAVIOptions.Size = new System.Drawing.Size(96, 23); this.btnScreenRecorderAVIOptions.TabIndex = 12; @@ -1233,9 +1187,9 @@ private void InitializeComponent() // this.cbScreenRecorderOutput.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.cbScreenRecorderOutput.FormattingEnabled = true; - this.cbScreenRecorderOutput.Location = new System.Drawing.Point(64, 12); + this.cbScreenRecorderOutput.Location = new System.Drawing.Point(72, 12); this.cbScreenRecorderOutput.Name = "cbScreenRecorderOutput"; - this.cbScreenRecorderOutput.Size = new System.Drawing.Size(128, 21); + this.cbScreenRecorderOutput.Size = new System.Drawing.Size(152, 21); this.cbScreenRecorderOutput.TabIndex = 1; this.cbScreenRecorderOutput.SelectedIndexChanged += new System.EventHandler(this.cbScreenRecorderOutput_SelectedIndexChanged); // @@ -1244,9 +1198,9 @@ private void InitializeComponent() this.lblScreenRecorderOutput.AutoSize = true; this.lblScreenRecorderOutput.Location = new System.Drawing.Point(16, 16); this.lblScreenRecorderOutput.Name = "lblScreenRecorderOutput"; - this.lblScreenRecorderOutput.Size = new System.Drawing.Size(42, 13); + this.lblScreenRecorderOutput.Size = new System.Drawing.Size(54, 13); this.lblScreenRecorderOutput.TabIndex = 0; - this.lblScreenRecorderOutput.Text = "Output:"; + this.lblScreenRecorderOutput.Text = "Recorder:"; // // cbScreenRecorderFixedDuration // @@ -1342,38 +1296,6 @@ private void InitializeComponent() this.btnActionsAdd.UseVisualStyleBackColor = true; this.btnActionsAdd.Click += new System.EventHandler(this.btnActionsAdd_Click); // - // lvActions - // - this.lvActions.CheckBoxes = true; - this.lvActions.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.chActionsName, - this.chActionsPath, - this.chActionsArgs}); - this.lvActions.FullRowSelect = true; - this.lvActions.Location = new System.Drawing.Point(8, 40); - this.lvActions.MultiSelect = false; - this.lvActions.Name = "lvActions"; - this.lvActions.Size = new System.Drawing.Size(496, 280); - this.lvActions.TabIndex = 3; - this.lvActions.UseCompatibleStateImageBehavior = false; - this.lvActions.View = System.Windows.Forms.View.Details; - this.lvActions.ItemChecked += new System.Windows.Forms.ItemCheckedEventHandler(this.lvActions_ItemChecked); - // - // chActionsName - // - this.chActionsName.Text = "Name"; - this.chActionsName.Width = 100; - // - // chActionsPath - // - this.chActionsPath.Text = "Path"; - this.chActionsPath.Width = 250; - // - // chActionsArgs - // - this.chActionsArgs.Text = "Args"; - this.chActionsArgs.Width = 134; - // // btnActionsEdit // this.btnActionsEdit.Location = new System.Drawing.Point(88, 8); @@ -1722,6 +1644,97 @@ private void InitializeComponent() this.chkUseDefaultAdvancedSettings.UseVisualStyleBackColor = true; this.chkUseDefaultAdvancedSettings.CheckedChanged += new System.EventHandler(this.chkUseDefaultAdvancedSettings_CheckedChanged); // + // chkRunScreencastCLI + // + this.chkRunScreencastCLI.AutoSize = true; + this.chkRunScreencastCLI.Location = new System.Drawing.Point(336, 14); + this.chkRunScreencastCLI.Name = "chkRunScreencastCLI"; + this.chkRunScreencastCLI.Size = new System.Drawing.Size(117, 17); + this.chkRunScreencastCLI.TabIndex = 14; + this.chkRunScreencastCLI.Text = "Run CLI afterwards"; + this.chkRunScreencastCLI.UseVisualStyleBackColor = true; + this.chkRunScreencastCLI.CheckedChanged += new System.EventHandler(this.chkRunScreencastCLI_CheckedChanged); + // + // btnAfterCapture + // + this.btnAfterCapture.Location = new System.Drawing.Point(6, 93); + this.btnAfterCapture.Menu = this.cmsAfterCapture; + this.btnAfterCapture.Name = "btnAfterCapture"; + this.btnAfterCapture.Size = new System.Drawing.Size(506, 23); + this.btnAfterCapture.TabIndex = 4; + this.btnAfterCapture.Text = "After capture..."; + this.btnAfterCapture.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.btnAfterCapture.UseMnemonic = false; + this.btnAfterCapture.UseVisualStyleBackColor = true; + // + // btnAfterUpload + // + this.btnAfterUpload.Location = new System.Drawing.Point(6, 149); + this.btnAfterUpload.Menu = this.cmsAfterUpload; + this.btnAfterUpload.Name = "btnAfterUpload"; + this.btnAfterUpload.Size = new System.Drawing.Size(506, 23); + this.btnAfterUpload.TabIndex = 6; + this.btnAfterUpload.Text = "After upload..."; + this.btnAfterUpload.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.btnAfterUpload.UseMnemonic = false; + this.btnAfterUpload.UseVisualStyleBackColor = true; + // + // btnDestinations + // + this.btnDestinations.Location = new System.Drawing.Point(6, 205); + this.btnDestinations.Menu = this.cmsDestinations; + this.btnDestinations.Name = "btnDestinations"; + this.btnDestinations.Size = new System.Drawing.Size(506, 23); + this.btnDestinations.TabIndex = 8; + this.btnDestinations.Text = "Destinations..."; + this.btnDestinations.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.btnDestinations.UseMnemonic = false; + this.btnDestinations.UseVisualStyleBackColor = true; + // + // btnTask + // + this.btnTask.Location = new System.Drawing.Point(6, 37); + this.btnTask.Menu = this.cmsTask; + this.btnTask.Name = "btnTask"; + this.btnTask.Size = new System.Drawing.Size(506, 23); + this.btnTask.TabIndex = 2; + this.btnTask.Text = "Task..."; + this.btnTask.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.btnTask.UseMnemonic = false; + this.btnTask.UseVisualStyleBackColor = true; + // + // lvActions + // + this.lvActions.CheckBoxes = true; + this.lvActions.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.chActionsName, + this.chActionsPath, + this.chActionsArgs}); + this.lvActions.FullRowSelect = true; + this.lvActions.Location = new System.Drawing.Point(8, 40); + this.lvActions.MultiSelect = false; + this.lvActions.Name = "lvActions"; + this.lvActions.Size = new System.Drawing.Size(496, 280); + this.lvActions.TabIndex = 3; + this.lvActions.UseCompatibleStateImageBehavior = false; + this.lvActions.View = System.Windows.Forms.View.Details; + this.lvActions.ItemChecked += new System.Windows.Forms.ItemCheckedEventHandler(this.lvActions_ItemChecked); + // + // chActionsName + // + this.chActionsName.Text = "Name"; + this.chActionsName.Width = 100; + // + // chActionsPath + // + this.chActionsPath.Text = "Path"; + this.chActionsPath.Width = 250; + // + // chActionsArgs + // + this.chActionsArgs.Text = "Args"; + this.chActionsArgs.Width = 134; + // // TaskSettingsForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -1926,6 +1939,7 @@ private void InitializeComponent() private System.Windows.Forms.CheckBox cbClipboardUploadAutoIndexFolder; private System.Windows.Forms.Button btnScreenRecorderAVIOptions; private System.Windows.Forms.Label lblScreenRecorderCLI; + private System.Windows.Forms.CheckBox chkRunScreencastCLI; diff --git a/ShareX/Forms/TaskSettingsForm.cs b/ShareX/Forms/TaskSettingsForm.cs index bdba8c887..00c601c4c 100644 --- a/ShareX/Forms/TaskSettingsForm.cs +++ b/ShareX/Forms/TaskSettingsForm.cs @@ -160,6 +160,7 @@ public TaskSettingsForm(TaskSettings hotkeySetting, bool isDefault = false) // Capture / Screen recorder cbScreenRecorderOutput.Items.AddRange(Helpers.GetEnumDescriptions()); cbScreenRecorderOutput.SelectedIndex = (int)TaskSettings.CaptureSettings.ScreenRecordOutput; + chkRunScreencastCLI.Checked = TaskSettings.CaptureSettings.RunScreencastCLI; UpdateVideoEncoders(); nudScreenRecorderFPS.Value = TaskSettings.CaptureSettings.ScreenRecordFPS; @@ -644,9 +645,8 @@ private void cbCaptureTransparent_CheckedChanged(object sender, EventArgs e) private void cbScreenRecorderOutput_SelectedIndexChanged(object sender, EventArgs e) { TaskSettings.CaptureSettings.ScreenRecordOutput = (ScreenRecordOutput)cbScreenRecorderOutput.SelectedIndex; - btnScreenRecorderAVIOptions.Enabled = TaskSettings.CaptureSettings.ScreenRecordOutput == ScreenRecordOutput.AVI || - TaskSettings.CaptureSettings.ScreenRecordOutput == ScreenRecordOutput.AVICommandLine; - btnEncoderConfig.Enabled = cboEncoder.Enabled = TaskSettings.CaptureSettings.ScreenRecordOutput == ScreenRecordOutput.AVICommandLine; + btnScreenRecorderAVIOptions.Enabled = TaskSettings.CaptureSettings.ScreenRecordOutput == ScreenRecordOutput.AVI; + btnEncoderConfig.Enabled = cboEncoder.Enabled = chkRunScreencastCLI.Enabled = TaskSettings.CaptureSettings.ScreenRecordOutput != ScreenRecordOutput.GIF; } private void btnScreenRecorderAVIOptions_Click(object sender, EventArgs e) @@ -702,6 +702,11 @@ private void cbScreenRecorderFixedDuration_CheckedChanged(object sender, EventAr nudScreenRecorderDuration.Enabled = TaskSettings.CaptureSettings.ScreenRecordFixedDuration; } + private void chkRunScreencastCLI_CheckedChanged(object sender, EventArgs e) + { + TaskSettings.CaptureSettings.RunScreencastCLI = btnEncoderConfig.Enabled = cboEncoder.Enabled = chkRunScreencastCLI.Checked; + } + private void nudScreenRecorderDuration_ValueChanged(object sender, EventArgs e) { TaskSettings.CaptureSettings.ScreenRecordDuration = (float)nudScreenRecorderDuration.Value; diff --git a/ShareX/TaskSettings.cs b/ShareX/TaskSettings.cs index 625b0bc91..8d2e63d09 100644 --- a/ShareX/TaskSettings.cs +++ b/ShareX/TaskSettings.cs @@ -284,6 +284,7 @@ public class TaskSettingsCapture public float ScreenRecordDuration = 3f; public float ScreenRecordStartDelay = 0.1f; + public bool RunScreencastCLI = false; public int VideoEncoderSelected = 0; #endregion Capture / Screen recorder