C#问题读取控制台输出到字符串

时间:2011-04-26 15:39:40

标签: c# .net console ffmpeg

我想从我的应用程序启动ffmpeg并检索ffmpeg生成的所有控制台输出。事情似乎很明显,我跟随了许多论坛帖子/文章,如this one,但我有问题,虽然我遵循其中包含的所有信息,我似乎最终走到了死胡同。

应包含ffmpeg输出的字符串始终为空。我试着看看问题出在哪里,所以我制作了简单的c#控制台应用程序,它只列出了传递给ffmpeg的所有执行参数,只是为了检查问题是否是由ffmpeg本身引起的。在这种情况下,一切都按预期工作。

我也预览了我的应用程序的控制台窗口。当我启动ffmpeg时,我看到控制台中的所有输出但是应该接收该输出以进行进一步处理的函数报告该字符串为空。当我的param-listing应用程序启动时,我唯一看到的是来自函数的预期报告获得输出。

所以我的问题是如何在第一时间获得ffmpeg输出。

提前致谢 MTH

2 个答案:

答案 0 :(得分:3)

这是一个很长的镜头,但您是否尝试过重定向StandardError?

答案 1 :(得分:2)

这是我的ffmpeg包装类的一部分,特别展示了如何从ffmpeg收集输出和错误。

我已将过程放在GetVideoDuration()功能中,这样您就可以在一个地方看到所有内容。

设定:

我的ffmpeg在桌面上,ffPath用于指向它。

namespace ChildTools.Tools
{
    public class FFMpegWrapper
    {
        //path to ffmpeg (I HATE!!! MS special folders)
        string ffPath = System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\ffmpeg.exe";
    //outputLines receives each line of output, only if they are not zero length
        List<string> outputLines = new List<string>();


    //In GetVideoDuration I only want the one line of output and in text form.
    //To get the whole output just remove the filter I use (my search for 'Duration') and either return the List<>
    //Or joint the strings from List<> (you could have used StringBuilder, but I find a List<> handier.

        public string GetVideoDuration(FileInfo fi)
        {
            outputLines.Clear();
    //I only use the information flag in this function
            string strCommand = string.Concat(" -i \"", fi.FullName, "\"");
    //Point ffPath to my ffmpeg
            string ffPath = System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\ffmpeg.exe";

            Process processFfmpeg = new Process();

            processFfmpeg.StartInfo.Arguments = strCommand;
            processFfmpeg.StartInfo.FileName = ffPath;

    //I have to say that I struggled for a while with the order that I setup the process.
    //But this order below I know to work


            processFfmpeg.StartInfo.UseShellExecute = false;
            processFfmpeg.StartInfo.RedirectStandardOutput = true;
            processFfmpeg.StartInfo.RedirectStandardError = true;
            processFfmpeg.StartInfo.CreateNoWindow = true;
            processFfmpeg.ErrorDataReceived += processFfmpeg_OutData;
            processFfmpeg.OutputDataReceived += processFfmpeg_OutData;
            processFfmpeg.EnableRaisingEvents = true;
            processFfmpeg.Start();
            processFfmpeg.BeginOutputReadLine();
            processFfmpeg.BeginErrorReadLine();
            processFfmpeg.WaitForExit();

    //I filter the lines because I only want 'Duration' this time
            string oStr = "";
            foreach (string str in outputLines)
            {
                if (str.Contains("Duration"))
                {
                    oStr = str;
                }
            }
    //return a single string with the duration line

            return oStr;
        }

        private void processFfmpeg_OutData(object sender, DataReceivedEventArgs e)
        {
    //The data we want is in e.Data, you must be careful of null strings
            string strMessage = e.Data;
            if outputLines != null && strMessage != null && strMessage.Length > 0)
            {
                outputLines.Add(string.Concat( strMessage,"\n"));
        //Try a Console output here to see all of the output. Particularly
        //useful when you are examining the packets and working out timeframes
        //Console.WriteLine(strMessage);
            }
        } 
    }
}