2009-11-10 2 views
16

Я хотел бы иметь возможность использовать FFmpeg для преобразования видеофайла из моей программы на C#. Я знаю, что могу просто вызвать команду оболочки, , но есть ли лучший способ?C# и FFmpeg предпочтительно без команд оболочки?

Проблема с вызовом команды через оболочку, я не уверен, что вы можете делать что-то вроде индикатора выполнения и т. Д. ... или не могли бы вы?

Если нет способа, может ли кто-нибудь предложить лучший способ компоновки некоторой структуры для выполнения команд оболочки. Передача одной большой длинной струны очень громоздкая.

+0

Кто-нибудь? C'mon, кто-то, должно быть, использовал ffmpeg с .net –

ответ

33

Вы можете легко реализовать индикатор выполнения, если работает ffmpeg. Выход FFmpeg во время работы что-то вроде:

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

И обновляется ~ два раза в секунду. Вы можете проанализировать эту строку и получить данные, необходимые для отображения прогресса. Когда вы запускаете в командной строке, вы видите только одну строку, постоянно обновляемую, но то, что ffmpeg делает, это написать строку, за которой следует \ r. Вот почему вы не видите несколько строк. Однако при использовании StreamReader.ReadLine() на выходе ошибки программы вы получаете по одной строке для каждого обновления.

Ниже приведен пример кода для чтения. Вам нужно будет игнорировать любую строку, которая не начинается с «рамки», возможно, используйте BeginErrorReadLine() + ErrorDataReceived, если вы хотите, чтобы строки для чтения были асинхронными и т. Д., Но вы получили идею (я ее протестировал):

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 ... Я пытался перенаправить на standardOutput ... а не на ошибку. Это внезапно работает: P –

+0

+1: Я сделал то же самое в Java, и очень, очень доволен результатами. Однако есть несколько уловов: например, значение 'time', может быть чем-то вроде 100000000 int для вывода строки прогресса для первого обновления. Моя кишка говорит, что это внутреннее инициализированное значение. –

+0

Возможно, да. Просто используйте инструкцию predicate для устранения значений выше определенного разумного диапазона. Грязный, но он будет работать –

6

Существует библиотека wrapper над FFmpeg для .NET.

+0

«В настоящее время декодирование и кодирование звука зрелые и видео возможности находятся в разработке (в настоящее время мы работаем с видео декодированием, но без синхронизированного звука)». Мне нужно, чтобы звук работал правильно. –

+0

Звучит для меня, как будто они на нем, но его еще нет ... – Abel

+0

К сожалению, проект не обновлялся с тех пор, как комментарии были выше от +2 лет назад. И нет двоичного распределения; вы должны проверить код и построить его самостоятельно. –

2

Как насчет написания оболочки C++/CLI вокруг собственного интерфейса ffmpeg, а затем вызова интерфейса оболочки из вашего приложения?

+1

Компилятор VC не поддерживает многие конструкции языка Си, используемые в ffmpeg. Команда ffmpeg заинтересована в том, чтобы кто-то преуспел в переносе кода на VC. –

2

Я только что нашел fflib у источникаforge. Выглядит довольно многообещающе, но не использовал его.

+0

любой полный образец? – Kiquenet

Смежные вопросы