Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FFmpeg stops Process C#

Tags:

c#

ffmpeg

I believe my "FFmpeg" process is getting stuck in a infinite loop or it's waiting for something and I don't know what that is. It won't pass the WaitForExit method.

FFmpeg:

-ss 0 -i output.mp4 -t 10 -an -y test.mp4

C# Code:

using (Process process = new Process())
{
     process.StartInfo.UseShellExecute = false;
     process.StartInfo.RedirectStandardOutput = true;
     process.StartInfo.RedirectStandardError = true;
     process.StartInfo.FileName = FileName; // ffmpeg.exe
     process.StartInfo.Arguments = Arguments; //-ss 0 -i output.mp4 -t 10 -an -y test.mp4
     process.Start();
     process.WaitForExit(); // stops here and waits

     return process.StandardOutput.ReadToEnd();
}

Edit:

Adding -loglevel quiet to my ffmpeg query made my problem disappear. Why? How can I achieve same results with out adding -loglevel quiet?

like image 440
Srdjan M. Avatar asked Sep 06 '25 03:09

Srdjan M.


1 Answers

You are redirecting standard and error outputs, but then you don't read from them until child process exits.

There is a buffer of limited size associated with those outputs, and when this buffer becomes full - process (in this case ffmpeg) blocks when trying to write there. So this buffer is like queue: one side (one process, ffmpeg) pushes stuff there, and another side (your process, because you redirected output) is expected to pop them from queue. If you do not do that - queue becomes full and one process cannot push items there, so it blocks waiting for space to become available.

For that reason adding -loglevel quiet "solves" the problem, reducing output of ffmpeg so that it fits into buffer even without you ever reading from it.

So easiest solution is - don't redirect error output (you are not reading it anyway), and read standard output:

process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;                
process.StartInfo.FileName = FileName; // ffmpeg.exe
process.StartInfo.Arguments = Arguments; //-ss 0 -i output.mp4 -t 10 -an -y test.mp4
process.Start();
string result = process.StandardOutput.ReadToEnd();
process.WaitForExit(); // stops here and waits
return result;

If you need to read from both error and standard output, or if you need a timeout - that's more complicated, but you can find plenty of solutions on internet.

like image 178
Evk Avatar answered Sep 08 '25 15:09

Evk