Взаимодействовать с ffmpeg из программы .NET - запись ввода - PullRequest
1 голос
/ 18 сентября 2011

Что касается этого вопроса, как вы видите, мне удалось запустить и получить данные из программы.

Однако мне не удалось отправитьнапример, данные к нему при преобразовании файла, нажав 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.

Ответы [ 2 ]

2 голосов
/ 30 сентября 2011

Используйте WriteLine('q'); вместо Write('q');.

:)

Я попытался запустить ffmpeg из оболочки Cygwin Bash и увидел, что мне пришлось вводить ввод после '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 он печатает 61 строку на stderr, 1 строку на stdout и создает mp3-файл1212457 байт.
  • добавляет выход, и он выводит меньшее количество строк на stderr, ничего на stdout и намного меньший файл mp3.

Обратите внимание, что он оставляет файл mp3 вокруг.

Итак.

РЕДАКТИРОВАТЬ

Увидев ваш комментарий, что вы уже пробовали это ..

Я только что перепроверил.Поведение странное.

Сначала я повторил то, что у меня было, и увидел, что отправка "q\n" на 5-й строке в sterr создает файл намного меньшего размера, хотя в разных сериях он немного отличается - между 160K и 220K.

Далее я прокомментировал Console.WriteLine, надеясь, что это заставит ffmpeg выйти быстрее.Напротив, ffmpeg теперь не остановился совсем и создал полный файл с точно таким же числом байтов, 1212457 байт.Это поведение согласуется с вашим наблюдением

Наконец, с 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 строк на его вход?

Что-то не совсем правильно ... пахнет ошибкой.

Обновление от asker:

Обновление сборок Windows с здесь (статическое) решило мою проблему, я использовалнекоторые сборки с неофициального сайта, по-видимому.

1 голос
/ 07 мая 2015

Мне удалось, я использую глобальные переменные, как в процессе в моем коде:

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