Important Update to Another Simple C# Wrapper For FFmpeg

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

        }

Tags: , , , ,

Comments (5) -

Zero
Zero Russia
10/15/2010 9:44:52 PM #

Thank you. That's what I was looking for!

Reply

Tarqui
Tarqui Italy
5/4/2011 4:43:28 PM #

Dude, you're AWESOME !!!

Reply

Eric
Eric France
11/25/2011 11:08:13 AM #

hi,

what is the purpose of this code if exitcode is equal to 0 (or not) same code is executed

if (proc.ExitCode == 0)
{
    proc.Close();
    if (objStreamReader != null)
    {
      objStreamReader.Close();
    }
}
else
{
    proc.Close();
    if (objStreamReader != null)
   {
        objStreamReader.Close();
    }
}

Reply

nLL
nLL
11/25/2011 11:21:39 AM #

I don't remember lol.

I am using below one now.

private string RunProcessAlternate(string Parameters)
        {
            Process p = new Process();
            p.StartInfo.UseShellExecute = false;
      p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.FileName = this.FFmpegPath;
            p.StartInfo.Arguments = Parameters;
            p.StartInfo.WorkingDirectory = Path.GetDirectoryName(this.FFmpegPath);
            p.Start();
            p.BeginOutputReadLine();
            string output = "";//p.StandardOutput.ReadToEnd();
            string error = p.StandardError.ReadToEnd();
            p.WaitForExit();
            p.Close();
            return "Output: "+ output +"<br/> Error: " + error;
        }

Reply

Eric
Eric France
11/25/2011 11:39:03 AM #

do you use a new release of your code source ?
if yes, could you please share it ?

ty

Reply

Add comment

  Country flag

biuquote
Loading

Adverts

Welcome

Tag cloud

Month List