How to manipulate video in .NET using ffmpeg (updated)
22 Apr 2008Based on the reader comments on my previous entry on this topic I was able to fix some of the issues that others were experiencing.
I changed how the output is read, instead of reading the entire stream at once, its now read line-by-line as ErrorDataReceived and OutputDataReceived events are raised. Also added an extra option in the command line (-ar 44100) to explicitly set the audio frequency to default since it wasn’t being applied to some video formats resulting in an error. And lastly, the console window is now set as hidden.
private void ConvertVideo(string srcURL, string destURL)
{
string ffmpegURL = "~/project/tools/ffmpeg.exe";
DirectoryInfo directoryInfo = new DirectoryInfo(Path.GetDirectoryName(Server.MapPath(ffmpegURL)));
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = Server.MapPath(ffmpegURL);
startInfo.Arguments = string.Format("-i \"{0}\" -aspect 1.7777 -ar 44100 -f flv \"{1}\"", srcURL, destURL);
startInfo.WorkingDirectory = directoryInfo.FullName;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardError = true;
startInfo.CreateNoWindow = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
using (Process process = new Process())
{
process.StartInfo = startInfo;
process.EnableRaisingEvents = true;
process.ErrorDataReceived += new DataReceivedEventHandler(process_ErrorDataReceived);
process.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
process.Exited += new EventHandler(process_Exited);
try
{
process.Start();
process.BeginErrorReadLine();
process.BeginOutputReadLine();
process.WaitForExit();
}
catch (Exception ex)
{
lblError.Text = ex.ToString();
}
finally
{
process.ErrorDataReceived -= new DataReceivedEventHandler(process_ErrorDataReceived);
process.OutputDataReceived -= new DataReceivedEventHandler(process_OutputDataReceived);
process.Exited -= new EventHandler(process_Exited);
}
}
}
void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
lblStdout.Text += e.Data.ToString() + "<br />";
}
}
void process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
lblStderr.Text += e.Data.ToString() + "<br />";
}
}
void process_Exited(object sender, EventArgs e)
{
//Post-processing code goes here
}