2

In reference to this question, as you can see I managed to run and receive data from the program.

However I didn't manage to submit data to it, for instance, while converting a file, pressing q immediately stop conversion and stops the program.
I need my application to support stopping the process as well, and I think this should be done by passing this parameter to the ffmpeg app, since I want it to take care of all uncollected resource or whatever dust it would leave behind if I would just go and use process.Kill()

Here is what I've tried:

static int lineCount = 0;
static bool flag;
static void process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
  Console.WriteLine("Error ({1:m:s:fff}: {0})", lineCount++,
      DateTime.Now);

  if (e.Data != null && string.Equals(e.Data,"Press [q] to stop, [?] for help")) 
    flag = true;

  if (flag)
  {
    flag = false;
    Console.WriteLine("Stopping ({0:m:s:fff})...", DateTime.Now);
    process.CancelErrorRead();
    process.CancelOutputRead();
    process.StandardInput.WriteLine("q");
  }   

  Console.WriteLine(e.Data);
  Console.WriteLine();
}

But it doesn't do anything, seems that once the conversion has been requested, I have no control on it any more, I can only receive output from it. Running it as stand alone does allow me interaction of course.

What am I missing here, is it a different trick in submitting the output or the code in previous answer is wrong, or I should have chosen a different approach?

For your attention, RedirectStandardInput is on.

NOTE: as you can see in the answer of my previous question, ffmpeg interacts differently, I think the one who knows the answer will be (maybe I'm wrong) someone with experience in ffmpeg.

4
  • Did you RedirectStandardInput? Commented Sep 18, 2011 at 3:01
  • @SLaks, I've opened a bounty to this question. If you have some experience with ffmpeg, please share your knowledge! As per your comment, RedirectStandardInput is true, I just forgot to point it out in my question, now updated. Commented Sep 24, 2011 at 23:55
  • I think it would be a lot easier to use the ffmpreg-sharp project: code.google.com/p/ffmpeg-sharp Commented Sep 30, 2011 at 20:04
  • @SimonMourier, I would, but it was last updated in 2008. I can't rely on inactive projects. Commented Oct 1, 2011 at 21:04

2 Answers 2

3
+50

Use WriteLine('q'); instead of Write('q');.

:)

I tried to run ffmpeg from cygwin bash shell and saw that I had to type an enter after 'q'. So....

    static void process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
    {
        Console.WriteLine("Error line: {0} ({1:m:s:fff})", lineCount++,
            DateTime.Now);
        Console.WriteLine(e.Data);
        Console.WriteLine();
        if (lineCount == 5)
            process.StandardInput.WriteLine("q");
    }

With the stock c:\Documents and Settings\All Users\Documents\My Music\Sample Music\Beethoven's Symphony No. 9 (Scherzo).wma

  • without the process.StandardInput.WriteLine it prints 61 lines on stderr, 1 line on stdout and creates mp3 file of 1212457 bytes.
  • add the quit and it prints less number of lines on stderr, nothing on stdout and a much smaller mp3 file.

Note that it does leave the mp3 file around.

So there.

EDIT

After seeing your comment that you already tried this..

I just rechecked. The behavior is strange.

First I retried what I had and saw that sending "q\n" on the 5th line to sterr creates a much smaller file, though slightly different sizes in different runs -- between 160K and 220K.

Next I commented out Console.WriteLine hoping it will make ffmpeg quit faster. On the contrary, ffmpeg now did not stop at all and created the full file with exact same byte count, 1,212,457 bytes. This behavior is consistent with your observation

Finally, with WriteLines in place, I pumped "q\n" on every line to stderr after the fifth. Big surprise! After logging 40 error lines,

Unhandled Exception: System.InvalidOperationException: StandardIn has not been redirected.
   at System.Diagnostics.Process.get_StandardInput()
   at StandAlone.Program.process_ErrorDataReceived(Object sender, DataReceivedEventArgs e) in C:\[..]\StandAlone\Program.cs:line 171
   at System.Diagnostics.Process.ErrorReadNotifyUser(String data)

Not redirected? And you are telling me after I sent 35 lines to its input?

Something is not quite right...smells like a bug.

Update by asker:

Updating the windows builds from here (static) solved my issue, I used some builds from an unofficial website apparently.

Sign up to request clarification or add additional context in comments.

8 Comments

It's the only answer and it works. I am wondering why it is not getting accepted.
Sorry for the delay, I wasn't near the computer for 3 days now. Anyway your solution doesn't work :(. I've tried this already before posting the question and starting the bounty. The output file is the same size and the program keeps on printing the progress until the conversion is completed to the end.
Thanks for your update. Lemme ask you 2 questions 1) What's the cygwin bash shell, I need to run the ffmpeg program from a .NET program, where do you take the compiled ffmpeg files from? 2) Can you please send me your entire solution in a zip file? Be sure I'm not dreaming... I am testing carefully before commenting on things. I've updated the sample code in my question. BTW, what's WriteLines?
Its very late in the night for me. If you send me a mail to "hemal dot pandya at gmail dot com" I will send you my project tomorrow. WriteLines is Console.WriteLine calls in process_ErrorDataReceived and process_OutputDataReceived that I commented out in the previous step.
Can you please just tell me where you take compiled windows ffmpeg libs from?
|
1

I succeeded, I'm using global variables like with the process in my code:

private void RunProcessAsync(string FfmpegPath, string Parameters)
{
  //Create process info
  ProcessStartInfo oInfo = new ProcessStartInfo(FfmpegPath, Parameters);
  //Set process properties
  oInfo.UseShellExecute = false;
  oInfo.CreateNoWindow = true;
  oInfo.RedirectStandardOutput = false;
  oInfo.RedirectStandardError = true;
  oInfo.RedirectStandardInput = true;

  process.StartInfo = oInfo;

  process.EnableRaisingEvents = true;
  process.ErrorDataReceived += new DataReceivedEventHandler(proc_ErrorDataReceived);
  process.Exited += new EventHandler(proc_Exited);

  process.Start();
  // this.pid = proc.Id;          
  process.BeginErrorReadLine();
}

public void stopProcess()
{
  process.StandardInput.WriteLine("q");
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.