diff --git a/FFMpegCore/FFMPEG/FFBase.cs b/FFMpegCore/FFMPEG/FFBase.cs
deleted file mode 100644
index 554f36d..0000000
--- a/FFMpegCore/FFMPEG/FFBase.cs
+++ /dev/null
@@ -1,103 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.Linq;
-using System.Threading.Tasks;
-using RunProcessAsTask;
-
-namespace FFMpegCore.FFMPEG
-{
- public abstract class FFBase : IDisposable
- {
- protected Process Process;
-
- protected FFBase()
- {
- }
-
- ///
- /// Is 'true' when an exception is thrown during process kill (for paranoia level users).
- ///
- public bool IsKillFaulty { get; private set; }
-
- ///
- /// Returns true if the associated process is still alive/running.
- ///
- public bool IsWorking
- {
- get
- {
- bool processHasExited;
-
- try
- {
- processHasExited = Process.HasExited;
- }
- catch
- {
- processHasExited = true;
- }
-
- return !processHasExited && Process.GetProcesses().Any(x => x.Id == Process.Id);
- }
- }
-
- public void Dispose()
- {
- Process?.Dispose();
- }
-
- protected void CreateProcess(string args, string processPath, bool rStandardInput = false,
- bool rStandardOutput = false, bool rStandardError = false)
- {
- if (IsWorking)
- throw new InvalidOperationException(
- "The current FFMpeg process is busy with another operation. Create a new object for parallel executions.");
-
- Process = new Process();
- IsKillFaulty = false;
- Process.StartInfo.FileName = processPath;
- Process.StartInfo.Arguments = args;
- Process.StartInfo.UseShellExecute = false;
- Process.StartInfo.CreateNoWindow = true;
-
- Process.StartInfo.RedirectStandardInput = rStandardInput;
- Process.StartInfo.RedirectStandardOutput = rStandardOutput;
- Process.StartInfo.RedirectStandardError = rStandardError;
- }
-
- public void Kill()
- {
- try
- {
- if (IsWorking)
- Process.Kill();
- }
- catch
- {
- IsKillFaulty = true;
- }
- }
- protected async Task RunProcessAsync(string filePath, string arguments)
- {
- var result = await ProcessEx.RunAsync(filePath, arguments);
- return string.Join("", result.StandardOutput);
- }
- }
-
- public static class ProcessHelpers
- {
- public static void RunProcess(string filePath, string arguments)
- {
-
- }
- public static async Task RunProcessAsync(string fileName, string arguments)
- {
- var startInfo = new ProcessStartInfo(fileName, arguments);
- startInfo.RedirectStandardOutput = true;
- startInfo.RedirectStandardError = true;
-
- var result = await ProcessEx.RunAsync(startInfo);
- return string.Join("", result.StandardOutput);
- }
- }
-}
\ No newline at end of file
diff --git a/FFMpegCore/FFMPEG/FFMpeg.cs b/FFMpegCore/FFMPEG/FFMpeg.cs
index b5b49db..a44a4e7 100644
--- a/FFMpegCore/FFMPEG/FFMpeg.cs
+++ b/FFMpegCore/FFMPEG/FFMpeg.cs
@@ -13,12 +13,13 @@
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
+using Instances;
namespace FFMpegCore.FFMPEG
{
public delegate void ConversionHandler(double percentage);
- public class FFMpeg : FFBase
+ public class FFMpeg
{
IArgumentBuilder ArgumentBuilder { get; set; }
@@ -457,6 +458,11 @@ public VideoInfo Convert(ArgumentContainer arguments)
return new VideoInfo(output);
}
+ ///
+ /// Returns true if the associated process is still alive/running.
+ ///
+ public bool IsWorking => _instance.Started;
+
///
/// Stops any current job that FFMpeg is running.
///
@@ -464,53 +470,31 @@ public void Stop()
{
if (IsWorking)
{
- Process.StandardInput.Write('q');
+ _instance.SendInput("q").Wait();
}
}
#region Private Members & Methods
- private string _ffmpegPath;
+ private readonly string _ffmpegPath;
private TimeSpan _totalTime;
private volatile StringBuilder _errorOutput = new StringBuilder();
private bool RunProcess(ArgumentContainer container, FileInfo output)
{
- var successState = true;
+ _instance?.Dispose();
+ var arguments = ArgumentBuilder.BuildArguments(container);
+ _instance = new Instance(_ffmpegPath, arguments);
+ _instance.DataReceived += OutputData;
+ var exitCode = _instance.BlockUntilFinished();
- CreateProcess(ArgumentBuilder.BuildArguments(container), _ffmpegPath, true, rStandardError: true);
-
- try
+ if (!File.Exists(output.FullName) || new FileInfo(output.FullName).Length == 0)
{
- Process.Start();
- Process.ErrorDataReceived += OutputData;
- Process.BeginErrorReadLine();
- Process.WaitForExit();
- }
- catch (Exception)
- {
- successState = false;
- }
- finally
- {
- Process.Close();
-
- if (File.Exists(output.FullName))
- {
- using var file = File.Open(output.FullName, FileMode.Open);
- if (file.Length == 0)
- {
- throw new FFMpegException(FFMpegExceptionType.Process, _errorOutput);
- }
- }
- else
- {
- throw new FFMpegException(FFMpegExceptionType.Process, _errorOutput);
- }
+ throw new FFMpegException(FFMpegExceptionType.Process, _errorOutput);
}
- return successState;
+ return exitCode == 0;
}
private void Cleanup(IEnumerable pathList)
@@ -524,23 +508,28 @@ private void Cleanup(IEnumerable pathList)
}
}
- private static Regex _progressRegex = new Regex(@"\w\w:\w\w:\w\w", RegexOptions.Compiled);
- private void OutputData(object sender, DataReceivedEventArgs e)
- {
- if (e.Data == null)
- return;
+ private static readonly Regex ProgressRegex = new Regex(@"\w\w:\w\w:\w\w", RegexOptions.Compiled);
+ private Instance _instance;
- _errorOutput.AppendLine(e.Data);
+ private void OutputData(object sender, (DataType Type, string Data) msg)
+ {
+ var (type, data) = msg;
+
+ if (data == null) return;
+ if (type == DataType.Error)
+ {
+ _errorOutput.AppendLine(data);
+ return;
+ }
+
#if DEBUG
- Trace.WriteLine(e.Data);
+ Trace.WriteLine(data);
#endif
- if (OnProgress == null || !IsWorking) return;
-
-
- if (!e.Data.Contains("frame")) return;
+ if (OnProgress == null) return;
+ if (!data.Contains("frame")) return;
- var match = _progressRegex.Match(e.Data);
+ var match = ProgressRegex.Match(data);
if (!match.Success) return;
var processed = TimeSpan.Parse(match.Value, CultureInfo.InvariantCulture);
diff --git a/FFMpegCore/FFMPEG/FFMpegOptions.cs b/FFMpegCore/FFMPEG/FFMpegOptions.cs
index 7555620..23f7559 100644
--- a/FFMpegCore/FFMPEG/FFMpegOptions.cs
+++ b/FFMpegCore/FFMPEG/FFMpegOptions.cs
@@ -3,6 +3,7 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
+using Instances;
namespace FFMpegCore.FFMPEG
{
@@ -44,13 +45,7 @@ private static string FFBinary(string name)
ffName = Path.Combine(target, ffName);
}
- var path = Path.Combine(Options.RootDirectory, ffName);
-
- if (!File.Exists(path))
- throw new FFMpegException(FFMpegExceptionType.Dependency,
- $"{name} cannot be found @ {path}");
-
- return path;
+ return Path.Combine(Options.RootDirectory, ffName);
}
}
}
diff --git a/FFMpegCore/FFMPEG/FFProbe.cs b/FFMpegCore/FFMPEG/FFProbe.cs
index 0e084cd..5002817 100644
--- a/FFMpegCore/FFMPEG/FFProbe.cs
+++ b/FFMpegCore/FFMPEG/FFProbe.cs
@@ -4,17 +4,18 @@
using System;
using System.Globalization;
using System.Threading.Tasks;
+using Instances;
namespace FFMpegCore.FFMPEG
{
- public sealed class FFProbe : FFBase
+ public sealed class FFProbe
{
static readonly double BITS_TO_MB = 1024 * 1024 * 8;
+ private readonly string _ffprobePath;
public FFProbe(): base()
{
FFProbeHelper.RootExceptionCheck(FFMpegOptions.Options.RootDirectory);
-
_ffprobePath = FFMpegOptions.Options.FFProbeBinary;
}
@@ -44,7 +45,9 @@ public Task ParseVideoInfoAsync(string source)
/// A video info object containing all details necessary.
public VideoInfo ParseVideoInfo(VideoInfo info)
{
- var output = RunProcess(BuildFFProbeArguments(info));
+ var instance = new Instance(_ffprobePath, BuildFFProbeArguments(info));
+ instance.BlockUntilFinished();
+ var output = string.Join("", instance.OutputData);
return ParseVideoInfoInternal(info, output);
}
///
@@ -54,7 +57,9 @@ public VideoInfo ParseVideoInfo(VideoInfo info)
/// A video info object containing all details necessary.
public async Task ParseVideoInfoAsync(VideoInfo info)
{
- var output = await RunProcessAsync(_ffprobePath, BuildFFProbeArguments(info));
+ var instance = new Instance(_ffprobePath, BuildFFProbeArguments(info));
+ await instance.FinishedRunning();
+ var output = string.Join("", instance.OutputData);
return ParseVideoInfoInternal(info, output);
}
@@ -115,35 +120,5 @@ private VideoInfo ParseVideoInfoInternal(VideoInfo info, string probeOutput)
return info;
}
-
- #region Private Members & Methods
-
- private readonly string _ffprobePath;
-
- private string RunProcess(string args)
- {
- CreateProcess(args, _ffprobePath, rStandardOutput: true);
-
- string output;
-
- try
- {
- Process.Start();
- output = Process.StandardOutput.ReadToEnd();
- }
- catch (Exception)
- {
- output = "";
- }
- finally
- {
- Process.WaitForExit();
- Process.Close();
- }
-
- return output;
- }
-
- #endregion
}
}
diff --git a/FFMpegCore/FFMpegCore.csproj b/FFMpegCore/FFMpegCore.csproj
index 3fc56cf..b92a3da 100644
--- a/FFMpegCore/FFMpegCore.csproj
+++ b/FFMpegCore/FFMpegCore.csproj
@@ -129,7 +129,7 @@
-
+