【问题标题】:Interact with ffmpeg from a .NET program - Write Input从 .NET 程序与 ffmpeg 交互 - 写入输入
【发布时间】:2011-09-18 02:49:00
【问题描述】:

参考this 问题,如您所见,我设法运行并从程序接收数据。

但是我没有设法向它提交数据,例如,在转换文件时,按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 已开启。

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

【问题讨论】:

  • RedirectStandardInput了吗?
  • @SLaks,我已经为这个问题开了一个赏金。如果您对 ffmpeg 有一些经验,请分享您的知识!根据您的评论,RedirectStandardInput 是真的,我只是忘了在我的问题中指出,现在更新了。
  • 我觉得用ffmpreg-sharp项目会容易很多:code.google.com/p/ffmpeg-sharp
  • @SimonMourier,我愿意,但它最后一次更新是在 2008 年。我不能依赖非活动项目。

标签: .net process ffmpeg interaction


【解决方案1】:

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

:)

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

    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

  • 没有process.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 行到它的输入之后告诉我的?

有些地方不太对劲……闻起来像个虫子。

提问者更新:

here(静态)更新 windows 构建解决了我的问题,我显然使用了来自非官方网站的一些构建。

【讨论】:

  • 这是唯一的答案并且有效。我想知道为什么它没有被接受。
  • 抱歉耽搁了,我已经三天没靠近电脑了。无论如何您的解决方案不起作用:(。在发布问题和开始赏金之前我已经尝试过了。输出文件大小相同,程序继续打印进度,直到转换完成到最后。
  • 感谢您的更新。让我问你 2 个问题 1) 什么是 cygwin bash shell,我需要从 .NET 程序运行 ffmpeg 程序,你从哪里获取编译后的 ffmpeg 文件? 2) 您能否将您的整个解决方案以 zip 文件的形式发送给我?确定我不是在做梦……在评论事情之前我会仔细测试。我已经更新了我的问题中的示例代码。顺便说一句,WriteLines 是什么?
  • 对我来说已经很晚了。如果你给我发邮件到“gmail dot com 的 hemal dot pandya”,我明天会把我的项目发给你。 WriteLinesConsole.WriteLine 调用 process_ErrorDataReceivedprocess_OutputDataReceived 我在上一步中注释掉的。
  • 你能告诉我你从哪里得到编译的 windows ffmpeg 库吗?
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2011-11-09
    • 2013-03-28
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 2020-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多