对于Linux和Windows都可行的解决方案是习惯于在代码中使用控制台ffmpeg。我堆叠线程,编写一个简单的线程控制器类,然后您可以轻松利用想要使用的ffmpeg的功能。
作为示例,其中包含使用ffmpeg的部分,从我指定的时间开始创建缩略图。
在线程控制器中,您有类似
List<ThrdFfmpeg> threads = new List<ThrdFfmpeg>();
这是您正在运行的线程的列表,我利用计时器来对这些线程进行极点操作,如果极点操作不适合您的应用程序,您还可以设置一个事件。在这种情况下,Thrdffmpeg类包含
public class ThrdFfmpeg
{
    public FfmpegStuff ffm { get; set; }
    public Thread thrd { get; set; }
}
FFmpegStuff包含各种ffmpeg功能,显然thrd是线程。
FfmpegStuff中的一个属性是FilesToProcess类,该类用于将信息传递给被调用的进程,并在线程停止后接收信息。
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(我使用数据库)告诉线程处理要使用的视频是从数据库中获取的。fname在使用FilesToProcess的函数的其他部分中使用,但此处未使用。durationSeconds-由仅收集视频持续时间的线程填充。imgFiles用于返回创建的所有缩略图。
当这样做的目的是鼓励在易于控制的线程中使用ffmpeg时,我不想陷入僵局。
现在我们有了我们可以添加到线程列表中的片段,因此在我们的控制器中,我们做了类似的事情,
        AddThread()
        {
        ThrdFfmpeg thrd;
        FileToProcess ftp;
        foreach(FileToProcess ff in  `dbhelper.GetFileNames(txtCategory.Text))`
        {
            
            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();
        }
现在,给我们的线程穿针引线变得很简单, 
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;
 
    
    
    
                    break;
                case System.Threading.ThreadState.StopRequested:
                    break;
                case System.Threading.ThreadState.SuspendRequested:
                    break;
                case System.Threading.ThreadState.Background:
                    break;
                case System.Threading.ThreadState.Unstarted:
                    thrd.thrd.Start();
                    ++runningCount;
                    break;
                case System.Threading.ThreadState.Stopped:
                    ++finishedThreads;
   
   
                    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)
        {
         
            lbThreadStatus.BackColor = Color.White;
            flash = false;
        }
        else
        {
            lbThreadStatus.BackColor = this.BackColor;
            flash = true;
        }
        if(finishedThreads >= threads.Count())
        {
            StopThreadTimer();
            ShowSample();
            MakeJoinedThumb();
        }
    }
将您自己的事件放到控制器类中效果很好,但是在视频工作中,当我自己的代码实际上未执行任何视频文件处理时,在控制类中轮询然后调用事件也同样有效。
使用这种方法,我已经慢慢建立了几乎所有我想使用的视频和静止图像功能,所有这些功能都包含在一个类中,并且该类作为文本文件可在Lunux和Windows版本上使用,只有少量预处理指令。