by nolovelust
7. October 2010 11:00
If you haven't, read Another Simple C# Wrapper For FFmpeg before this post.
After long hours of suffering I found a solution to large video encoding on asp.net with ffmpeg! If you ever tried you already know that encoding videos larger than 5-6 MB with asp.net and FFmpeg couses Application pool to hang and start eating froms erver's ram. I finally found out that you .NET does not provide more memory to FFMpeg. When converting large files, FFMpeg's out put stream gets filled and waits for .NET to allocate memory resources but is never done. In order to utilize less memory, you need to the buffer periodically.
To do that, just add below method to Encoder.cs and use it in EncodeVideo method instead of using RunProccess method. Or, you could replace actual RunProccess method with this one.
private string RunProcessLargeFile(string Parameters)
{
/* The below will be the right solution ....
* The while loop which reads the stream is very improtant
* for FFMPEG as .NET does not provide more memory to FFMPEG.
* When converting large files, FFMPEG's out put stream gets filled...
* And waits for .NET to allocate memory resources but is never done.
* In order to utilize less memory, we are clearing the buffer periodically.
**/
ProcessStartInfo oInfo = new ProcessStartInfo(this.FFmpegPath, Parameters);
oInfo.WorkingDirectory = Path.GetDirectoryName(this.FFmpegPath);
oInfo.UseShellExecute = false;
oInfo.CreateNoWindow = true;
oInfo.RedirectStandardOutput = true;
oInfo.RedirectStandardError = true;
using (Process proc = System.Diagnostics.Process.Start(oInfo))
{
using (StreamReader srOutput = proc.StandardError)
{
System.Text.StringBuilder output = new System.Text.StringBuilder();
using (StreamReader objStreamReader = proc.StandardError)
{
System.Text.StringBuilder sbOutPut = new StringBuilder();
while (!proc.WaitForExit(1000))
{
sbOutPut.Append(objStreamReader.ReadToEnd().ToString());
}
if (proc.ExitCode == 0)
{
proc.Close();
if (objStreamReader != null)
{
objStreamReader.Close();
}
}
else
{
proc.Close();
if (objStreamReader != null)
{
objStreamReader.Close();
}
}
return sbOutPut.ToString();
}
}
}
}