从 .NET 程序与 ffmpeg 交互 - 写入输入

发布于 2024-12-04 21:34:57 字数 1283 浏览 1 评论 0原文

参考这个问题,如您所见,我设法运行并从程序。

但是我没有设法向它提交数据,例如,在转换文件时,按 q 立即停止转换并停止程序。
我需要我的应用程序也支持停止该过程,我认为这应该通过将此参数传递给 ffmpeg 应用程序来完成,因为我希望它能够处理所有未收集的资源或它会留下的任何灰尘,如果我只是这样做的话去使用 process.Kill()

这是我尝试过的:

static int lineCount = 0;
static bool flag;
static void process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
  Console.WriteLine("Error ({1:m:s:fff}: {0})", lineCount++,
      DateTime.Now);

  if (e.Data != null && string.Equals(e.Data,"Press [q] to stop, [?] for help")) 
    flag = true;

  if (flag)
  {
    flag = false;
    Console.WriteLine("Stopping ({0:m:s:fff})...", DateTime.Now);
    process.CancelErrorRead();
    process.CancelOutputRead();
    process.StandardInput.WriteLine("q");
  }   

  Console.WriteLine(e.Data);
  Console.WriteLine();
}

但它没有做任何事情,似乎一旦请求转换,我就无法再控制它了,我只能接收它的输出。当然,独立运行它确实允许我进行交互。

我在这里缺少什么,提交输出时是否有不同的技巧,或者之前答案中的代码是错误的,或者我应该选择不同的方法?

请注意,RedirectStandardInput 已打开。

注意:正如您在答案中看到的我的上一个问题,ffmpeg 的交互方式不同,我认为知道答案的人将是(也许我错了)具有 ffmpeg 经验的人。

In reference to this question, as you can see I managed to run and receive data from the program.

However I didn't manage to submit data to it, for instance, while converting a file, pressing q immediately stop conversion and stops the program.
I need my application to support stopping the process as well, and I think this should be done by passing this parameter to the ffmpeg app, since I want it to take care of all uncollected resource or whatever dust it would leave behind if I would just go and use process.Kill()

Here is what I've tried:

static int lineCount = 0;
static bool flag;
static void process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
  Console.WriteLine("Error ({1:m:s:fff}: {0})", lineCount++,
      DateTime.Now);

  if (e.Data != null && string.Equals(e.Data,"Press [q] to stop, [?] for help")) 
    flag = true;

  if (flag)
  {
    flag = false;
    Console.WriteLine("Stopping ({0:m:s:fff})...", DateTime.Now);
    process.CancelErrorRead();
    process.CancelOutputRead();
    process.StandardInput.WriteLine("q");
  }   

  Console.WriteLine(e.Data);
  Console.WriteLine();
}

But it doesn't do anything, seems that once the conversion has been requested, I have no control on it any more, I can only receive output from it. Running it as stand alone does allow me interaction of course.

What am I missing here, is it a different trick in submitting the output or the code in previous answer is wrong, or I should have chosen a different approach?

For your attention, RedirectStandardInput is on.

NOTE: as you can see in the answer of my previous question, ffmpeg interacts differently, I think the one who knows the answer will be (maybe I'm wrong) someone with experience in ffmpeg.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情归归情 2024-12-11 21:34:57

使用 WriteLine('q'); 而不是 Write('q');

:)

我尝试从 cygwin bash shell 运行 ffmpeg,发现我必须在 'q' 之后输入 Enter。所以....

    static void process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
    {
        Console.WriteLine("Error line: {0} ({1:m:s:fff})", lineCount++,
            DateTime.Now);
        Console.WriteLine(e.Data);
        Console.WriteLine();
        if (lineCount == 5)
            process.StandardInput.WriteLine("q");
    }

使用库存c:\Documents and Settings\All Users\Documents\My Music\Sample Music\Beethoven's Symphony No. 9 (Scherzo).wma

  • 无需进程。 StandardInput.WriteLine 它在 stderr 上打印 61 行,在 stdout 上打印 1 行,并创建 1212457 字节的 mp3 文件。
  • 添加退出,它在 stderr 上打印更少的行数,在 stdout 上打印任何内容,并且 mp3 文件要小得多。

请注意,它确实留下了 mp3 文件。

就这样。

编辑

在看到您的评论后说您已经尝试过这个..

我刚刚重新检查了。这种行为很奇怪。

首先,我重试了我的操作,发现在第 5 行发送 "q\n" 到 sterr 会创建一个小得多的文件,尽管在不同的运行中大小略有不同 - 介于 160K 和 220K 之间。

接下来我注释掉了 Console.WriteLine 希望它能让 ffmpeg 退出得更快。相反,ffmpeg 现在根本没有停止,并创建了具有完全相同的字节数(1,212,457 字节)的完整文件。此行为与您的观察结果一致

