2011-09-04 14 views
5

che sto cercando di creare un wrapper .NET per la conversione di media-file usando ffmepg, ecco che cosa ho provato:Interagire con ffmpeg da un programma .NET?

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(); 
    } 
} 

Cosa succede in realtà è il contenuto del programma FFmpeg è stampato al Console app, ma la variabile result è una stringa vuota. Voglio controllare l'avanzamento della conversione in modo interattivo, quindi l'utente non deve neanche sapere che sto usando ffmpeg, ma conosce ancora i dettagli dell'avanzamento della conversione e quale percentuale ecc. L'app è all'altezza.

Fondamentalmente sarei anche felice con un wrapper .NET per una funzione P/Invoke to conversion SOLO (non sono interessato a un'intera libreria esterna, a meno che non riesca a estrarre la funzione PI da esso).

Chiunque abbia esperienza in ffmpeg & .NET?

Aggiornamento Vedere la mia ulteriore domanda, how to write input to a running ffmpeg process.

risposta

4

ecco la risposta:

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!"); 
} 
+0

Lo StringBuilder sb non viene utilizzato. –

+0

@aaaa bbbb: rimosso, grazie. È rimasto da tentativi precedenti, comunque ho aggiunto alcune funzionalità importanti alla mia risposta. ** Potrebbe per favore dare un'occhiata a [questo] (http://stackoverflow.com/questions/7296901) **? – Shimmy

0

Provare a utilizzare ffmpeg-sharp.

+0

io non preferisco usare altri strumenti esterni. Mi piacerebbe sapere come creare solo P/Invokes di base per il solo supporto di conversione. C'è un modo per insterparire con un programma del genere usando un processo in background come nel mio esempio? Cosa mi sto perdendo? – Shimmy

+0

Controlla http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/ea8b0fd5-a660-46f9-9dcb-d525cc22dcbd puoi nascondere la finestra ma sono sicuro che puoi leggere l'output di ancora. –

+0

http://stackoverflow.com/questions/7296901 – Shimmy