38

我像这样运行ffmpeg:

System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo = new System.Diagnostics.ProcessStartInfo(ffmpegPath, myParams);
p.Start();
p.WaitForExit();

...但问题是带有ffmpeg的控制台弹出并立即消失,所以我无法得到任何反馈。我什至不知道该过程是否正确运行。

那么我该怎么做:

  • 告诉控制台保持打开状态

  • 在 C# 中检索控制台显示的内容

4

4 回答 4

56

What you need to do is capture the Standard Output stream:

p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
// instead of p.WaitForExit(), do
string q = "";
while ( ! p.HasExited ) {
    q += p.StandardOutput.ReadToEnd();
}

You may also need to do something similar with StandardError. You can then do what you wish with q.

It is a bit finicky, as I discovered in one of my questions

As Jon Skeet has pointed out, it is not smart performance-wise to use string concatenation like this; you should instead use a StringBuilder:

p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
// instead of p.WaitForExit(), do
StringBuilder q = new StringBuilder();
while ( ! p.HasExited ) {
    q.Append(p.StandardOutput.ReadToEnd());
}
string r = q.ToString();
于 2009-09-07T18:50:05.200 回答
22

卢卡斯的回答有一个竞争条件:如果进程很快完成,即使有一些输出,也会留下(或从未进入)while循环,那就是你可能会错过一些数据。为防止这种情况,ReadToEnd应在进程退出后进行另一次。

WaitForExit(请注意,与我的答案的旧版本相比,一旦标志为真,我就不再需要process.HasExited,所以这归结为:)

using (var process = Process.Start(startInfo))
{
    var standardOutput = new StringBuilder();

    // read chunk-wise while process is running.
    while (!process.HasExited)
    {
        standardOutput.Append(process.StandardOutput.ReadToEnd());
    }

    // make sure not to miss out on any remaindings.
    standardOutput.Append(process.StandardOutput.ReadToEnd());

    // ...
}
于 2013-09-04T14:19:22.880 回答
4

对于与 ffmpeg 直接相关的更具体的答案,将“-report”命令传递给 ffmpeg 将使其将日志转储到当前目录中,其中包含进程显示中所说的内容。

'-报告'

将完整的命令行和控制台输出转储到当前目录中名为 program-YYYYMMDD-HHMMSS.log 的文件中。此文件可用于错误报告。它还暗示 -loglevel 详细。

注意:将环境变量 FFREPORT 设置为任何值都具有相同的效果。

来自FFMpeg 文档

于 2012-05-07T19:23:51.137 回答
4

我知道这个问题很老,但无论如何我都会添加它。

如果您只想显示命令行进程的输出,并且从控制台窗口生成该进程,则只需重定向标准输入(是的,我知道这听起来不对,但它有效)。

所以:

System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo = new System.Diagnostics.ProcessStartInfo(ffmpegPath, myParams);
p.UseShellExecute = false;
p.RedirectStandardInput = true;
p.Start();
p.WaitForExit();

会做得很好。

于 2010-07-23T00:38:01.347 回答