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);
}
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 ;
}
Related
I'm using windows 10.
I'm trying to compile a c++ file within c# using MinGW(the MinGW folder is in the projects directory), but it won't compile a resource script (using windres).
Whenever I use windres in cmd it says: "C:/Users/username/AppData/Local/Temp/my.rc:1: unrecognized escape sequence".
but still works.
But when I run the exact same command through c# (by creating a process) it doesn't work at all and says: "The filename, directory name, or volume label syntax is incorrect.".
My code:
String tempDir = Path.GetTempPath();
String file = tempDir + "my.rc";
using (StreamWriter writer = new StreamWriter(file, false, Encoding.ASCII))
{
if (!textIcon.Text.Equals(""))
await writer.WriteLineAsync("25 ICON \"" + textIcon.Text + "\"");
if (checkAdmin.Checked)
{
String manifest = tempDir + #"\manifest.xml";
createManifest(manifest);
await writer.WriteLineAsync("55 24 \"" + manifest + "\"");
}
}
String args2 = "/c \"" + Path.Combine(gccLocation, "windres.exe") + "\" -o \"" + Path.Combine(tempDir, "my.o").Replace("\\", "/") + "\" \"" + file.Replace("\\", "/") + "\"";
//Debug
//args2 = "/k echo " + args2;
ProcessStartInfo psi2 = new ProcessStartInfo();
psi2.FileName = "CMD.exe";
psi2.Arguments = args2;
psi2.UseShellExecute = false;
psi2.CreateNoWindow = true;
//Debug
//psi2.CreateNoWindow = false;
Process windres = Process.Start(psi2);
windres.WaitForExit();
if(windres.ExitCode != 0)
{
MessageBox.Show("Error: Could not create resource file (" + windres.ExitCode + ")");
}
Ended up using a batch file to run the command.
String args2 = "windres.exe -i \"" + Path.GetFullPath(file) + "\" -o \"" + Path.Combine(tempDir, "my.o") + "\"" ;
using (StreamWriter writer = new StreamWriter(tempDir + #"\my.bat", false, Encoding.ASCII))
{
await writer.WriteLineAsync("#echo off");
await writer.WriteLineAsync("cd " + Path.GetFullPath(gccLocation));
await writer.WriteLineAsync(args2);
}
//Debug
//args2 = "/k echo " + args2;
ProcessStartInfo psi2 = new ProcessStartInfo();
psi2.FileName = tempDir + #"\my.bat";
psi2.UseShellExecute = false;
psi2.CreateNoWindow = true;
//Debug
//psi2.CreateNoWindow = false;
Process windres = Process.Start(psi2);
windres.WaitForExit();
I am putting together a training site for my company and we need to extract an image from each mp4 video we upload. I have searched lots and decided to try FFMPEG.
Here is what I have so far. I'm not getting errors, but no image in the specified folder.
Any help would be appreciated.
string inputfile = Server.MapPath("/Report/TrainingLibrary/Material/Videos/RMSIMAILSignature.mp4");
//string withouttext;
string thumbpath;
string thumbname;
string thumbargs;
//string thumbre;
thumbpath = AppDomain.CurrentDomain.BaseDirectory + "Reports\\ TrainingLibrary\\Material\\Videos\\";
thumbname = thumbpath + "Image" + "%d" + ".jpg";
thumbargs = "-i " + inputfile + " -vframes 1 -ss 00:00:07 -s 150x150 " + thumbname;
Process thumbproc = new Process();
thumbproc = new Process();
thumbproc.StartInfo.FileName = "C:\\FFMPEG\\Bin\\ffmpeg.exe";
thumbproc.StartInfo.Arguments = thumbargs;
thumbproc.StartInfo.UseShellExecute = false;
thumbproc.StartInfo.CreateNoWindow = false;
thumbproc.StartInfo.RedirectStandardOutput = false;
try
{
thumbproc.Start();
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
thumbproc.WaitForExit();
thumbproc.Close();
I have a strange requirement. User can upload their video of any format (or a limited format). We have to store them and convert them to .mp4 format so we can play that in our site.
Same requirement also for audio files.
I have googled but I can't get any proper idea. Any help or suggestions....??
Thanks in advance
You can convert almost any video/audio user files to mp4/mp3 with FFMpeg command line utility. From .NET it can be called using wrapper library like Video Converter for .NET (this one is nice because everything is packed into one DLL):
(new NReco.VideoConverter.FFMpegConverter()).ConvertMedia(pathToVideoFile, pathToOutputMp4File, Formats.mp4)
Note that video conversion requires significant CPU resources; it's good idea to run it in background.
Your Answer
please Replace .flv to .mp4 you will get your answer
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 + "OriginalVideo";
//Path of the original file
outputPath = AppPath + "ConvertVideo";
//Path of the converted file
imgpath = AppPath + "Thumbs";
//Path of the preview file
string filepath = Server.MapPath("~/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("~/OriginalVideo/" + fileName);
}
try
{
this.fileuploadImageVideo.SaveAs(filepath);
}
catch
{
return false;
}
string outPutFile;
outPutFile = "~/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);
string imgargs = " -i \"" + outputPath + "\\" + fileName.Remove(fileName.IndexOf(".")) + ".flv" + "\" -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 "flvtool2.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)
{
}
}
protected void btn_Submit_Click(object sender, EventArgs e)
{
ReturnVideo(this.fileuploadImageVideo.FileName.ToString());
}
I know it's a bit old thread but if I get here other people see this too. You shoudn't use it process info to start ffmpeg. It is a lot to do with it. Xabe.FFmpeg you could do this by running just
await Conversion.Convert("inputfile.mkv", "file.mp4").Start()
This is one of easiest usage. This library provide fluent API to FFmpeg.
I wrote the code to convert the file in c#asp.net using ffmpeg. While executing it shows error as "The filename, directory name, or volume label syntax is incorrect" but my paths are correct. So what is the solution for this?
ProcessStartInfo info = new ProcessStartInfo("e:\ffmpeg\bin\ffmpeg.exe", "-i cars1.flv -same_quant intermediate1.mpg");
process.Start();
I tried another way as shown below. But that is also won't works.
ProcessStartInfo info = new ProcessStartInfo("ffmpeg.exe", "-i cars1.flv -same_quant intermediate1.mpg");
Please help me with sample code for converting one video file format to another using ffmpeg in c# asp.net. Thanks in advance.
There is wrapper library available
http://www.ffmpeg-csharp.com/
Also refer
http://www.codeproject.com/Articles/24995/FFMPEG-using-ASP-NET
https://stackoverflow.com/questions/tagged/asp.net+c%23+video
string apppath = Request.PhysicalApplicationPath;
string outf = Server.MapPath(".");
string fileargs = "-i" + " " + "\"C:/file.mp4 \"" + " " + "\"C:/files/test.flv \"";
Process myProcess = new Process();
myProcess.StartInfo.FileName = Server.MapPath(".")+"//ffmpeg.exe";
myProcess.StartInfo.Arguments = fileargs;
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.CreateNoWindow = false;
myProcess.StartInfo.RedirectStandardOutput = false;
myProcess.Start();
myProcess.WaitForExit(50 * 1000);
Thanks
Deepu
The backslashes (\) in your path are considered to start escape sequences. To prevent this, either use double backslashes (\\), or prefix the string with #.
ProcessStartInfo info = new ProcessStartInfo("e:\\ffmpeg\\bin\\ffmpeg.exe",
"-i cars1.flv -same_quant intermediate1.mpg");
Or:
ProcessStartInfo info = new ProcessStartInfo(#"e:\ffmpeg\bin\ffmpeg.exe",
"-i cars1.flv -same_quant intermediate1.mpg");
You need to have backslashes in your path see below this is how I create videos using ffmpeg.exe
string sConverterPath = #"C:\ffmpeg.exe";
string sConverterArguments = #" -i ";
sConverterArguments += "\"" + sAVIFile + "\"";
sConverterArguments += " -s " + iVideoWidth.ToString() + "x" + iVideoHeight.ToString() + " ";
sConverterArguments += " -b " + iVideoBitRate.ToString() + "k -ab " + iAudioBitRate.ToString() + "k -ac 1 -ar 44100 -r 24 -absf remove_extra ";
sConverterArguments += "\"" + sOutputFile + "\"";
Process oProcess = new Process();
oProcess.StartInfo.UseShellExecute = true;
oProcess.StartInfo.Arguments = sConverterArguments;
oProcess.StartInfo.FileName = sConverterPath;
string inputpath = strFileNamePath;
string outputpath = "C:\\Image\\";
//for (int iIndex = 0; iIndex < 1000; iIndex++)
//{
//string fileargs = "-i" + " " + inputpath + " -ab 56 -ar 44100 -b 200 -r 15 -s 320x240 -f flv " + outputpath + "SRT.flv";
string fileargs = "-i" + " " + inputpath + " " + outputpath + "image.jpg";
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = "C:\\Documents and Settings\\Badr\\My Documents\\Visual Studio 2008\\Projects\\Video2image2video.\\ffmpeg\\ffmpeg.exe";
p.StartInfo.Arguments = fileargs;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.Start();
i have this code this creates only 1 image of video i apply a loop but i repeatedly generates the initial image how can i get images of all the video
thanx in advance
From the documentation of ffmpeg:
You can extract images from a video,
or create a video from many images:
For extracting images from a video:
ffmpeg -i foo.avi -r 1 -s WxH -f
image2 foo-%03d.jpeg
This will extract one video frame per
second from the video and will output
them in files named foo-001.jpeg',
foo-002.jpeg', etc. Images will be
rescaled to fit the new WxH values.
So just change the arguments you pass to ffmpeg and you should be up and running.
Hi do you want to take images in video files when you for to return in in this way;
for (int i = 0; i < iImageCount; i++)
{
string sInputVideo = Page.MapPath(...);
string sImageCapture = Page.MapPath("") + "\\Videolar\\" + ImageName+ "_" + iResim + ".jpg";
ffmpeg.StartInfo.Arguments = " -i \"" + sInputVideo + "\" -s 108*100 -ss " + iImageCapture + " -vframes 1 -f image2 -vcodec mjpeg \"" + sImageCapture + "\"";
ffmpeg.StartInfo.FileName = (Server.MapPath("Referanslar/ffmpeg.exe"));
ffmpeg.Start();
ffmpeg.WaitForExit();
ffmpeg.Close();
iImageCapture += 1;
iResim++;
}
You can take pictures as you like by changing it ;)