Использование FFmpeg в .net?
Поэтому я знаю, что это довольно сложная задача, но я хочу написать базовый проигрыватель фильмов / конвертер в c #, используя библиотеку FFmpeg. Однако первым препятствием, которое мне нужно преодолеть, является обертывание библиотеки FFmpeg в c #. Я загрузил ffmpeg, но не смог скомпилировать его в Windows, поэтому я загрузил предварительно скомпилированную версию для меня. Отлично. Затем я начал искать обертки C #.
Я осмотрел и нашел несколько оберток, таких как SharpFFmpeg ( http://sourceforge.net/projects/sharpffmpeg/ ) и ffmpeg-sharp ( http://code.google.com/p/ffmpeg-sharp/ ). Прежде всего, я хотел использовать ffmpeg-sharp, поскольку LGPL и SharpFFmpeg – это GPL. Однако в нем было довольно много ошибок компиляции. Оказывается, это было написано для monoкомпилятора, я попытался скомпилировать его с mono, но не мог понять, как это сделать. Затем я начал вручную исправлять compiler errors, но натолкнулся на несколько страшных и подумал, что лучше оставить их в покое. Поэтому я отказался от ffmpeg-sharp.
Затем я посмотрел на SharpFFmpeg, и похоже, что я хочу, все функции P / Invoked для меня. Однако его GPL? Оба файла AVCodec.cs и AVFormat.cs выглядят как порты avcodec.c и avformat.c, которые, как я полагаю, я мог бы портировать? Тогда не нужно беспокоиться о лицензировании.
- Поддержка видео в IE9 HTML5
- Есть ли способ заставить FFmpeg быстрее искать конец файла в сетевом ресурсе?
- Как использовать эффект медленного движения в определенный интервал времени с помощью ffmpeg
- Как создать несжатый AVI из серии 1000 изображений PNG с использованием FFMPEG
- Программное обеспечение для записи веб-камер Windows 7
Но я хочу получить это право, прежде чем идти вперед и начинать кодирование. Нужно ли мне:
- Напишите мою собственную библиотеку C ++ для взаимодействия с ffmpeg, затем попросите мою программу C # поговорить с библиотекой C ++, чтобы воспроизводить / конвертировать видео и т. Д.
ИЛИ
- Порт avcodec.h и avformat.h (это все, что мне нужно?) До c #, используя множество DllImports и полностью записывая его на C #?
Прежде всего, подумайте, что я не очень хорош на C ++, поскольку я редко использую его, но я знаю достаточно, чтобы обойти. Причина, по которой я думаю, что № 1 может быть лучшим вариантом, заключается в том, что большинство учебников FFmpeg находятся на C ++, и у меня также будет больше контроля над управлением памятью, чем если бы я сделал это в c #.
Как вы думаете? Также у вас возникнут какие-либо полезные ссылки (возможно, учебник) для использования FFmpeg?
- Как передать статический видеофайл
- Добавление других видеокодеков / DVD-поддержки в JavaFX 2.2
- Добавьте водяной знак в видео после объединения видео и аудио активов в один из Swift3 iOS
- Есть ли способ посмотреть Netflix на Linux?
- Play Youtube HTML5 встроенное видео в Android WebView
- Ограничьте вывод видео в секцию дисплея и оставите пустой
- Программное обеспечение для редактирования видео для Mac OS X
- Последовательность изображений для видеоstreamа?
Первоначальный вопрос сейчас более 5 лет. Тем временем теперь есть решение для решения WinRT от ffmpeg и образца интеграции от Microsoft .
несколько других управляемых оберток для вас, чтобы проверить
- FFMpeg.NET
- FFMpeg-Sharp
- FFLib.NET
Написание собственных оберток для взаимодействия может быть трудоемким и сложным процессом в .NET. Есть несколько преимуществ для написания библиотеки C ++ для взаимодействия, в частности, поскольку это позволяет значительно упростить интерфейс, который является кодом C #. Однако, если вам нужно только подмножество библиотеки, это может сделать вашу жизнь проще, просто перейдя на C #.
GPL-скомпилированный ffmpeg может использоваться из программы, отличной от GPL (коммерческий проект), только если он вызывается в отдельном процессе как утилита командной строки; все обертки, связанные с библиотекой ffmpeg (включая Microsoft FFMpegInterop), могут использовать только сборку LGPL из ffmpeg.
Вы можете попробовать мою .NET-оболочку для FFMpeg: Video Converter для .NET (я являюсь автором этой библиотеки). Он внедряет FFMpeg.exe в DLL для легкого развертывания и не нарушает правила GPL (FFMpeg НЕ связан, и обертка вызывает его в отдельном процессе с помощью System.Diagnostics.Process).
Вы можете использовать этот пакет nuget:
Install-Package Xabe.FFmpeg
Я пытаюсь сделать простую в использовании кросс-платформенную упаковку FFmpeg.
Дополнительную информацию об этом можно найти на сайте Xabe.FFmpeg
Дополнительная информация в документации
Конверсия проста:
IConversionResult result = await Conversion.ToMp4(Resources.MkvWithAudio, output).Start();
Вы можете попробовать простой ffmpeg wrapper .NET отсюда: http://ivolo.mit.edu/post/Convert-Audio-Video-to-Any-Format-using-C.aspx
Решение, жизнеспособное для Linux и Windows, – это просто использовать консольный ffmpeg в вашем коде. Я складываю streamи, пишу простой class controllerа streamов, тогда вы можете легко использовать все функциональные возможности ffmpeg, которые хотите использовать.
Например, в этом разделе используются ffmpeg, чтобы создать эскиз с того времени, которое я укажу.
В controllerе streamа у вас есть что-то вроде
List threads = new List ();
Какой список streamов вы используете, я использую таймер для полюса этих streamов, вы также можете настроить событие, если Pole’ing не подходит для вашего приложения. В этом случае class Thrdffmpeg содержит,
public class ThrdFfmpeg { public FfmpegStuff ffm { get; set; } public Thread thrd { get; set; } }
FFmpegStuff содержит различные функциональные возможности ffmpeg, thrd – это, очевидно, stream.
Свойством в FfmpegStuff является class FilesToProcess, который используется для передачи информации вызываемому процессу и получения информации после прекращения streamа.
public class FileToProcess { public int videoID { get; set; } public string fname { get; set; } public int durationSeconds { get; set; } public List imgFiles { get; set; } }
VideoID (я использую базу данных) сообщает streamовому процессу, какое видео использовать, взятое из базы данных. fname используется в других частях моих функций, которые используют FilesToProcess, но не используются здесь. durationSeconds – заполняется streamами, которые просто собирают продолжительность видео. imgFiles используется для возврата созданных эскизов.
Я не хочу увязнуть в своем коде, когда целью этого является поощрение использования ffmpeg в легко контролируемых streamах.
Теперь у нас есть наши части, которые мы можем добавить в наш список тем, поэтому в нашем controllerе мы делаем что-то вроде:
AddThread() { ThrdFfmpeg thrd; FileToProcess ftp; foreach(FileToProcess ff in `dbhelper.GetFileNames(txtCategory.Text))` { //make a thread for each ftp = new FileToProcess(); ftp = ff; ftp.imgFiles = new List(); thrd = new ThrdFfmpeg(); thrd.ffm = new FfmpegStuff(); thrd.ffm.filetoprocess = ftp; thrd.thrd = new `System.Threading.Thread(thrd.ffm.CollectVideoLength);` threads.Add(thrd); } if(timerNotStarted) StartThreadTimer(); }
Теперь Pole’ing наших streamов становится простой задачей,
private void timerThreads_Tick(object sender, EventArgs e) { int runningCount = 0; int finishedThreads = 0; foreach(ThrdFfmpeg thrd in threads) { switch (thrd.thrd.ThreadState) { case System.Threading.ThreadState.Running: ++runningCount; //Note that you can still view data progress here, //but remember that you must use your safety checks //here more than anywhere else in your code, make sure the data //is readable and of the right sort, before you read it. break; case System.Threading.ThreadState.StopRequested: break; case System.Threading.ThreadState.SuspendRequested: break; case System.Threading.ThreadState.Background: break; case System.Threading.ThreadState.Unstarted: //Any threads that have been added but not yet started, start now thrd.thrd.Start(); ++runningCount; break; case System.Threading.ThreadState.Stopped: ++finishedThreads; //You can now safely read the results, in this case the //data contained in FilesToProcess //Such as ThumbnailsReadyEvent( thrd.ffm ); break; case System.Threading.ThreadState.WaitSleepJoin: break; case System.Threading.ThreadState.Suspended: break; case System.Threading.ThreadState.AbortRequested: break; case System.Threading.ThreadState.Aborted: break; default: break; } } if(flash) {//just a simple indicator so that I can see //that at least one thread is still running lbThreadStatus.BackColor = Color.White; flash = false; } else { lbThreadStatus.BackColor = this.BackColor; flash = true; } if(finishedThreads >= threads.Count()) { StopThreadTimer(); ShowSample(); MakeJoinedThumb(); } }
Ввод ваших собственных событий в class controllerа работает хорошо, но при работе с видео, когда мой собственный код на самом деле не выполняет какую-либо обработку видеофайлов, также работает полирование, а затем вызов события в контрольном classе.
Используя этот метод, я медленно создавал практически все функции видео и неподвижных изображений, которые, я думаю, когда-либо буду использовать, все они содержатся в одном classе, и этот class как текстовый файл можно использовать в версиях Lunux и Windows с небольшим числом предпродажных директив.