2009-11-10 13 views
16

Chciałbym móc użyć FFmpeg do konwersji pliku wideo z mojego programu C#. Wiem, że mogę po prostu wywołać polecenie powłoki, , ale czy istnieje lepszy sposób?C# i FFmpeg najlepiej bez poleceń powłoki?

Problem z wywołaniem polecenia przez powłokę, czy nie jestem pewien, czy mógłbyś zrobić takie rzeczy jak pasek postępu, itp. ... czy mógłbyś?

Jeśli nie ma sposobu, ktoś może zaproponować najlepszy sposób rozmieszczenia niektórych frameworków do wykonywania poleceń powłoki. Podanie jednego dużego długiego ciągu jest bardzo kłopotliwym atmem.

+0

Ktoś? No dalej, ktoś musiał użyć ffmpeg z .net –

Odpowiedz

33

Możesz łatwo zaimplementować pasek postępu, jeśli używasz ffmpeg. Wynik działania ffmpeg podczas działania jest następujący:

frame= 3366 fps=465 q=31.0 Lsize= 6474kB time=140.35 bitrate= 377.9kbits/s 

Odświeżono ~ dwa razy na sekundę. Możesz przeanalizować tę linię i uzyskać dane potrzebne do wyświetlenia postępu. Po uruchomieniu w wierszu poleceń widzisz tylko jedną linię aktualizowaną przez cały czas, ale to, co robi ffmpeg, to zapisanie wiersza, a następnie \ r. Dlatego nie widać wielu linii. Jednak podczas korzystania z StreamReader.ReadLine() na wyjściu błędu programu, dostajesz jeden wiersz dla każdej aktualizacji.

Przykładowy kod do odczytu wyników poniżej. Trzeba by zignorować dowolną linię, która nie zaczyna się od „ramy”, może użyć BeginErrorReadLine() + ErrorDataReceived jeśli chcesz czytać wiersze być asynchroniczny, itd., ale masz pomysł (mam faktycznie przetestowane):

using System; 
using System.Diagnostics; 
using System.IO; 

class Test { 
     static void Main (string [] args) 
     { 
       Process proc = new Process(); 
       proc.StartInfo.FileName = "ffmpeg"; 
       proc.StartInfo.Arguments = "-i " + args [0] + " " + args [1]; 
       proc.StartInfo.RedirectStandardError = true; 
       proc.StartInfo.UseShellExecute = false; 
       if (!proc.Start()) { 
         Console.WriteLine ("Error starting"); 
         return; 
       } 
       StreamReader reader = proc.StandardError; 
       string line; 
       while ((line = reader.ReadLine()) != null) { 
         Console.WriteLine (line); 
       } 
       proc.Close(); 
     } 
} 
+0

Ahh ... Próbowałem przekierować do standardowego wyjścia ... nie błędu. Nagle działa: P –

+0

+1: Zrobiłem to samo w Javie i jestem bardzo, bardzo zadowolony z wyników. Jest kilka chwytów: podobnie jak wartość 'time', może być coś w rodzaju 100000000 na wyjściu linii postępu dla pierwszej aktualizacji. Moje jelito mówi, że to wewnętrzna zainicjalizowana wartość. –

+0

Prawdopodobnie tak. Wystarczy użyć wyciągu predykatów, aby wyeliminować wartości powyżej pewnego rozsądnego zakresu. Brudny, ale będzie działał –

6

Istnieje biblioteka wrapper przez FFmpeg dla .NET.

+0

"W chwili obecnej dekodowanie i kodowanie dźwięku są dojrzałe, a możliwości wideo są w fazie rozwoju (obecnie mamy dekodowanie wideo działające, ale bez zsynchronizowanego dźwięku)." Potrzebuję dźwięku działającego poprawnie. –

+0

Wygląda na to, że są na nim, ale nie ma ich jeszcze ... – Abel

+0

Niestety, projekt nie został zaktualizowany od komentarzy powyżej od +2 lat. I nie ma dystrybucji binarnej; musisz sprawdzić kod i zbudować go sam. –

2

Co powiesz na napisanie wrappera C++/CLI wokół natywnego interfejsu ffmpeg, a następnie wywołanie interfejsu wrappera z aplikacji?

+1

Kompilator VC nie obsługuje wielu konstrukcji języka C używanych w ffmpeg. Zespół ffmpeg jest zainteresowany tym, że komuś uda się przenieść kod do VC. –

2

Właśnie znalazłem fflib na sourceforge. Wygląda całkiem obiecująco, ale go nie użyłem.

+0

jakiejkolwiek pełnej próbki? – Kiquenet

Powiązane problemy