2010-12-20 67 views
3

我一直在试图解决一个问题几天。我是多线程初学者。我的目标是使用ffmpeg.exe同时运行多个视频编码任务,并使用服务器的所有功能。使用任务并行库(C#.NET 4.0)与外部exe(ffmpeg)没有冲突

我有一个C#包装会启动ffmpeg.exe过程和无螺纹(或ffmpeg的内螺纹只(不适用于FLV编码)),它看起来像这样工作的:

using (Process process = new Process()) 
{ 
    process.StartInfo.FileName = encoderPath + "ffmpeg.exe"; 

    process.StartInfo.UseShellExecute = false; 
    process.StartInfo.RedirectStandardOutput = true; 
    process.StartInfo.RedirectStandardError = true; 
    process.StartInfo.CreateNoWindow = false; 

    string arguments = "-y -i " + filenameInput + " -f " + 
     GetVideoFormatName(format) + " -vcodec " + GetVideoCodecName(codec); 

    // (most argument setup has been omitted for brevity) 
    arguments += " " + filenameOutput + " "; 

    process.StartInfo.Arguments = arguments; 
    process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
    process.Start(); 

    bool succes = LireSortie(process); 
    process.WaitForExit(); 
    process.Close(); 
    return succes; 
} 

下面的代码调用包装器。每个Encode方法的第二个参数是用于内部ffmpeg线程的线程数。当我禁用它时,它不起作用。

var fm = new FFMpegWrapper(); 

fm.FilenameInput = "test.mp4"; 
//VideoInfo videoinfo = fm.GetVideoInfo(); 
Task[] tasks = { 
    Task.Factory.StartNew(
     new Action(()=>{ fm.Encodeto200p("test200p.mp4", 4); })), 
    Task.Factory.StartNew(
     new Action(()=>{ fm.EncodetoFlash200p("test200p.flv"); })), 
    // ... (calls to other Encode methods ommitted) ... 
    Task.Factory.StartNew(
     new Action(()=>{ fm.Encodeto404p("test404p.mp4", 4); })), 
    Task.Factory.StartNew(
     new Action(()=>{ fm.EncodetoFlash404p("test404p.flv"); })), 
    Task.Factory.StartNew(
     new Action(()=>{ fm.Encodeto720p("test720p.mp4", 4); })) 
}; 

Task.WaitAll(tasks, 5000); 

你可能想知道为什么我把5000超时WaitAll()。这是因为调用线程无限期地等待,因为TPL没有检测到任务结束。 ffmpeg.exe在编码中间处理“停止”,并继续以0%的CPU运行。

我认为TPL和Process是冲突的。当我通过TPL获得每项任务的状态时,它始终保持“正在运行”状态。我想用TPL(或其他一些机制)捕捉ffmpeg进程的真实事件,因为我想阻止应用程序崩溃并想要管理成功和失败。

+0

ffmpeg进程是否结束?即如果您在没有任务的情况下运行相同的代码,它会退出吗? – 2011-08-27 14:03:40

+0

所以这个问题与TPL无关。问题是ffmpeg没有退出。正确? – usr 2012-05-28 23:08:59

回答

0

我怀疑问题出在TPL上还是用任何自制的机制来检测过程是否结束。我怀疑真正的原因是等待不是无限期的,而是由于对特定资源的压力引起的颠簸的经典案例。

鉴于您对发生的事情的描述,以及CPU看起来处于低水平,您的压力可能在IO或内存上。我建议至少使用性能计数器对应用程序进行性能分析(并使用任务管理器作为表面级别的快速查看)以了解发生了什么。

正如一位评论者所建议的,消除任务并确定一个,两个或多个串行调用是否至少编码工作是有意义的。这可能是一个特定的调用将所有东西都保存起来(例如编码错误),而不是资源问题。