C#问题:如何将控制台输出读取为字符串?

3
我希望能从我的应用程序中启动FFmpeg,并检索FFmpeg产生的所有控制台输出。这个问题似乎很明显,我遵循了很多论坛帖子/文章(例如这个),但是我有问题,尽管我遵循了其中包含的所有信息,但好像陷入了死胡同。
应该包含来自FFmpeg的输出的字符串总是为空。我试图找出问题所在,所以我制作了一个简单的C#控制台应用程序,仅列出传递给FFmpeg的所有执行参数,只是为了检查问题是否由FFmpeg本身引起。在这种情况下,一切都按预期进行。
我还预览了我的应用程序的控制台窗口。当我启动FFmpeg时,我在控制台上看到所有输出,但是应该接收该输出进行进一步处理的函数报告字符串为空。当启动我的参数列表应用程序时,我唯一看到的是从获取输出的函数中得到的预期报告。
所以我的问题是要做些什么才能像最初打算的那样获得FFmpeg的输出。
提前致谢 MTH

1
你是否同时重定向了标准输出和标准错误? - Felice Pollano
不,但那是个问题。感谢您的帮助! - MoreThanChaos
2个回答

3
这个可能有点冒险,您尝试过将StandardError重定向吗?

那正是问题所在,但仍然没有任何错误行为让我考虑重定向标准错误。谢谢! - MoreThanChaos

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);
            }
        } 
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接