ffmpeg.exe freezes
I'm using Asp.Net C# Framework 4 and currently developing a video conversion application. I'm also using ffmpeg to convert from all uploaded formats to flv. I'm first converting uploaded file to mpg and after to flv due to problems I encountered while trying conversion directly to flv from mp4 sometimes. But ffmpeg freezes as soon as it's done with conversion process to mpg file. When I run task manager and check the processes list, it just stands there using no CPU resource. When I end the ffmpeg process directly from task manager, other process take place which converts from mpg to flv and preview file (jpg) and works smoothly. Due to freezing of first process, the second process cannot start when I try to upload from my web page's file upload form. I appreciate any response from now. Here is my code:
string duration = "00:00:00";
//converting video
Process ffmpeg;
ffmpeg = new Process();
// convert to mpg 1st
ffmpeg.StartInfo.Arguments = " -i \"" + Server.MapPath("static/user/vid/") + videolink + "\" -f mpeg -b 300k -ac 2 -ab 128k -ar 44K \"" + Server.MapPath("static/user/vid/") + mpglink + "\"";
ffmpeg.StartInfo.FileName = Page.MapPath("bin/ffmpeg.exe");
ffmpeg.StartInfo.CreateNoWindow = true;
ffmpeg.StartInfo.UseShellExecute = false;
ffmpeg.StartInfo.RedirectStandardOutput = true;
ffmpeg.StartInfo.RedirectStandardError = true;
ffmpeg.Start();
ffmpeg.WaitForExit();
ffmpeg.Close();
// mpg 2 flv
ffmpeg = new Process();
ffmpeg.StartInfo.Arguments = " -i \"" + Server.MapPath("static/user/vid/") + mpglink + "\" -f flv -s 624x352 \"" + Server.MapPath("static/user/vid/") + flvlink + "\"";
ffmpeg.StartInfo.FileName = Page.MapPath("bin/ffmpeg.exe");
ffmpeg.StartInfo.CreateNoWindow = true;
ffmpeg.StartInfo.UseShellExecute = false;
ffmpeg.StartInfo.RedirectStandardOutput = true;
ffmpeg.StartInfo.RedirectStandardError = true;
ffmpeg.Start();
ffmpeg.BeginOutputReadLine();
string error = ffmpeg.StandardError.ReadToEnd();
ffmpeg.WaitForExit();
try
{
duration = error.Substring(error.IndexOf("Duration: ") + 10, 8);
开发者_如何学C }
catch
{
}
if (ffmpeg.ExitCode != 0)
{
ltrUpload.Text = "<div class=\"resultbox-negative\" id=\"divResult\">Problem occured during upload process. Error code: " + error + "<br>" + "</div>";
return;
}
ffmpeg.Close();
// generate preview image
ffmpeg.StartInfo.Arguments = " -i \"" + Server.MapPath("static/user/vid/") + flvlink + "\" -s 624x352 -ss 00:00:03 -an -vframes 1 -f image2 -vcodec mjpeg \"" + Server.MapPath("static/user/vid/") + flvlink.Replace(".flv", ".jpg") + "\"";
ffmpeg.StartInfo.FileName = Page.MapPath("bin/ffmpeg.exe");
ffmpeg.StartInfo.CreateNoWindow = true;
ffmpeg.StartInfo.UseShellExecute = false;
ffmpeg.StartInfo.RedirectStandardOutput = true;
ffmpeg.StartInfo.RedirectStandardError = true;
ffmpeg.Start();
ffmpeg.WaitForExit();
ffmpeg.Close();
// deleting original file and mpg
FileInfo fi = new FileInfo(Server.MapPath("static/user/vid/") + videolink);
if (fi.Exists) fi.Delete();
fi = new FileInfo(Server.MapPath("static/user/vid/") + mpglink);
if (fi.Exists) fi.Delete();
I know this is a very old question, but if someone gets here because of a Google search, the answer is the following:
You would have to read the redirected error output of the first ffmpeg process, too, even if you do not need it. It will result in a deadlock if you do not read the redirected error output because your program will wait for the process to finish, but the process waits for the filled error output stream to be read. You can look it up here.
// convert to mpg 1st
ffmpeg.StartInfo.Arguments = " -i \"" + Server.MapPath("static/user/vid/") + videolink + "\" -f mpeg -b 300k -ac 2 -ab 128k -ar 44K \"" + Server.MapPath("static/user/vid/") + mpglink + "\"";
ffmpeg.StartInfo.FileName = Page.MapPath("bin/ffmpeg.exe");
ffmpeg.StartInfo.CreateNoWindow = true;
ffmpeg.StartInfo.UseShellExecute = false;
ffmpeg.StartInfo.RedirectStandardOutput = true;
ffmpeg.StartInfo.RedirectStandardError = true;
ffmpeg.Start();
// Use asynchronous read operations on at least one of the streams.
// Reading both streams synchronously would generate another deadlock.
ffmpeg.BeginOutputReadLine();
string tmpErrorOut = ffmpeg.StandardError.ReadToEnd();
ffmpeg.WaitForExit();
ffmpeg.Close();
So you would have to read the redirected error and output streams like you did with your second ffmpeg process.
The same goes for your generating image preview part!
private bool ReturnVideo(string fileName)
{
string html = string.Empty;
//rename if file already exists
int j = 0;
string AppPath;
string inputPath;
string outputPath;
string imgpath;
AppPath = Request.PhysicalApplicationPath;
//Get the application path
inputPath = AppPath + "Upload\\Videos\\OriginalVideo";
//Path of the original file
outputPath = AppPath + "Upload\\Videos\\ConvertVideo";
//Path of the converted file
imgpath = AppPath + "Upload\\Videos\\Thumbs";
//Path of the preview file
string filepath = Server.MapPath("../Upload/Videos/OriginalVideo/" + fileName);
while (File.Exists(filepath))
{
j = j + 1;
int dotPos = fileName.LastIndexOf(".");
string namewithoutext = fileName.Substring(0, dotPos);
string ext = fileName.Substring(dotPos + 1);
fileName = namewithoutext + j + "." + ext;
filepath = Server.MapPath("../Upload/Videos/OriginalVideo/" + fileName);
}
try
{
this.fileuploadImageVideo.SaveAs(filepath);
}
catch
{
return false;
}
string outPutFile;
outPutFile = "../Upload/Videos/OriginalVideo/" + fileName;
int i = this.fileuploadImageVideo.PostedFile.ContentLength;
System.IO.FileInfo a = new System.IO.FileInfo(Server.MapPath(outPutFile));
while (a.Exists == false)
{ }
long b = a.Length;
while (i != b)
{ }
string cmd = " -i \"" + inputPath + "\\" + fileName + "\" \"" + outputPath + "\\" + fileName.Remove(fileName.IndexOf(".")) + ".flv" + "\"";
ConvertNow(cmd);
ViewState["fileName"] = fileName.Remove(fileName.IndexOf(".")) + ".wmv";
string imgargs = " -i \"" + inputPath + "\\" + fileName.Remove(fileName.IndexOf(".")) + ".wmv" + "\" -f image2 -ss 1 -vframes 1 -s 280x200 -an \"" + imgpath + "\\" + fileName.Remove(fileName.IndexOf(".")) + ".jpg" + "\"";
ConvertNow(imgargs);
return true;
}
private void ConvertNow(string cmd)
{
string exepath;
string AppPath = Request.PhysicalApplicationPath;
//Get the application path
exepath = AppPath + "ffmpeg.exe";
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = exepath;
//Path of exe that will be executed, only for "filebuffer" it will be "wmvtool2.exe"
proc.StartInfo.Arguments = cmd;
//The command which will be executed
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.RedirectStandardOutput = false;
proc.Start();
while (proc.HasExited == false)
{ }
}
if (fileuploadImageVideo.HasFile)
{
ReturnVideo(this.fileuploadImageVideo.FileName.ToString());
string filename = fileuploadImageVideo.PostedFile.FileName;
fileuploadImageVideo.SaveAs(Server.MapPath("../upload/Video/"+filename));
objfun.Video = filename ;
}
精彩评论