最后,在 WriteLines 就位后,我在第五行之后将每一行上的 "q\n" 泵送到 stderr 。大惊喜!记录 40 行错误行后,

Unhandled Exception: System.InvalidOperationException: StandardIn has not been redirected.
   at System.Diagnostics.Process.get_StandardInput()
   at StandAlone.Program.process_ErrorDataReceived(Object sender, DataReceivedEventArgs e) in C:\[..]\StandAlone\Program.cs:line 171
   at System.Diagnostics.Process.ErrorReadNotifyUser(String data)

未重定向?并且您在我向其输入发送35 行后告诉我?

有些事情不太对劲……闻起来像虫子。

由提问者更新:

此处 更新 Windows 版本(静态)解决了我的问题,我使用了一些版本显然是一个非官方网站。

Use WriteLine('q'); instead of Write('q');.

:)

I tried to run ffmpeg from cygwin bash shell and saw that I had to type an enter after 'q'. So....

    static void process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
    {
        Console.WriteLine("Error line: {0} ({1:m:s:fff})", lineCount++,
            DateTime.Now);
        Console.WriteLine(e.Data);
        Console.WriteLine();
        if (lineCount == 5)
            process.StandardInput.WriteLine("q");
    }

With the stock c:\Documents and Settings\All Users\Documents\My Music\Sample Music\Beethoven's Symphony No. 9 (Scherzo).wma

  • without the process.StandardInput.WriteLine it prints 61 lines on stderr, 1 line on stdout and creates mp3 file of 1212457 bytes.
  • add the quit and it prints less number of lines on stderr, nothing on stdout and a much smaller mp3 file.

Note that it does leave the mp3 file around.

So there.

EDIT

After seeing your comment that you already tried this..

I just rechecked. The behavior is strange.

First I retried what I had and saw that sending "q\n" on the 5th line to sterr creates a much smaller file, though slightly different sizes in different runs -- between 160K and 220K.

Next I commented out Console.WriteLine hoping it will make ffmpeg quit faster. On the contrary, ffmpeg now did not stop at all and created the full file with exact same byte count, 1,212,457 bytes. This behavior is consistent with your observation

Finally, with WriteLines in place, I pumped "q\n" on every line to stderr after the fifth. Big surprise! After logging 40 error lines,

Unhandled Exception: System.InvalidOperationException: StandardIn has not been redirected.
   at System.Diagnostics.Process.get_StandardInput()
   at StandAlone.Program.process_ErrorDataReceived(Object sender, DataReceivedEventArgs e) in C:\[..]\StandAlone\Program.cs:line 171
   at System.Diagnostics.Process.ErrorReadNotifyUser(String data)

Not redirected? And you are telling me after I sent 35 lines to its input?

Something is not quite right...smells like a bug.

Update by asker:

Updating the windows builds from here (static) solved my issue, I used some builds from an unofficial website apparently.

左耳近心 2024-12-11 21:34:57

我成功了,我使用了全局变量,就像我的代码中的过程一样:

private void RunProcessAsync(string FfmpegPath, string Parameters)
{
  //Create process info
  ProcessStartInfo oInfo = new ProcessStartInfo(FfmpegPath, Parameters);
  //Set process properties
  oInfo.UseShellExecute = false;
  oInfo.CreateNoWindow = true;
  oInfo.RedirectStandardOutput = false;
  oInfo.RedirectStandardError = true;
  oInfo.RedirectStandardInput = true;

  process.StartInfo = oInfo;

  process.EnableRaisingEvents = true;
  process.ErrorDataReceived += new DataReceivedEventHandler(proc_ErrorDataReceived);
  process.Exited += new EventHandler(proc_Exited);

  process.Start();
  // this.pid = proc.Id;          
  process.BeginErrorReadLine();
}

public void stopProcess()
{
  process.StandardInput.WriteLine("q");
}

I succeeded, I'm using global variables like with the process in my code:

private void RunProcessAsync(string FfmpegPath, string Parameters)
{
  //Create process info
  ProcessStartInfo oInfo = new ProcessStartInfo(FfmpegPath, Parameters);
  //Set process properties
  oInfo.UseShellExecute = false;
  oInfo.CreateNoWindow = true;
  oInfo.RedirectStandardOutput = false;
  oInfo.RedirectStandardError = true;
  oInfo.RedirectStandardInput = true;

  process.StartInfo = oInfo;

  process.EnableRaisingEvents = true;
  process.ErrorDataReceived += new DataReceivedEventHandler(proc_ErrorDataReceived);
  process.Exited += new EventHandler(proc_Exited);

  process.Start();
  // this.pid = proc.Id;          
  process.BeginErrorReadLine();
}

public void stopProcess()
{
  process.StandardInput.WriteLine("q");
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文