diff --git a/ShareX.HelpersLib/Helpers/FileHelpers.cs b/ShareX.HelpersLib/Helpers/FileHelpers.cs
index 59f9c6db5..c93f57bb3 100644
--- a/ShareX.HelpersLib/Helpers/FileHelpers.cs
+++ b/ShareX.HelpersLib/Helpers/FileHelpers.cs
@@ -131,6 +131,21 @@ public static string ChangeFileNameExtension(string fileName, string extension)
return fileName;
}
+ public static string AppendTextToFileName(string filePath, string text)
+ {
+ if (!string.IsNullOrEmpty(filePath))
+ {
+ int pos = filePath.LastIndexOf('.');
+
+ if (pos >= 0)
+ {
+ return filePath.Substring(0, pos) + text + filePath.Substring(pos);
+ }
+ }
+
+ return filePath + text;
+ }
+
public static string AppendExtension(string filePath, string extension)
{
return filePath.TrimEnd('.') + '.' + extension.TrimStart('.');
diff --git a/ShareX.MediaLib/FFmpegCLIManager.cs b/ShareX.MediaLib/FFmpegCLIManager.cs
index 4dc7daf4e..6796e335f 100644
--- a/ShareX.MediaLib/FFmpegCLIManager.cs
+++ b/ShareX.MediaLib/FFmpegCLIManager.cs
@@ -291,7 +291,7 @@ public void ConcatenateVideos(string[] inputFiles, string outputFile, bool autoD
{
foreach (string inputFile in inputFiles)
{
- if (!inputFile.Equals(outputFile, StringComparison.OrdinalIgnoreCase) && File.Exists(inputFile))
+ if (File.Exists(inputFile))
{
File.Delete(inputFile);
}
diff --git a/ShareX.ScreenCaptureLib/Enums.cs b/ShareX.ScreenCaptureLib/Enums.cs
index 710295771..01aeeccfd 100644
--- a/ShareX.ScreenCaptureLib/Enums.cs
+++ b/ShareX.ScreenCaptureLib/Enums.cs
@@ -339,6 +339,6 @@ public enum BorderStyle // Localized
public enum ScreenRecordState
{
- Waiting, BeforeStart, AfterStart, AfterRecordingStart, Encoding
+ Waiting, BeforeStart, AfterStart, AfterRecordingStart, RecordingEnd, Encoding
}
}
\ No newline at end of file
diff --git a/ShareX.ScreenCaptureLib/Forms/ScreenRecordForm.Designer.cs b/ShareX.ScreenCaptureLib/Forms/ScreenRecordForm.Designer.cs
index b198514cf..766cb6326 100644
--- a/ShareX.ScreenCaptureLib/Forms/ScreenRecordForm.Designer.cs
+++ b/ShareX.ScreenCaptureLib/Forms/ScreenRecordForm.Designer.cs
@@ -26,6 +26,7 @@ private void InitializeComponent()
this.tsmiStart = new System.Windows.Forms.ToolStripMenuItem();
this.tsmiAbort = new System.Windows.Forms.ToolStripMenuItem();
this.niTray = new System.Windows.Forms.NotifyIcon(this.components);
+ this.btnPause = new ShareX.HelpersLib.NoFocusBorderButton();
this.pInfo.SuspendLayout();
this.cmsMain.SuspendLayout();
this.SuspendLayout();
@@ -54,6 +55,7 @@ private void InitializeComponent()
// pInfo
//
resources.ApplyResources(this.pInfo, "pInfo");
+ this.pInfo.Controls.Add(this.btnPause);
this.pInfo.Controls.Add(this.btnAbort);
this.pInfo.Controls.Add(this.btnStart);
this.pInfo.Controls.Add(this.lblTimer);
@@ -87,6 +89,12 @@ private void InitializeComponent()
resources.ApplyResources(this.niTray, "niTray");
this.niTray.MouseClick += new System.Windows.Forms.MouseEventHandler(this.btnStart_MouseClick);
//
+ // btnPause
+ //
+ resources.ApplyResources(this.btnPause, "btnPause");
+ this.btnPause.Name = "btnPause";
+ this.btnPause.MouseClick += new System.Windows.Forms.MouseEventHandler(this.btnPause_MouseClick);
+ //
// ScreenRecordForm
//
resources.ApplyResources(this, "$this");
@@ -116,5 +124,6 @@ private void InitializeComponent()
private System.Windows.Forms.ToolStripMenuItem tsmiStart;
private System.Windows.Forms.ToolStripMenuItem tsmiAbort;
private System.Windows.Forms.NotifyIcon niTray;
+ private HelpersLib.NoFocusBorderButton btnPause;
}
}
\ No newline at end of file
diff --git a/ShareX.ScreenCaptureLib/Forms/ScreenRecordForm.cs b/ShareX.ScreenCaptureLib/Forms/ScreenRecordForm.cs
index 570ee9e54..40f3e57ec 100644
--- a/ShareX.ScreenCaptureLib/Forms/ScreenRecordForm.cs
+++ b/ShareX.ScreenCaptureLib/Forms/ScreenRecordForm.cs
@@ -44,6 +44,7 @@ public partial class ScreenRecordForm : Form
public Stopwatch Timer { get; private set; }
public ManualResetEvent RecordResetEvent { get; set; }
public bool IsStopRequested { get; private set; }
+ public bool IsPauseRequested { get; private set; }
public bool IsAbortRequested { get; private set; }
public bool ActivateWindow { get; set; } = true;
@@ -171,6 +172,13 @@ public void StartRecordingTimer()
UpdateTimer();
}
+ public void StopRecordingTimer()
+ {
+ Timer.Stop();
+ timerRefresh.Stop();
+ UpdateTimer();
+ }
+
private void UpdateTimer()
{
if (!IsDisposed)
@@ -216,6 +224,14 @@ private void btnStart_MouseClick(object sender, MouseEventArgs e)
}
}
+ private void btnPause_MouseClick(object sender, MouseEventArgs e)
+ {
+ if (e.Button == MouseButtons.Left)
+ {
+ StartStopRecording(true);
+ }
+ }
+
private void btnAbort_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
@@ -228,12 +244,18 @@ private void btnAbort_MouseClick(object sender, MouseEventArgs e)
}
}
- public void StartStopRecording()
+ public void StartStopRecording(bool isPause = false)
{
if (IsWorking)
{
IsStopRequested = true;
+ if (isPause)
+ {
+ RecordResetEvent.Reset();
+ IsPauseRequested = true;
+ }
+
if (!IsRecording)
{
IsAbortRequested = true;
@@ -274,6 +296,7 @@ public void ChangeState(ScreenRecordState state)
break;
case ScreenRecordState.AfterStart:
IsWorking = true;
+ IsPauseRequested = false;
string trayTextAfterStart = "ShareX - " + Resources.ScreenRecordForm_StartRecording_Click_tray_icon_to_stop_recording_;
niTray.Text = trayTextAfterStart.Truncate(63);
niTray.Icon = Resources.control_record.ToIcon();
@@ -284,6 +307,11 @@ public void ChangeState(ScreenRecordState state)
IsRecording = true;
StartRecordingTimer();
break;
+ case ScreenRecordState.RecordingEnd:
+ IsWorking = false;
+ IsRecording = false;
+ StopRecordingTimer();
+ break;
case ScreenRecordState.Encoding:
Hide();
string trayTextAfterStop = "ShareX - " + Resources.ScreenRecordForm_StartRecording_Encoding___;
diff --git a/ShareX.ScreenCaptureLib/Forms/ScreenRecordForm.resx b/ShareX.ScreenCaptureLib/Forms/ScreenRecordForm.resx
index db39e7c6c..c5d8d4d8f 100644
--- a/ShareX.ScreenCaptureLib/Forms/ScreenRecordForm.resx
+++ b/ShareX.ScreenCaptureLib/Forms/ScreenRecordForm.resx
@@ -151,19 +151,19 @@
pInfo
- 1
+ 2
Arial, 12pt
- 190, 0
+ 285, 0
0, 0, 0, 0
- 90, 36
+ 92, 36
2
@@ -184,7 +184,7 @@
pInfo
- 2
+ 3
17, 17
@@ -196,7 +196,7 @@
Arial, 12pt
- 95, 0
+ 190, 0
0, 0, 0, 0
@@ -220,7 +220,7 @@
pInfo
- 0
+ 1
True
@@ -228,11 +228,47 @@
GrowAndShrink
+
+ Flat
+
+
+ Arial, 12pt
+
+
+ NoControl
+
+
+ 95, 0
+
+
+ 0, 0, 0, 0
+
+
+ 96, 36
+
+
+ 3
+
+
+ Pause
+
+
+ btnPause
+
+
+ ShareX.HelpersLib.NoFocusBorderButton, ShareX.HelpersLib, Version=14.1.2.0, Culture=neutral, PublicKeyToken=null
+
+
+ pInfo
+
+
+ 0
+
8, 8
- 280, 36
+ 377, 36
0
diff --git a/ShareX/ScreenRecordManager.cs b/ShareX/ScreenRecordManager.cs
index acf93bcb7..626c7ac67 100644
--- a/ShareX/ScreenRecordManager.cs
+++ b/ShareX/ScreenRecordManager.cs
@@ -24,6 +24,7 @@ You should have received a copy of the GNU General Public License
#endregion License Information (GPL v3)
using ShareX.HelpersLib;
+using ShareX.MediaLib;
using ShareX.Properties;
using ShareX.ScreenCaptureLib;
using System;
@@ -167,6 +168,8 @@ private static void StartRecording(ScreenRecordOutput outputType, TaskSettings t
IsRecording = true;
string path = "";
+ string concatPath = "";
+ string tempPath = "";
bool abortRequested = false;
float duration = taskSettings.CaptureSettings.ScreenRecordFixedDuration ? taskSettings.CaptureSettings.ScreenRecordDuration : 0;
@@ -202,61 +205,88 @@ private static void StartRecording(ScreenRecordOutput outputType, TaskSettings t
{
abortRequested = true;
}
-
- if (!abortRequested)
+ else
{
- recordForm.ChangeState(ScreenRecordState.BeforeStart);
-
- if (taskSettings.CaptureSettings.ScreenRecordAutoStart)
- {
- int delay = (int)(taskSettings.CaptureSettings.ScreenRecordStartDelay * 1000);
-
- if (delay > 0)
- {
- recordForm.InvokeSafe(() => recordForm.StartCountdown(delay));
-
- recordForm.RecordResetEvent.WaitOne(delay);
- }
- }
- else
- {
- recordForm.RecordResetEvent.WaitOne();
- }
-
- if (recordForm.IsAbortRequested)
- {
- abortRequested = true;
- }
+ concatPath = FileHelpers.AppendTextToFileName(path, "-concat");
+ FileHelpers.DeleteFile(concatPath);
+ tempPath = FileHelpers.AppendTextToFileName(path, "-temp");
+ FileHelpers.DeleteFile(tempPath);
+ }
+ do
+ {
if (!abortRequested)
{
- ScreenRecordingOptions options = new ScreenRecordingOptions()
+ recordForm.ChangeState(ScreenRecordState.BeforeStart);
+
+ if (recordForm.IsPauseRequested || !taskSettings.CaptureSettings.ScreenRecordAutoStart)
{
- IsRecording = true,
- IsLossless = taskSettings.CaptureSettings.ScreenRecordTwoPassEncoding,
- FFmpeg = taskSettings.CaptureSettings.FFmpegOptions,
- FPS = fps,
- Duration = duration,
- OutputPath = path,
- CaptureArea = captureRectangle,
- DrawCursor = taskSettings.CaptureSettings.ScreenRecordShowCursor
- };
+ recordForm.RecordResetEvent.WaitOne();
+ }
+ else
+ {
+ int delay = (int)(taskSettings.CaptureSettings.ScreenRecordStartDelay * 1000);
- Screenshot screenshot = TaskHelpers.GetScreenshot(taskSettings);
- screenshot.CaptureCursor = taskSettings.CaptureSettings.ScreenRecordShowCursor;
+ if (delay > 0)
+ {
+ recordForm.InvokeSafe(() => recordForm.StartCountdown(delay));
- screenRecorder = new ScreenRecorder(ScreenRecordOutput.FFmpeg, options, screenshot, captureRectangle);
- screenRecorder.RecordingStarted += ScreenRecorder_RecordingStarted;
- screenRecorder.EncodingProgressChanged += ScreenRecorder_EncodingProgressChanged;
- recordForm.ChangeState(ScreenRecordState.AfterStart);
- screenRecorder.StartRecording();
+ recordForm.RecordResetEvent.WaitOne(delay);
+ }
+ }
if (recordForm.IsAbortRequested)
{
abortRequested = true;
}
+
+ if (recordForm.IsPauseRequested && File.Exists(path))
+ {
+ FileHelpers.RenameFile(path, concatPath);
+ }
+
+ if (!abortRequested)
+ {
+ ScreenRecordingOptions options = new ScreenRecordingOptions()
+ {
+ IsRecording = true,
+ IsLossless = taskSettings.CaptureSettings.ScreenRecordTwoPassEncoding,
+ FFmpeg = taskSettings.CaptureSettings.FFmpegOptions,
+ FPS = fps,
+ Duration = duration,
+ OutputPath = path,
+ CaptureArea = captureRectangle,
+ DrawCursor = taskSettings.CaptureSettings.ScreenRecordShowCursor
+ };
+
+ Screenshot screenshot = TaskHelpers.GetScreenshot(taskSettings);
+ screenshot.CaptureCursor = taskSettings.CaptureSettings.ScreenRecordShowCursor;
+
+ screenRecorder = new ScreenRecorder(ScreenRecordOutput.FFmpeg, options, screenshot, captureRectangle);
+ screenRecorder.RecordingStarted += ScreenRecorder_RecordingStarted;
+ screenRecorder.EncodingProgressChanged += ScreenRecorder_EncodingProgressChanged;
+ recordForm.ChangeState(ScreenRecordState.AfterStart);
+ screenRecorder.StartRecording();
+ recordForm.ChangeState(ScreenRecordState.RecordingEnd);
+
+ if (recordForm.IsAbortRequested)
+ {
+ abortRequested = true;
+ }
+ }
+
+ if (File.Exists(concatPath))
+ {
+ using (FFmpegCLIManager ffmpeg = new FFmpegCLIManager(taskSettings.CaptureSettings.FFmpegOptions.FFmpegPath))
+ {
+ ffmpeg.ShowError = true;
+ ffmpeg.ConcatenateVideos(new string[] { concatPath, path }, tempPath, true);
+ FileHelpers.RenameFile(tempPath, path);
+ }
+ }
}
}
+ while (recordForm.IsPauseRequested);
}
catch (Exception e)
{