Interact with ffmpeg from a .NET program?
Asked Answered
C

2

7

I'm trying to create a .NET wrapper for media-file conversion using ffmepg, here is what I've tried:

static void Main(string[] args)
{
  if (File.Exists("sample.mp3")) File.Delete("sample.mp3");

  string result;

  using (Process p = new Process())
  {
    p.StartInfo.FileName = "ffmpeg";
    p.StartInfo.Arguments = "-i sample.wma sample.mp3";

    p.StartInfo.UseShellExecute = false;
    p.StartInfo.RedirectStandardOutput = true;

    p.Start();

    //result is assigned with an empty string!
    result = p.StandardOutput.ReadToEnd();

    p.WaitForExit();
  }
}

What actually happens is the content of the ffmpeg program is printed out to the Console app, but the result variable is an empty string. I want to control the conversion progress interactively, so the user doesn't even have to know I'm using ffmpeg, but he still knows the conversion progress' details and what percentage etc. the app is up to.

Basically I would also be happy with a .NET wrapper for a P/Invoke to conversion function ONLY (I am not interested in a whole external library, unless I can extract the PI function from it).

Anyone with experience in ffmpeg & .NET?

Update Please view my further question, how to write input to a running ffmpeg process.

Christner answered 4/9, 2011 at 1:34 Comment(0)
C
7

Here is the answer:

static void Main()
{
  ExecuteAsync();
  Console.WriteLine("Executing Async");
  Console.Read();
}

static Process process = null;
static void ExecuteAsync()
{
  if (File.Exists("sample.mp3"))
    try
    {
      File.Delete("sample.mp3");
    }
    catch
    {
      return;
    }

  try
  {
    process = new Process();
    ProcessStartInfo info = new ProcessStartInfo("ffmpeg.exe",
        "-i sample.wma sample.mp3");

    info.CreateNoWindow = false;
    info.UseShellExecute = false;
    info.RedirectStandardError = true;
    info.RedirectStandardOutput = true;

    process.StartInfo = info;

    process.EnableRaisingEvents = true;
    process.ErrorDataReceived +=
        new DataReceivedEventHandler(process_ErrorDataReceived);
    process.OutputDataReceived +=
        new DataReceivedEventHandler(process_OutputDataReceived);
    process.Exited += new EventHandler(process_Exited);

    process.Start();

    process.BeginOutputReadLine();
    process.BeginErrorReadLine();
  }
  catch
  {
    if (process != null) process.Dispose();
  }
}

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

static void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
  Console.WriteLine("Output Data Received.");
}

static void process_Exited(object sender, EventArgs e)
{
  process.Dispose();
  Console.WriteLine("Bye bye!");
}
Christner answered 8/9, 2011 at 15:16 Comment(2)
The StringBuilder sb is not used.Geode
@aaaa bbbb: Removed, thanks. It remained from previous attempts, anyway I added some important functionality to my answer. Could you please take a look at this?Christner
H
0

Try using ffmpeg-sharp.

Horsemint answered 4/9, 2011 at 1:36 Comment(2)
I prefer not using other external tools. I would love to hear about how to create some basic simple P/Invokes for conversion support only. Is there a way to insteract with such a program using a background process as in my example? What am I missing out?Christner
Check out social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/… you can hide the window but I'm sure you can read the output of it still.Horsemint

© 2022 - 2024 — McMap. All rights reserved.