Reputation: 23
I am using ffmpeg commands with C# processes. I used a command to change the audio of a video and it was working but I also wanted to write the output to a text file. The new command works from cmd but apparently, it does not work while using a C# process. The command that does not work with the Process is:
ffmpeg -i videoPath -i audioPath -c:v copy -map 0:v:0 -map 1:a:0 -shortest newVideoPath > textFilePath 2>&1
And the working command is the same without the last part:
ffmpeg -i videoPath -i audioPath -c:v copy -map 0:v:0 -map 1:a:0 -shortest newVideoPath
Here is the C# code:
Process proc = new Process();
proc.StartInfo.FileName = ffmpegPath;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.Arguments = "-i " + videoPath + " -i " + newAudioPath + " -c:v copy" + " -map" + " 0:v:0 " + "-map 1:a:0 " + "-shortest " + newVideoPath + " > " + @"F:\Videos\log.txt"+ " 2>&1";
proc.EnableRaisingEvents = true;
proc.Exited += UpdateVideoSource;
proc.Start();
I checked the arguments over and over again, and looked for missing spaces but nothing worked. What can be the problem?
Upvotes: 2
Views: 739
Reputation: 7590
The function >
is specific to cmd.
To redirect the process output to a file, you can redirect the output to the calling program that will write to a file :
void Redirect(StreamReader output, StreamWriter to)
{
string textLine;
while ((textLine = output.ReadLine()) == null)
{
to.WriteLine(textLine);
}
}
using (Process proc = new Process())
{
proc.StartInfo.FileName = ffmpegPath;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.Arguments = "-i " + videoPath + " -i " + newAudioPath + " -c:v copy" + " -map" + " 0:v:0 " + "-map 1:a:0 " + "-shortest";
proc.EnableRaisingEvents = true;
proc.Exited += UpdateVideoSource;
proc.Start();
using (StreamWriter writer = File.CreateText(@"F:\Videos\log.txt"))
{
//Redirect standard and error ouput
var standardOutputThread = new Thread(new ThreadStart(() => Redirect(proc.StandardOutput, writer)));
var errorOutputThread = new Thread(new ThreadStart(() => Redirect(proc.StandardError, writer)));
//Start redirect thread
standardOutputThread.Start();
errorOutputThread.Start();
//Wait the end of redirection
standardOutputThread.Join();
errorOutputThread.Join();
}
proc.WaitForExit();
}
Upvotes: 0
Reputation: 7590
ffmpeg has the option -report :
Dump full command line and log output to a file named program-YYYYMMDD-HHMMSS.log in the current directory.
By default, the file generated follow the parttern program-YYYYMMDD-HHMMSS.log
. To specify a file, you can set the environnement variable variable FFREPORT :
FFREPORT=file=ffreport.log:level=verbose
In C#, you can start a process with a specific environnement variables by ProcessStartInfo.EnvironmentVariables :
Process proc = new Process();
proc.StartInfo.FileName = ffmpegPath;
proc.StartInfo.RedirectStandardError = false; // Don't redirect the output
proc.StartInfo.RedirectStandardOutput = false;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
//Add the argument -report
proc.StartInfo.Arguments = "-i " + videoPath + " -i " + newAudioPath + " -c:v copy" + " -map" + " 0:v:0 " + "-map 1:a:0 " + "-shortest " + newVideoPath + " -report";
//Set the output file and the log level
proc.StartInfo.EnvironmentVariables["FFREPORT"] = "file=ffreport.log:level=verbose";
proc.EnableRaisingEvents = true;
proc.Exited += UpdateVideoSource;
proc.Start();
I haven't tested, but this is good start.
Upvotes: 2