Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added constructors to allow multiple running instances of FFmpeg #50

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -215,3 +215,4 @@ pip-log.txt
.mr.developer.cfg

TestVideo/
/MediaToolkit src/packages
42 changes: 31 additions & 11 deletions MediaToolkit src/MediaToolkit/Engine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,17 @@ public Engine()

public Engine(string ffMpegPath) : base(ffMpegPath)
{


}

public Engine(bool enableMultipleRunningProcesses) : base(enableMultipleRunningProcesses)
{

}

public Engine(string ffMpegPath, bool enableMultipleRunningProcesses) : base(ffMpegPath, enableMultipleRunningProcesses)
{

}

/// -------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -130,12 +140,18 @@ private void FFmpegEngine(EngineParameters engineParameters)

try
{
this.Mutex.WaitOne();
if (Mutex != null)
{
this.Mutex.WaitOne();
}
this.StartFFmpegProcess(engineParameters);
}
finally
{
this.Mutex.ReleaseMutex();
if (Mutex != null)
{
this.Mutex.ReleaseMutex();
}
}
}

Expand Down Expand Up @@ -225,15 +241,15 @@ private void StartFFmpegProcess(EngineParameters engineParameters)
? this.GenerateStartInfo(engineParameters.CustomArguments)
: this.GenerateStartInfo(engineParameters);

using (this.FFmpegProcess = Process.Start(processStartInfo))
using (var FFmpegProcess = Process.Start(processStartInfo))
{
Exception caughtException = null;
if (this.FFmpegProcess == null)
if (FFmpegProcess == null)
{
throw new InvalidOperationException(Resources.Exceptions_FFmpeg_Process_Not_Running);
}

this.FFmpegProcess.ErrorDataReceived += (sender, received) =>
DataReceivedEventHandler errorDataRecievedFunction = (sender, received) =>
{
if (received.Data == null) return;
#if (DebugToConsole)
Expand Down Expand Up @@ -281,7 +297,7 @@ private void StartFFmpegProcess(EngineParameters engineParameters)

try
{
this.FFmpegProcess.Kill();
FFmpegProcess.Kill();
}
catch (InvalidOperationException)
{
Expand All @@ -291,15 +307,19 @@ private void StartFFmpegProcess(EngineParameters engineParameters)
}
};

this.FFmpegProcess.BeginErrorReadLine();
this.FFmpegProcess.WaitForExit();
FFmpegProcess.ErrorDataReceived += errorDataRecievedFunction;

FFmpegProcess.BeginErrorReadLine();
FFmpegProcess.WaitForExit();

if ((this.FFmpegProcess.ExitCode != 0 && this.FFmpegProcess.ExitCode != 1) || caughtException != null)
if ((FFmpegProcess.ExitCode != 0 && FFmpegProcess.ExitCode != 1) || caughtException != null)
{
throw new Exception(
this.FFmpegProcess.ExitCode + ": " + receivedMessagesLog[1] + receivedMessagesLog[0],
FFmpegProcess.ExitCode + ": " + receivedMessagesLog[1] + receivedMessagesLog[0],
caughtException);
}

FFmpegProcess.ErrorDataReceived -= errorDataRecievedFunction;
}
}
}
Expand Down
64 changes: 50 additions & 14 deletions MediaToolkit src/MediaToolkit/EngineBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,39 @@ public class EngineBase : IDisposable
/// <summary> Used for locking the FFmpeg process to one thread. </summary>
private const string LockName = "MediaToolkit.Engine.LockName";

private const string DefaultFFmpegFilePath = @"/MediaToolkit/ffmpeg.exe";
/// <summary>
/// Path to the ffmpeg executable
/// </summary>
private string DefaultFFmpegFilePath => Path.Combine(Path.GetTempPath(), "MediaToolkit/" + Guid.NewGuid().ToString() + "/ffmpeg.exe");

private bool DeleteExeOnExit;

/// <summary> Full pathname of the FFmpeg file. </summary>
protected readonly string FFmpegFilePath;

/// <summary> The Mutex. </summary>
/// <remarks>Null if concurrently running FFmpeg instances are allowed.</remarks>
protected readonly Mutex Mutex;

/// <summary> The ffmpeg process. </summary>
protected Process FFmpegProcess;
private object _fileExistLock = new object();


