对于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版本上使用,只有少量预处理指令。