Запуск ffmpeg.exe через службу Windows не завершается при работе с большими файлами - PullRequest
1 голос
/ 24 ноября 2010

Я использую ffmpeg.exe для преобразования видеофайлов в формат flv . Для этой цели я использую службу windows, чтобы запустить процесс преобразования в фоновом режиме . При попытке преобразовать большие файлы (я испытал это при размере файла> 14 МБ) через службу Windows, он застревает в строке, которая запускает процесс (то есть process.start();) .

Но когда я попытался запустить ffmpeg.exe напрямую из командной строки, это сработало без проблем.

Мой код в Служба Windows как следует:

private Thread WorkerThread; 
protected override void OnStart(string[] args)
{ 

   WorkerThread = new Thread(new ThreadStart(StartHandlingVideo));
   WorkerThread.Start();
}

protected override void OnStop()
{ 
   WorkerThread.Abort();
}

private void StartHandlingVideo()
{   
   FilArgs = string.Format("-i {0} -ar 22050 -qscale 1 {1}", InputFile, OutputFile);
   Process proc;
   proc = new Process();

   try
   {

     proc.StartInfo.FileName = spath + "\\ffmpeg\\ffmpeg.exe";
     proc.StartInfo.Arguments = FilArgs;
     proc.StartInfo.UseShellExecute = false;
     proc.StartInfo.CreateNoWindow = false;
     proc.StartInfo.RedirectStandardOutput = true;
     proc.StartInfo.RedirectStandardError = true;

     eventLog1.WriteEntry("Going to start process of convertion");

     proc.Start();

     string StdOutVideo = proc.StandardOutput.ReadToEnd();
     string StdErrVideo = proc.StandardError.ReadToEnd();

     eventLog1.WriteEntry("Convertion Successful");
     eventLog1.WriteEntry(StdErrVideo);               
 }
 catch (Exception ex)
 {
     eventLog1.WriteEntry("Convertion Failed");
     eventLog1.WriteEntry(ex.ToString());            
 }
 finally
 {
     proc.WaitForExit();
     proc.Close();
 }

Как мне избавиться от этой ситуации.

1 Ответ

6 голосов
/ 24 ноября 2010

Кажется, вы зашли в тупик, потому что вы выполнили синхронное чтение до конца обоих перенаправленных потоков.

Ссылка от MSDN :

Тампохожая проблема, когда вы читаете весь текст как из стандартного потока вывода, так и из стандартных потоков ошибок.Следующий код C #, например, выполняет операцию чтения в обоих потоках.

 // Do not perform a synchronous read to the end of both
 // redirected streams.
 // string output = p.StandardOutput.ReadToEnd();
 // string error = p.StandardError.ReadToEnd();
 // p.WaitForExit();
 // Use asynchronous read operations on at least one of the streams.
 p.BeginOutputReadLine();
 string error = p.StandardError.ReadToEnd();
 p.WaitForExit();

В примере кода исключается условие взаимоблокировки путем выполнения операций асинхронного чтения в потоке StandardOutput.Условие взаимоблокировки возникает, если родительский процесс вызывает p.StandardOutput.ReadToEnd, за которым следует p.StandardError.ReadToEnd, и дочерний процесс записывает достаточно текста, чтобы заполнить свой поток ошибок.Родительский процесс будет бесконечно ждать, пока дочерний процесс закроет свой поток StandardOutput.Дочерний процесс будет бесконечно ждать, пока родительский объект прочитает полный поток StandardError.

Вы можете использовать асинхронные операции чтения, чтобы избежать этих зависимостей и их потенциальной взаимоблокировки.Кроме того, вы можете избежать условия взаимоблокировки, создав два потока и считав выходные данные каждого потока в отдельном потоке.

...