Используете FFmpeg в .net? - PullRequest
       12

Используете FFmpeg в .net?

61 голосов
/ 27 марта 2010

Так что я знаю, что это довольно сложная задача, но я хочу написать базовый проигрыватель фильмов / конвертер для 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. Однако, это было довольно много ошибок компиляции. Оказывается, это было написано для моно-компилятора, я попытался скомпилировать его с моно, но не мог понять, как. Затем я начал вручную исправлять ошибки компилятора, но пришел Я подумал, что мне лучше оставить их в покое. Поэтому я отказался от ffmpeg-sharp.

Затем я посмотрел на SharpFFmpeg, и он выглядит так, как я хочу, все функции P / Вызваны для меня. Однако его GPL? И файлы AVCodec.cs, и AVFormat.cs выглядят как порты avcodec.c и avformat.c, которые, как я считаю, я мог бы портировать сам? Тогда не нужно беспокоиться о лицензировании.

Но я хочу сделать это правильно, прежде чем я начну писать код. Должен ли я:

  1. Напишите мою собственную библиотеку C ++ для взаимодействия с ffmpeg, затем попросите мою программу C # общаться с библиотекой C ++ для воспроизведения / конвертации видео и т. Д.

OR

  1. Перенесите avcodec.h и avformat.h (это все, что мне нужно?) На c #, используя множество DllImports, и запишите его полностью на C #?

Прежде всего, учтите, что я не очень хорош в C ++, так как редко использую его, но знаю достаточно, чтобы обойти его. Причина, по которой я думаю, что № 1 может быть лучшим вариантом, заключается в том, что большинство учебных пособий по FFmpeg написаны на C ++, и я бы также имел больший контроль над управлением памятью, чем если бы я делал это в c #.

Что вы думаете? Также есть ли у вас какие-либо полезные ссылки (возможно, учебное пособие) для использования FFmpeg?

Ответы [ 6 ]

29 голосов
/ 15 июня 2015

Первоначальному вопросу уже более 5 лет. В настоящее время существует решение для WinRT от ffmpeg и пример интеграции от Microsoft .

23 голосов
/ 29 марта 2010

несколько других управляемых оболочек для вас, чтобы проверить

Написание собственных оболочек взаимодействия может быть трудоемким и сложным процессом в .NET. Есть несколько преимуществ написания библиотеки C ++ для взаимодействия - особенно потому, что она позволяет значительно упростить интерфейс, который код на C #. Однако, если вам нужна только часть библиотеки, это может упростить вашу жизнь, просто сделав взаимодействие в C #.

5 голосов
/ 27 сентября 2017

Вы можете использовать этот пакет nuget:

Install-Package Xabe.FFmpeg

Я пытаюсь сделать простой в использовании кроссплатформенный упаковщик FFmpeg.

Вы можете найти больше информации об этом в Xabe.FFmpeg

Подробнее в документации

Преобразование простое:

IConversionResult result = await Conversion.ToMp4(Resources.MkvWithAudio, output).Start();
5 голосов
/ 08 сентября 2013

GPL-скомпилированный ffmpeg можно использовать из не-GPL программы (коммерческий проект), только если он вызывается в отдельном процессе как утилита командной строки; все оболочки, связанные с библиотекой ffmpeg (включая Microsoft FFMpegInterop), могут использовать только сборку LGPL ffmpeg.

Вы можете попробовать мою оболочку .NET для FFMpeg: Video Converter for .NET (я являюсь автором этой библиотеки). Он встраивает FFMpeg.exe в DLL для простоты развертывания и не нарушает правила GPL (FFMpeg НЕ связан и обертка вызывает его в отдельном процессе с System.Diagnostics.Process).

2 голосов
/ 15 июля 2016

Решение, приемлемое как для Linux, так и для Windows, состоит в том, чтобы просто привыкнуть к использованию консоли ffmpeg в своем коде. Я складываю потоки, пишу простой класс контроллера потоков, и вы можете легко использовать все функции ffmpeg, которые вы хотите использовать.

В качестве примера, здесь содержатся разделы, использующие ffmpeg для создания миниатюры в указанное мной время.

В контроллере потоков у вас есть что-то вроде

List<ThrdFfmpeg> threads = new List<ThrdFfmpeg>();

Какой список потоков вы используете, я использую таймер для Pole этих потоков, вы также можете настроить событие, если Pole'ing не подходит для вашего приложения. В этом случае ththffmpeg содержит,

public class ThrdFfmpeg
{
    public FfmpegStuff ffm { get; set; }
    public Thread thrd { get; set; }
}

FFmpegStuff содержит различные функции ffmpeg, очевидно, thrd - это поток.

Свойством в FfmpegStuff является класс FilesToProcess, который используется для передачи информации вызываемому процессу и получения информации после остановки потока.

public class FileToProcess
{
    public int videoID { get; set; }
    public string fname { get; set; }
    public int durationSeconds { get; set; }
    public List<string> imgFiles { get; set; }
}

VideoID (я использую базу данных) сообщает многопоточному процессу, какое видео использовать, взятое из базы данных. fname используется в других частях моих функций, которые используют FilesToProcess, но не используются здесь. durationSeconds - заполняется потоками, которые просто собирают продолжительность видео. imgFiles используется для возврата созданных миниатюр.

Я не хочу зацикливаться на своем коде, когда целью этого является поощрение использования ffmpeg в легко контролируемых потоках.

Теперь у нас есть части, которые мы можем добавить в наш список потоков, поэтому в нашем контроллере мы делаем что-то вроде

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

Теперь поляризация наших потоков становится простой задачей,

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

Помещение ваших собственных событий в класс контроллера работает хорошо, но в работе с видео, когда мой собственный код фактически не выполняет никакой обработки видеофайла, опрос, а затем вызов события в управляющем классе работает также хорошо.

Используя этот метод, я постепенно создавал практически все функции видео и фотографий, которые, как мне кажется, я буду когда-либо использовать, все они содержатся в одном классе, и этот класс в качестве текстового файла можно использовать в версиях Lunux и Windows, используя только небольшое количество директив предварительной обработки.

2 голосов
/ 03 июня 2010

Вы можете попробовать простую оболочку ffmpeg .NET здесь: http://ivolo.mit.edu/post/Convert-Audio-Video-to-Any-Format-using-C.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...