mirror of
https://github.com/ShareX/ShareX.git
synced 2024-09-30 01:07:21 +13:00
Created FFmpegCLIHelper
ffmpeg.exe quits as soon as it starts!
This commit is contained in:
parent
58cd9990b4
commit
ca6c61fe8e
14 changed files with 266 additions and 70 deletions
96
HelpersLib/CLI/ExternalCLIManager.cs
Normal file
96
HelpersLib/CLI/ExternalCLIManager.cs
Normal file
|
@ -0,0 +1,96 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace HelpersLib
|
||||
{
|
||||
public abstract class ExternalCLIManager : IDisposable
|
||||
{
|
||||
protected Process CLI = new Process();
|
||||
|
||||
public StringBuilder Output = new StringBuilder();
|
||||
public StringBuilder Errors = new StringBuilder();
|
||||
|
||||
public delegate void ErrorDataReceivedHandler();
|
||||
public event ErrorDataReceivedHandler ErrorDataReceived;
|
||||
|
||||
public virtual void Run(string cliPath, string args = "")
|
||||
{
|
||||
ProcessStartInfo psi = new ProcessStartInfo(cliPath);
|
||||
psi.UseShellExecute = false;
|
||||
psi.ErrorDialog = false;
|
||||
psi.RedirectStandardInput = true;
|
||||
psi.RedirectStandardError = true;
|
||||
psi.RedirectStandardOutput = true;
|
||||
psi.Arguments = args;
|
||||
psi.WindowStyle = ProcessWindowStyle.Normal;
|
||||
|
||||
using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false))
|
||||
using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false))
|
||||
{
|
||||
CLI.OutputDataReceived += (sender, e) =>
|
||||
{
|
||||
if (e.Data == null)
|
||||
{
|
||||
outputWaitHandle.Set();
|
||||
}
|
||||
else
|
||||
{
|
||||
Output.AppendLine(e.Data);
|
||||
}
|
||||
};
|
||||
|
||||
CLI.ErrorDataReceived += (sender, e) =>
|
||||
{
|
||||
if (e.Data == null)
|
||||
{
|
||||
errorWaitHandle.Set();
|
||||
}
|
||||
else
|
||||
{
|
||||
Errors.AppendLine(e.Data);
|
||||
}
|
||||
};
|
||||
|
||||
CLI.StartInfo = psi;
|
||||
CLI.Start();
|
||||
|
||||
CLI.BeginOutputReadLine();
|
||||
CLI.WaitForExit();
|
||||
}
|
||||
}
|
||||
|
||||
public void SendCommand(string command)
|
||||
{
|
||||
if (CLI != null)
|
||||
{
|
||||
CLI.StandardInput.WriteLine(command);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Close()
|
||||
{
|
||||
CLI.CloseMainWindow();
|
||||
}
|
||||
|
||||
public virtual void OnErrorDataReceived()
|
||||
{
|
||||
if (ErrorDataReceived != null)
|
||||
{
|
||||
ErrorDataReceived();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (CLI != null)
|
||||
{
|
||||
CLI.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -87,6 +87,7 @@
|
|||
<Compile Include="ConvolutionMatrix.cs" />
|
||||
<Compile Include="ConvolutionMatrixManager.cs" />
|
||||
<Compile Include="EncoderProgram.cs" />
|
||||
<Compile Include="CLI\ExternalCLIManager.cs" />
|
||||
<Compile Include="FontSafe.cs" />
|
||||
<Compile Include="Helpers\MathHelpers.cs" />
|
||||
<Compile Include="MimeTypes.cs" />
|
||||
|
|
13
ScreenCaptureLib/CLIEncoder.cs
Normal file
13
ScreenCaptureLib/CLIEncoder.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
using HelpersLib;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ScreenCaptureLib
|
||||
{
|
||||
public abstract class CLIEncoder : ExternalCLIManager
|
||||
{
|
||||
public abstract void Record();
|
||||
}
|
||||
}
|
|
@ -63,9 +63,9 @@
|
|||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CLIEncoder.cs" />
|
||||
<Compile Include="Enums.cs" />
|
||||
<Compile Include="Screencast\FFmpegOptions.cs" />
|
||||
<Compile Include="Screencast\ScreencastOptions.cs" />
|
||||
<Compile Include="Screencast\FFmpegCLIHelper.cs" />
|
||||
<Compile Include="Screencast\AVIOptions.cs" />
|
||||
<Compile Include="Screencast\AviWriter.cs" />
|
||||
<Compile Include="Screencast\FFmpegCache.cs" />
|
||||
|
|
|
@ -32,10 +32,19 @@ You should have received a copy of the GNU General Public License
|
|||
|
||||
namespace ScreenCaptureLib
|
||||
{
|
||||
public class AVIOptions : ScreencastOptions
|
||||
public class AVIOptions
|
||||
{
|
||||
public string OutputPath;
|
||||
public int FPS;
|
||||
public Size Size;
|
||||
|
||||
// AVI
|
||||
public AVICOMPRESSOPTIONS CompressOptions;
|
||||
public bool ShowOptionsDialog;
|
||||
public IntPtr ParentWindow;
|
||||
|
||||
// FFmpeg
|
||||
public string CLIPath { get; set; }
|
||||
public int BitRate { get; set; }
|
||||
}
|
||||
}
|
78
ScreenCaptureLib/Screencast/FFmpegCLIHelper.cs
Normal file
78
ScreenCaptureLib/Screencast/FFmpegCLIHelper.cs
Normal file
|
@ -0,0 +1,78 @@
|
|||
#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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#endregion License Information (GPL v3)
|
||||
|
||||
using HelpersLib;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ScreenCaptureLib
|
||||
{
|
||||
public class FFmpegCLIHelper : CLIEncoder
|
||||
{
|
||||
public AVIOptions Options { get; private set; }
|
||||
|
||||
public FFmpegCLIHelper(AVIOptions options)
|
||||
{
|
||||
Options = options;
|
||||
|
||||
if (string.IsNullOrEmpty(options.CLIPath))
|
||||
{
|
||||
options.CLIPath = Path.Combine(Application.StartupPath, "ffmpeg.exe");
|
||||
}
|
||||
|
||||
Helpers.CreateDirectoryIfNotExist(Options.OutputPath);
|
||||
|
||||
this.ErrorDataReceived += Close;
|
||||
}
|
||||
|
||||
public override void Record()
|
||||
{
|
||||
StringBuilder args = new StringBuilder();
|
||||
args.Append("-f dshow -i video=\"screen-capture-recorder\"");
|
||||
if (Options.FPS > 0)
|
||||
{
|
||||
args.Append(string.Format(" -r {0}", Options.FPS));
|
||||
}
|
||||
args.Append(string.Format(" -c:v libx264 -crf 23 -preset medium -pix_fmt yuv420p -y \"{0}\"", Options.OutputPath));
|
||||
|
||||
Run(Options.CLIPath, args.ToString());
|
||||
}
|
||||
|
||||
public void ListDevices()
|
||||
{
|
||||
SendCommand("-list_devices true -f dshow -i dummy");
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
CLI.StandardInput.WriteLine("q");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -43,7 +43,7 @@ public class FFmpegCache : ImageCache
|
|||
|
||||
private VideoFileWriter ffmpegWriter;
|
||||
|
||||
public FFmpegCache(FFmpegOptions options)
|
||||
public FFmpegCache(AVIOptions options)
|
||||
{
|
||||
Options = options;
|
||||
Helpers.CreateDirectoryIfNotExist(Options.OutputPath);
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ScreenCaptureLib
|
||||
{
|
||||
public class FFmpegOptions : ScreencastOptions
|
||||
{
|
||||
public int BitRate { get; set; }
|
||||
}
|
||||
}
|
|
@ -37,7 +37,7 @@ namespace ScreenCaptureLib
|
|||
{
|
||||
public partial class FFmpegOptionsForm : Form
|
||||
{
|
||||
public FFmpegOptionsForm(FFmpegOptions options)
|
||||
public FFmpegOptionsForm(AVIOptions options)
|
||||
{
|
||||
InitializeComponent();
|
||||
this.Text = string.Format("{0} - FFmpeg Options", Application.ProductName);
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace ScreenCaptureLib
|
|||
public abstract class ImageCache : IDisposable
|
||||
{
|
||||
public bool IsWorking { get; protected set; }
|
||||
public ScreencastOptions Options { get; set; }
|
||||
public AVIOptions Options { get; set; }
|
||||
|
||||
protected Task task;
|
||||
protected BlockingCollection<Image> imageQueue;
|
||||
|
|
|
@ -88,7 +88,7 @@ private set
|
|||
|
||||
public ScreenRecordOutput OutputType { get; private set; }
|
||||
|
||||
public ScreencastOptions Options { get; set; }
|
||||
public AVIOptions Options { get; set; }
|
||||
|
||||
public delegate void ProgressEventHandler(int progress);
|
||||
|
||||
|
@ -98,6 +98,7 @@ private set
|
|||
private float durationSeconds;
|
||||
private Rectangle captureRectangle;
|
||||
private ImageCache imgCache;
|
||||
private FFmpegCLIHelper ffMpegCli;
|
||||
private bool stopRequest;
|
||||
|
||||
public ScreenRecorder(int fps, float durationSeconds, Rectangle captureRectangle, string cachePath, ScreenRecordOutput outputType, AVICOMPRESSOPTIONS compressOptions)
|
||||
|
@ -113,27 +114,24 @@ public ScreenRecorder(int fps, float durationSeconds, Rectangle captureRectangle
|
|||
CachePath = cachePath;
|
||||
OutputType = outputType;
|
||||
|
||||
Options = new ScreencastOptions()
|
||||
Options = new AVIOptions()
|
||||
{
|
||||
FPS = FPS,
|
||||
OutputPath = CachePath,
|
||||
Size = CaptureRectangle.Size
|
||||
Size = CaptureRectangle.Size,
|
||||
CompressOptions = compressOptions
|
||||
};
|
||||
|
||||
switch (OutputType)
|
||||
{
|
||||
case ScreenRecordOutput.AVI:
|
||||
AVIOptions aviOptions = Options as AVIOptions;
|
||||
aviOptions.CompressOptions = compressOptions;
|
||||
imgCache = new AVICache(aviOptions);
|
||||
imgCache = new AVICache(Options);
|
||||
break;
|
||||
case ScreenRecordOutput.FFmpegNet:
|
||||
FFmpegOptions ffMpegOptions = Options as FFmpegOptions;
|
||||
ffMpegOptions.BitRate = 1000;
|
||||
imgCache = new FFmpegCache(ffMpegOptions);
|
||||
imgCache = new FFmpegCache(Options);
|
||||
break;
|
||||
case ScreenRecordOutput.GIF:
|
||||
imgCache = new HardDiskCache(Options as AVIOptions);
|
||||
imgCache = new HardDiskCache(Options);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -151,6 +149,28 @@ public void StartRecording()
|
|||
IsRecording = true;
|
||||
stopRequest = false;
|
||||
|
||||
if (OutputType == ScreenRecordOutput.FFmpegCLI)
|
||||
{
|
||||
RecordUsingFFmpegCLI();
|
||||
}
|
||||
else
|
||||
{
|
||||
RecordUsingCache();
|
||||
}
|
||||
}
|
||||
|
||||
IsRecording = false;
|
||||
}
|
||||
|
||||
private void RecordUsingFFmpegCLI()
|
||||
{
|
||||
ffMpegCli = new FFmpegCLIHelper(Options);
|
||||
ffMpegCli.Record();
|
||||
ffMpegCli.ListDevices();
|
||||
}
|
||||
|
||||
private void RecordUsingCache()
|
||||
{
|
||||
try
|
||||
{
|
||||
for (int i = 0; !stopRequest && (frameCount == 0 || i < frameCount); i++)
|
||||
|
@ -183,12 +203,14 @@ public void StartRecording()
|
|||
}
|
||||
}
|
||||
|
||||
IsRecording = false;
|
||||
}
|
||||
|
||||
public void StopRecording()
|
||||
{
|
||||
stopRequest = true;
|
||||
|
||||
if (ffMpegCli != null)
|
||||
{
|
||||
ffMpegCli.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveAsGIF(string path, GIFQuality quality)
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ScreenCaptureLib
|
||||
{
|
||||
public class ScreencastOptions
|
||||
{
|
||||
public string OutputPath;
|
||||
public int FPS;
|
||||
public Size Size;
|
||||
}
|
||||
}
|
|
@ -145,6 +145,10 @@ await TaskEx.Run(() =>
|
|||
{
|
||||
path = Path.Combine(TaskSettings.CaptureFolder, TaskHelpers.GetFilename(TaskSettings, "avi"));
|
||||
}
|
||||
else if (TaskSettings.CaptureSettings.ScreenRecordOutput == ScreenRecordOutput.FFmpegCLI)
|
||||
{
|
||||
path = Path.Combine(TaskSettings.CaptureFolder, TaskHelpers.GetFilename(TaskSettings, "mp4"));
|
||||
}
|
||||
else
|
||||
{
|
||||
path = Program.ScreenRecorderCacheFilePath;
|
||||
|
|
|
@ -279,7 +279,7 @@ public class TaskSettingsCapture
|
|||
|
||||
public ScreenRecordOutput ScreenRecordOutput = ScreenRecordOutput.GIF;
|
||||
public AVICOMPRESSOPTIONS ScreenRecordCompressOptions = new AVICOMPRESSOPTIONS();
|
||||
public FFmpegOptions FFmpegOptions = new FFmpegOptions();
|
||||
public AVIOptions FFmpegOptions = new AVIOptions();
|
||||
public int ScreenRecordFPS = 5;
|
||||
public bool ScreenRecordFixedDuration = true;
|
||||
public float ScreenRecordDuration = 3f;
|
||||
|
|
Loading…
Reference in a new issue