A solution that is viable for both Linux and Windows is to just get used to using console ffmpeg in your code. I stack up threads, write a simple thread controller class, then you can easily make use of what ever functionality of ffmpeg you want to use.
As an example, this contains sections use ffmpeg to create a thumbnail from a time that I specify.
In the thread controller you have something like
List<ThrdFfmpeg> threads = new List<ThrdFfmpeg>();
Which is the list of threads that you are running, I make use of a timer to Pole these threads, you can also set up an event if Pole'ing is not suitable for your application.
In this case thw class Thrdffmpeg contains,
public class ThrdFfmpeg
{
public FfmpegStuff ffm { get; set; }
public Thread thrd { get; set; }
}
FFmpegStuff contains the various ffmpeg functionality, thrd is obviously the thread.
A property in FfmpegStuff is the class FilesToProcess, which is used to pass information to the called process, and receive information once the thread has stopped.
public class FileToProcess
{
public int videoID { get; set; }
public string fname { get; set; }
public int durationSeconds { get; set; }
public List<string> imgFiles { get; set; }
}
VideoID (I use a database) tells the threaded process which video to use taken from the database.
fname is used in other parts of my functions that use FilesToProcess, but not used here.
durationSeconds - is filled in by the threads that just collect video duration.
imgFiles is used to return any thumbnails that were created.
I do not want to get bogged down in my code when the purpose of this is to encourage the use of ffmpeg in easily controlled threads.
Now we have our pieces we can add to our threads list, so in our controller we do something like,
AddThread()
{
ThrdFfmpeg thrd;
FileToProcess ftp;
foreach(FileToProcess ff in `dbhelper.GetFileNames(txtCategory.Text))`
{
//make a thread for each
ftp = new FileToProcess();
ftp = ff;
ftp.imgFiles = new List<string>();
thrd = new ThrdFfmpeg();
thrd.ffm = new FfmpegStuff();
thrd.ffm.filetoprocess = ftp;
thrd.thrd = new `System.Threading.Thread(thrd.ffm.CollectVideoLength);`
threads.Add(thrd);
}
if(timerNotStarted)
StartThreadTimer();
}
Now Pole'ing our threads becomes a simple task,
private void timerThreads_Tick(object sender, EventArgs e)
{
int runningCount = 0;
int finishedThreads = 0;
foreach(ThrdFfmpeg thrd in threads)
{
switch (thrd.thrd.ThreadState)
{
case System.Threading.ThreadState.Running:
++runningCount;
//Note that you can still view data progress here,
//but remember that you must use your safety checks
//here more than anywhere else in your code, make sure the data
//is readable and of the right sort, before you read it.
break;
case System.Threading.ThreadState.StopRequested:
break;
case System.Threading.ThreadState.SuspendRequested:
break;
case System.Threading.ThreadState.Background:
break;
case System.Threading.ThreadState.Unstarted:
//Any threads that have been added but not yet started, start now
thrd.thrd.Start();
++runningCount;
break;
case System.Threading.ThreadState.Stopped:
++finishedThreads;
//You can now safely read the results, in this case the
//data contained in FilesToProcess
//Such as
ThumbnailsReadyEvent( thrd.ffm );
break;
case System.Threading.ThreadState.WaitSleepJoin:
break;
case System.Threading.ThreadState.Suspended:
break;
case System.Threading.ThreadState.AbortRequested:
break;
case System.Threading.ThreadState.Aborted:
break;
default:
break;
}
}
if(flash)
{//just a simple indicator so that I can see
//that at least one thread is still running
lbThreadStatus.BackColor = Color.White;
flash = false;
}
else
{
lbThreadStatus.BackColor = this.BackColor;
flash = true;
}
if(finishedThreads >= threads.Count())
{
StopThreadTimer();
ShowSample();
MakeJoinedThumb();
}
}
Putting your own events onto into the controller class works well, but in video work, when my own code is not actually doing any of the video file processing, poling then invoking an event in the controlling class works just as well.
Using this method I have slowly built up just about every video and stills function I think I will ever use, all contained in the one class, and that class as a text file is useable on the Lunux and Windows version, with just a small number of pre-process directives.