protected EngineBase()
: this(ConfigurationManager.AppSettings["mediaToolkit.ffmpeg.path"])
protected EngineBase()
: this(ConfigurationManager.AppSettings["mediaToolkit.ffmpeg.path"])
{
}

protected EngineBase(bool enableMultipleRunningProcesses)
: this(ConfigurationManager.AppSettings["mediaToolkit.ffmpeg.path"], enableMultipleRunningProcesses)
{
}

///-------------------------------------------------------------------------------------------------
/// <summary>
/// <para> Initializes FFmpeg.exe; Ensuring that there is a copy</para>
/// <para> in the clients temp folder &amp; isn't in use by another process.</para>
/// </summary>
protected EngineBase(string ffMpegPath) : this(ffMpegPath, false)
{
}

Expand All @@ -40,21 +59,31 @@ protected EngineBase()
/// <para> Initializes FFmpeg.exe; Ensuring that there is a copy</para>
/// <para> in the clients temp folder &amp; isn't in use by another process.</para>
/// </summary>
protected EngineBase(string ffMpegPath)
/// <param name="enableMultipleRunningProcesses">Whether or not to allow multiple instances of FFmpeg to run concurrently.</param>
protected EngineBase(string ffMpegPath, bool enableMultipleRunningProcesses)
{
this.Mutex = new Mutex(false, LockName);
if (!enableMultipleRunningProcesses)
{
this.Mutex = new Mutex(false, LockName);
}

this.isDisposed = false;

if (ffMpegPath.IsNullOrWhiteSpace())
{
ffMpegPath = DefaultFFmpegFilePath;
DeleteExeOnExit = true;
}

this.FFmpegFilePath = ffMpegPath;

this.EnsureDirectoryExists ();
this.EnsureDirectoryExists();
this.EnsureFFmpegFileExists();
this.EnsureFFmpegIsNotUsed ();

if (!enableMultipleRunningProcesses)
{
this.EnsureFFmpegIsNotUsed();
}
}

private void EnsureFFmpegIsNotUsed()
Expand Down Expand Up @@ -89,7 +118,13 @@ private void EnsureFFmpegFileExists()
{
if (!File.Exists(this.FFmpegFilePath))
{
UnpackFFmpegExecutable(this.FFmpegFilePath);
lock (_fileExistLock)
{
if (!File.Exists(this.FFmpegFilePath)) // Check again in case another thread got this far and created the file
{
UnpackFFmpegExecutable(this.FFmpegFilePath);
}
}
}
}

Expand Down Expand Up @@ -133,11 +168,12 @@ private void Dispose(bool disposing)
return;
}

if(FFmpegProcess != null)
// Clean up temporary file
if (DeleteExeOnExit)
{
this.FFmpegProcess.Dispose();
}
this.FFmpegProcess = null;
File.Delete(FFmpegFilePath);
}

this.isDisposed = true;
}
}
Expand Down
36 changes: 36 additions & 0 deletions MediaToolkit src/MediaToolkit/MediaToolkit.nuspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaToolkit</id>
<version>$version$</version>
<title>Media Toolkit</title>
<authors>Aydin</authors>
<owners>Aydin</owners>
<projectUrl>https://github.com/AydinAdn/MediaToolkit</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>MediaToolkit is a .NET library which can convert and process audio and video files.

Functionality:
- Grab thumbnails from videos
- Cut / split videos
- Convert video files into various other video formats.
- Perform video transcoding tasks.
- Set bit rate
- Set frame rate
- Set resolution or size
- Set aspect ratio
- Set duration
- Perform audio transcoding tasks.
- Set audio sample rate
- Convert video to physical formats using FILM, PAL or NTSC tv standards
- DVD
- DV
- DV50
- VCD
- SVCD</description>
<summary>MediaToolkit is a .NET library which can convert and process audio and video files.</summary>
<copyright>Aydin</copyright>
<language>en-GB</language>
<tags>Media Video Audio converter ffmpeg flv mp4 flash h264 hd 720p 1080p dvd</tags>
</metadata>
</package>
Binary file not shown.
28 changes: 0 additions & 28 deletions MediaToolkit src/packages/NUnit.2.6.3/NUnit.2.6.3.nuspec

This file was deleted.

Binary file not shown.
Loading