Solider FFmpeg-Wrapper für C # /. NET

88

Ich habe einige Zeit im Internet nach einem soliden FFmpeg- Wrapper für C # /. NET gesucht . Aber ich habe noch nichts Nützliches gefunden. Ich habe die folgenden drei Projekte gefunden, aber alle scheinen im frühen Alpha-Stadium tot zu sein.

FFmpeg.NET
ffmpeg-scharfes
FFLIB.NET

Meine Frage ist also, ob jemand von einem Wrapper-Projekt weiß, das ausgereifter ist?
Ich suche keine vollständige Transcodierungs-Engine mit Job-Warteschlangen und mehr. Nur ein einfacher Wrapper, damit ich keinen Befehlszeilenaufruf ausführen und dann die Konsolenausgabe analysieren muss, sondern Methodenaufrufe ausführen und Ereignislistener für den Fortschritt verwenden kann.

Und bitte zögern Sie nicht, aktive Projekte zu erwähnen, auch wenn diese noch im Anfangsstadium sind.

Jacob Poul Richardt
quelle
1
Mögliches Duplikat von Kennt jemand eine Reihe von C # -Bindungen für FFMPEG?
Paŭlo Ebermann
1
Etwas Neues dabei? Hat Ihr Wrapper Fortschritte gemacht?
Avi
1
Bitte folgen Sie und überprüfen Sie Ihre E-Mail- Adresse , um Ihre Stimme für eine neue FFmpeg-Q & A-Site auf SE abzugeben. Vielen Dank!
Shimmy Weitzhandler
3
@Lillemanden hast du jemals deinen Wrapper veröffentlicht oder Open Source?
Nick Benedict
Interessant, dass die Frage fast 6 Jahre alt ist, aber das OP (@JacobPoulRichardt) keine der Antworten akzeptiert hat.
Ofer Zelig

Antworten:

23

Dies ist ein eigener Wrapper: https://github.com/AydinAdn/MediaToolkit

MediaToolkit kann:

  • Konvertieren Sie Videodateien in verschiedene andere Videoformate.
  • Führen Sie Video-Transcodierungsaufgaben aus.
    • Optionen konfigurierbar: Bit rate, Frame rate, Resolution / size, Aspect ratio,Duration of video
  • Führen Sie Audio-Transcodierungsaufgaben aus.
    • Optionen konfigurierbar: Audio sample rate
  • Konvertieren Sie Videos mit FILM-, PAL- oder NTSC-TV-Standards in physische Formate
    • Medien umfassen: DVD, DV, DV50, VCD,SVCD

Ich aktualisiere es im Laufe der Zeit und Sie können es gerne verwenden. Sie können es auch über die Package Manager-Konsole installieren.

PM> Install-Package MediaToolkit
Aydin
quelle
Kann Ihr Toolkit verschiedene Video- und Audioclips in einer bestimmten Ausgabeauflösung muxen / rendern?
Antonio Petricca
Nein, es wurde für Leute entwickelt, die einfache Konvertierungen verfolgen. Das heißt, es gibt ziemlich bald v2, mit dem Sie alles tun können, was FFmpeg zu bieten hat.
Aydin
Vielen Dank, Aydin. Bitte halten Sie mich über diese neue Version auf dem Laufenden.
Antonio Petricca
Sieht fabelhaft aus! Gute Arbeit bisher!
SpoiledTechie.com
Hey Aydin, kann das auch den Bildschirm aufnehmen?
TEK
13

Nachdem ich mehrere Wrapper ausprobiert hatte, ging ich folgendermaßen vor: FFmpeg erzeugte automatisch unsichere Bindungen für C # /. NET und Mono .

Es handelt sich um eine Reihe von Interop-Bindungen auf niedriger Ebene für jede Klasse im FFmpeg-Namespace. Vielleicht nicht so bequem zu verwenden wie ein tatsächlicher Wrapper, aber IMO ist die beste Lösung für die Arbeit mit FFmpeg in .Net, wenn Sie nicht triviale Dinge tun möchten.

Vorteile:

  • Funktioniert
  • Vertrauenswürdig - kein Wrapper-Code von Drittanbietern, der Fehler verursacht, vorausgesetzt, Sie vertrauen FFMpeg selbst.
  • Es wird immer auf die neueste Version von FFmpeg aktualisiert
  • Einzelne Nuget-Packung für alle Bindungen
  • XML-Dokumentation ist enthalten, Sie können jedoch weiterhin die FFmpeg-Dokumentation zur Online- Dokumentation verwenden .

Nachteile:

  • Niedrige Ebene: Sie müssen wissen, wie man mit Zeigern auf c-Strukturen arbeitet .
  • Benötigt zunächst einige Arbeit, um es zum Laufen zu bringen. Ich schlage vor, aus den offiziellen Beispielen zu lernen .

Hinweis: In diesem Thread geht es um die Verwendung der FFmpeg-API. In einigen Anwendungsfällen ist es jedoch am besten, einfach die Befehlszeilenschnittstelle von ffmpeg.exe zu verwenden .

Orca
quelle
Haben Sie es geschafft, es aus einem Projekt heraus zu verwenden, das auf .Net Framework (nicht Core) ausgerichtet ist? Ich bin nicht sicher, was ich hier vermisse
Yoav Feuerstein
@ YoavFeuerstein Ja.
Orca
10

Ich habe FFmpeg aus einer ASP.NET / Windows-Dienstanwendung (.NET) verwendet. Am Ende habe ich jedoch die Befehlszeile verwendet, ohne die Konsole zu analysieren. Auf diese Weise hatte ich eine einfache Möglichkeit, Updates von FFmpeg zu steuern und mehrere Konvertierungen auf mehreren Kernen auszuführen.

Famdam
quelle
Ok, ich habe mit etwas Ähnlichem angefangen. Aber ich hoffe immer noch, dass jemand eine bessere Lösung hat.
Jacob Poul Richardt
4

Sie können dieses Nuget-Paket verwenden:

Ich weiß, dass Sie nach einem ausgereiften Projekt gefragt haben, aber ich habe kein Projekt gesehen, das meine Erwartungen erfüllt, also habe ich beschlossen, mein eigenes zu machen. Sie können Konvertierungen einfach in die Warteschlange stellen und parallel ausführen, Methoden zum Konvertieren von Medien in verschiedene Formate, Senden Ihrer eigenen Argumente an ffmpeg und Analysieren der Ausgabe von ffmpeg + Ereignis-Listener mit dem aktuellen Fortschritt.

Install-Package Xabe.FFmpeg

Ich versuche, einen benutzerfreundlichen, plattformübergreifenden FFmpeg-Wrapper zu erstellen.

Weitere Informationen hierzu finden Sie unter https://xabe.net/product/xabe_ffmpeg/

Mehr Infos hier: https://xabe.net/product/xabe_ffmpeg/#documentation

Die Konvertierung ist einfach:

IConversionResult result = await Conversion.ToMp4(Resources.MkvWithAudio, output).Start();

Wenn Sie Fortschritte wollen:

IConversion conversion = Conversion.ToMp4(Resources.MkvWithAudio, output);
conversion.OnProgress += (duration, length) => { currentProgress = duration; } 
await conversion.Start();
Tomasz Żmuda
quelle
3

Ich spiele mit einer ffmpeg-Wrapper-Bibliothek namens MediaHandler Pro aus

http://www.mediasoftpro.com

scheint bisher vielversprechend.

Christophe Chang
quelle
Wie hat das für Sie geklappt? Auch dann , wenn MediaHandlerlaichen ffmpeg.exeals Prozess seine Arbeit zu tun, oder ist es eine tatsächliche P / Invoke - Bibliothek?
Glenn Slayden
Ich habe es in einigen Projekten verwendet. Es funktionierte gut in einer Produktionsumgebung unter hoher Last. Es ist schon eine Weile her, seit ich es benutzt habe, aber soweit ich mich erinnere, erzeugt es ffmpeg.exe als Prozess.
Christophe Chang
3

Ich habe das Gleiche recherchiert und ursprünglich MediaToolKit (in einer anderen Antwort erwähnt) verwendet, das sich hervorragend für Conversions eignet, aber jetzt brauche ich etwas Robusteres.

Eine Option, die ausgereift und noch aktiv zu sein scheint, ist: https://github.com/hudl/HudlFfmpeg Über die Sie hier mehr lesen können: http://public.hudl.com/bits/archives/2014/08/15/announcing -hudlffmpeg-ac-Framework-zu-machen-ffmpeg-Interaktion-einfach /

Eine andere Option, die möglicherweise nicht für viele Fälle geeignet ist, besteht darin, die Exe direkt von Ihrem c # -Code aus aufzurufen: http://www.codeproject.com/Articles/774093/Another-FFmpeg-exe-Csharp-Wrapper

Ickydime
quelle
2

Hier gibt es noch eine einfache: http://ivolo.mit.edu/post/Metamorph-Convert-Audio-Video-to-Any-Format-on-Windows-Linux-and-Mac.aspx

Ilya
quelle
1
Vielen Dank für den Link, aber soweit ich sehen kann, haben Sie Ihren in Java geschrieben, nicht in C #.
Jacob Poul Richardt
Hallo lillemanden, der Link, den ich gegeben habe, ist tatsächlich in Java implementiert. Wenn Sie die Zip-Datei am Ende des Artikels herunterladen, werden Sie feststellen, dass sich darin eine JAR-Archivdatei befindet. Danke, Ilya
Ilya
Der Link in der Antwort scheint tot zu sein: "Diese Seite kann nicht erreicht werden - ivolo.mit.edu hat zu lange gebraucht, um zu antworten."
Pang
2

Los geht's ... Der größte Teil dieses Codes ist 2+ Jahre alt, daher fehlen viele asynchrone Dinge und es wird eine veraltete Namenskonvention verwendet. Läuft seit geraumer Zeit in einer Produktionsumgebung ~ JT

internal static class FFMpegArgUtils
    {
        public static string GetEncodeVideoFFMpegArgs(string sSourceFile, MP4Info objMp4Info, double nMbps, int iWidth, int iHeight, bool bIncludeAudio, string sOutputFile)
        {
            //Ensure file contains a video stream, otherwise this command will fail
            if (objMp4Info != null && objMp4Info.VideoStreamCount == 0)
            {
                throw new Exception("FFMpegArgUtils::GetEncodeVideoFFMpegArgs - mp4 does not contain a video stream");
            }

            int iBitRateInKbps = (int)(nMbps * 1000);


            StringBuilder sbArgs = new StringBuilder();
            sbArgs.Append(" -y -threads 2 -i \"" + sSourceFile + "\" -strict -2 "); // 0 tells it to choose how many threads to use

            if (bIncludeAudio == true)
            {
                //sbArgs.Append(" -acodec libmp3lame -ab 96k");
                sbArgs.Append(" -acodec aac -ar 44100 -ab 96k");
            }
            else
            {
                sbArgs.Append(" -an");
            }


            sbArgs.Append(" -vcodec libx264 -level 41 -r 15 -crf 25 -g 15  -keyint_min 45 -bf 0");

            //sbArgs.Append(" -vf pad=" + iWidth + ":" + iHeight + ":" + iVideoOffsetX + ":" + iVideoOffsetY);
            sbArgs.Append(String.Format(" -vf \"scale=iw*min({0}/iw\\,{1}/ih):ih*min({0}/iw\\,{1}/ih),pad={0}:{1}:({0}-iw)/2:({1}-ih)/2\"",iWidth, iHeight));

            //Output File
            sbArgs.Append(" \"" + sOutputFile + "\"");
            return sbArgs.ToString();
        }

        public static string GetEncodeAudioFFMpegArgs(string sSourceFile, string sOutputFile)
        {
            var args = String.Format(" -y -threads 2 -i \"{0}\" -strict -2  -acodec aac -ar 44100 -ab 96k -vn \"{1}\"", sSourceFile, sOutputFile);
            return args;


            //return GetEncodeVideoFFMpegArgs(sSourceFile, null, .2, 854, 480, true, sOutputFile);
            //StringBuilder sbArgs = new StringBuilder();
            //int iWidth = 854;
            //int iHeight = 480;
            //sbArgs.Append(" -y -i \"" + sSourceFile + "\" -strict -2 "); // 0 tells it to choose how many threads to use
            //sbArgs.Append(" -acodec aac -ar 44100 -ab 96k");
            //sbArgs.Append(" -vcodec libx264 -level 41 -r 15 -crf 25 -g 15  -keyint_min 45 -bf 0");
            //sbArgs.Append(String.Format(" -vf \"scale=iw*min({0}/iw\\,{1}/ih):ih*min({0}/iw\\,{1}/ih),pad={0}:{1}:({0}-iw)/2:({1}-ih)/2\"", iWidth, iHeight));
            //sbArgs.Append(" \"" + sOutputFile + "\"");
            //return sbArgs.ToString();
        }
    }

internal class CreateEncodedVideoCommand : ConsoleCommandBase
    {
        public event ProgressEventHandler OnProgressEvent;

        private string _sSourceFile;
        private  string _sOutputFolder;
        private double _nMaxMbps;

        public double BitrateInMbps
        {
            get { return _nMaxMbps; }
        }

        public int BitrateInKbps
        {
            get { return (int)Math.Round(_nMaxMbps * 1000); }
        }

        private int _iOutputWidth;
        private int _iOutputHeight;

        private bool _bIsConverting = false;
        //private TimeSpan _tsDuration;
        private double _nPercentageComplete;
        private string _sOutputFile;
        private string _sOutputFileName;


        private bool _bAudioEnabled = true;
        private string _sFFMpegPath;
        private string _sExePath;
        private string _sArgs;
        private MP4Info _objSourceInfo;
        private string _sOutputExt;

        /// <summary>
        /// Encodes an MP4 to the specs provided, quality is a value from 0 to 1
        /// </summary>
        /// <param name="nQuality">A value from 0 to 1</param>
        /// 
        public CreateEncodedVideoCommand(string sSourceFile, string sOutputFolder, string sFFMpegPath, double nMaxBitrateInMbps, MP4Info objSourceInfo, int iOutputWidth, int iOutputHeight, string sOutputExt)
        {
            _sSourceFile = sSourceFile;
            _sOutputFolder = sOutputFolder;
            _nMaxMbps = nMaxBitrateInMbps;
            _objSourceInfo = objSourceInfo;
            _iOutputWidth = iOutputWidth;
            _iOutputHeight = iOutputHeight;
            _sFFMpegPath = sFFMpegPath;
            _sOutputExt = sOutputExt;
        }

        public void SetOutputFileName(string sOutputFileName)
        {
            _sOutputFileName = sOutputFileName;
        }


        public override void Execute()
        {
            try
            {
                _bIsConverting = false;

                string sFileName = _sOutputFileName != null ? _sOutputFileName : Path.GetFileNameWithoutExtension(_sSourceFile) + "_" + _iOutputWidth + "." + _sOutputExt;
                _sOutputFile = _sOutputFolder + "\\" + sFileName;

                _sExePath = _sFFMpegPath;
                _sArgs = FFMpegArgUtils.GetEncodeVideoFFMpegArgs(_sSourceFile, _objSourceInfo,_nMaxMbps, _iOutputWidth, _iOutputHeight, _bAudioEnabled, _sOutputFile);

                InternalExecute(_sExePath, _sArgs);
            }
            catch (Exception objEx)
            {
                DispatchException(objEx);
            }
        }

        public override string GetCommandInfo()
        {
            StringBuilder sbInfo = new StringBuilder();
            sbInfo.AppendLine("CreateEncodeVideoCommand");
            sbInfo.AppendLine("Exe: " + _sExePath);
            sbInfo.AppendLine("Args: " + _sArgs);
            sbInfo.AppendLine("[ConsoleOutput]");
            sbInfo.Append(ConsoleOutput);
            sbInfo.AppendLine("[ErrorOutput]");
            sbInfo.Append(ErrorOutput);

            return base.GetCommandInfo() + "\n" + sbInfo.ToString();
        }

        protected override void OnInternalCommandComplete(int iExitCode)
        {
            DispatchCommandComplete( iExitCode == 0 ? CommandResultType.Success : CommandResultType.Fail);
        }

        override protected void OnOutputRecieved(object sender, ProcessOutputEventArgs objArgs)
        {
            //FMPEG out always shows as Error
            base.OnOutputRecieved(sender, objArgs);

            if (_bIsConverting == false && objArgs.Data.StartsWith("Press [q] to stop encoding") == true)
            {
                _bIsConverting = true;
            }
            else if (_bIsConverting == true && objArgs.Data.StartsWith("frame=") == true)
            {
                //Capture Progress
                UpdateProgressFromOutputLine(objArgs.Data);
            }
            else if (_bIsConverting == true && _nPercentageComplete > .8 && objArgs.Data.StartsWith("frame=") == false)
            {
                UpdateProgress(1);
                _bIsConverting = false;
            }
        }

        override protected void OnProcessExit(object sender, ProcessExitedEventArgs args)
        {
            _bIsConverting = false;
            base.OnProcessExit(sender, args);
        }

        override public void Abort()
        {
            if (_objCurrentProcessRunner != null)
            {
                //_objCurrentProcessRunner.SendLineToInputStream("q");
                _objCurrentProcessRunner.Dispose();
            }
        }

        #region Helpers

        //private void CaptureSourceDetailsFromOutput()
        //{
        //    String sInputStreamInfoStartLine = _colErrorLines.SingleOrDefault(o => o.StartsWith("Input #0"));
        //    int iStreamInfoStartIndex = _colErrorLines.IndexOf(sInputStreamInfoStartLine);
        //    if (iStreamInfoStartIndex >= 0)
        //    {
        //        string sDurationInfoLine = _colErrorLines[iStreamInfoStartIndex + 1];
        //        string sDurantionTime = sDurationInfoLine.Substring(12, 11);

        //        _tsDuration = VideoUtils.GetDurationFromFFMpegDurationString(sDurantionTime);
        //    }
        //}

        private void UpdateProgressFromOutputLine(string sOutputLine)
        {
            int iTimeIndex = sOutputLine.IndexOf("time=");
            int iBitrateIndex = sOutputLine.IndexOf(" bitrate=");

            string sCurrentTime = sOutputLine.Substring(iTimeIndex + 5, iBitrateIndex - iTimeIndex - 5);
            double nCurrentTimeInSeconds = double.Parse(sCurrentTime);
            double nPercentageComplete = nCurrentTimeInSeconds / _objSourceInfo.Duration.TotalSeconds;

            UpdateProgress(nPercentageComplete);
            //Console.WriteLine("Progress: " + _nPercentageComplete);
        }

        private void UpdateProgress(double nPercentageComplete)
        {
            _nPercentageComplete = nPercentageComplete;
            if (OnProgressEvent != null)
            {
                OnProgressEvent(this, new ProgressEventArgs( _nPercentageComplete));
            }
        }

        #endregion

        //public TimeSpan Duration { get { return _tsDuration; } }

        public double Progress { get { return _nPercentageComplete;  } }
        public string OutputFile { get { return _sOutputFile; } }

        public bool AudioEnabled
        {
            get { return _bAudioEnabled; }
            set { _bAudioEnabled = value; }
        }
}

public abstract class ConsoleCommandBase : CommandBase, ICommand
    {
        protected ProcessRunner _objCurrentProcessRunner;
        protected   List<String> _colOutputLines;
        protected List<String> _colErrorLines;


        private int _iExitCode;

        public ConsoleCommandBase()
        {
            _colOutputLines = new List<string>();
            _colErrorLines = new List<string>();
        }

        protected void InternalExecute(string sExePath, string sArgs)
        {
            InternalExecute(sExePath, sArgs, null, null, null);
        }

        protected void InternalExecute(string sExePath, string sArgs, string sDomain, string sUsername, string sPassword)
        {
            try
            {
                if (_objCurrentProcessRunner == null || _bIsRunning == false)
                {
                    StringReader objStringReader = new StringReader(string.Empty);

                    _objCurrentProcessRunner = new ProcessRunner(sExePath, sArgs);

                    _objCurrentProcessRunner.SetCredentials(sDomain, sUsername, sPassword);

                    _objCurrentProcessRunner.OutputReceived += new ProcessOutputEventHandler(OnOutputRecieved);
                    _objCurrentProcessRunner.ProcessExited += new ProcessExitedEventHandler(OnProcessExit);
                    _objCurrentProcessRunner.Run();

                    _bIsRunning = true;
                    _bIsComplete = false;
                }
                else
                {
                    DispatchException(new Exception("Processor Already Running"));
                }
            }
            catch (Exception objEx)
            {
                DispatchException(objEx);
            }
        }

        protected virtual void OnOutputRecieved(object sender, ProcessOutputEventArgs args)
        {
            try
            {
                if (args.Error == true)
                {
                    _colErrorLines.Add(args.Data);
                    //Console.WriteLine("Error: " + args.Data);
                }
                else
                {
                    _colOutputLines.Add(args.Data);
                    //Console.WriteLine(args.Data);
                }
            }
            catch (Exception objEx)
            {
                DispatchException(objEx);
            }
        }

        protected virtual void OnProcessExit(object sender, ProcessExitedEventArgs args)
        {
            try
            {
                Console.Write(ConsoleOutput);
                _iExitCode = args.ExitCode;

                _bIsRunning = false;
                _bIsComplete = true;

                //Some commands actually fail to succeed
                //if(args.ExitCode != 0)
                //{
                //    DispatchException(new Exception("Command Failed: " + this.GetType().Name + "\nConsole: " + ConsoleOutput + "\nConsoleError: " + ErrorOutput));
                //}

                OnInternalCommandComplete(_iExitCode);

                if (_objCurrentProcessRunner != null)
                {
                    _objCurrentProcessRunner.Dispose();
                    _objCurrentProcessRunner = null;    
                }
            }
            catch (Exception objEx)
            {
                DispatchException(objEx);
            }
        }

        abstract protected void OnInternalCommandComplete(int iExitCode);

        protected string JoinLines(List<String> colLines)
        {
            StringBuilder sbOutput = new StringBuilder();
            colLines.ForEach( o => sbOutput.AppendLine(o));
            return sbOutput.ToString();
        }

        #region Properties
        public int ExitCode
        {
            get { return _iExitCode; }
        }
        #endregion

        public override string GetCommandInfo()
        {
            StringBuilder sbCommandInfo = new StringBuilder();
            sbCommandInfo.AppendLine("Command:  " + this.GetType().Name);
            sbCommandInfo.AppendLine("Console Output");
            if (_colOutputLines != null)
            {
                foreach (string sOutputLine in _colOutputLines)
                {
                    sbCommandInfo.AppendLine("\t" + sOutputLine);
                }
            }
            sbCommandInfo.AppendLine("Error Output");
            if (_colErrorLines != null)
            {
                foreach (string sErrorLine in _colErrorLines)
                {
                    sbCommandInfo.AppendLine("\t" + sErrorLine);
                }
            }
            return sbCommandInfo.ToString();
        }

        public String ConsoleOutput { get { return JoinLines(_colOutputLines); } }
        public String ErrorOutput { get { return JoinLines(_colErrorLines);} }

    }

CommandBase : ICommand
    {
        protected IDedooseContext _context;
        protected Boolean _bIsRunning = false;
        protected Boolean _bIsComplete = false;

        #region Custom Events
        public event CommandCompleteEventHandler OnCommandComplete;
        event CommandCompleteEventHandler ICommand.OnCommandComplete
        {
            add { if (OnCommandComplete != null) { lock (OnCommandComplete) { OnCommandComplete += value; } } else { OnCommandComplete = new CommandCompleteEventHandler(value); } }
            remove { if (OnCommandComplete != null) { lock (OnCommandComplete) { OnCommandComplete -= value; } } }
        }

        public event UnhandledExceptionEventHandler OnCommandException;
        event UnhandledExceptionEventHandler ICommand.OnCommandException
        {
            add { if (OnCommandException != null) { lock (OnCommandException) { OnCommandException += value; } } else { OnCommandException = new UnhandledExceptionEventHandler(value); } }
            remove { if (OnCommandException != null) { lock (OnCommandException) { OnCommandException -= value; } } }
        }

        public event ProgressEventHandler OnProgressUpdate;
        event ProgressEventHandler ICommand.OnProgressUpdate
        {
            add { if (OnProgressUpdate != null) { lock (OnProgressUpdate) { OnProgressUpdate += value; } } else { OnProgressUpdate = new ProgressEventHandler(value); } }
            remove { if (OnProgressUpdate != null) { lock (OnProgressUpdate) { OnProgressUpdate -= value; } } }
        }
        #endregion

        protected CommandBase()
        {
            _context = UnityGlobalContainer.Instance.Context;
        }

        protected void DispatchCommandComplete(CommandResultType enResult)
        {
            if (enResult == CommandResultType.Fail)
            {
                StringBuilder sbMessage = new StringBuilder();
                sbMessage.AppendLine("Command Commpleted with Failure: "  + this.GetType().Name);
                sbMessage.Append(GetCommandInfo());
                Exception objEx = new Exception(sbMessage.ToString());
                DispatchException(objEx);
            }
            else
            {
                if (OnCommandComplete != null)
                {
                    OnCommandComplete(this, new CommandCompleteEventArgs(enResult));
                }
            }
        }

        protected void DispatchException(Exception objEx)
        {
            if (OnCommandException != null)
            { 
                OnCommandException(this, new UnhandledExceptionEventArgs(objEx, true)); 
            }
            else
            {
                _context.Logger.LogException(objEx, MethodBase.GetCurrentMethod());
                throw objEx;
            }
        }

        protected void DispatchProgressUpdate(double nProgressRatio)
        {
            if (OnProgressUpdate != null) { OnProgressUpdate(this, new ProgressEventArgs(nProgressRatio)); } 
        }

        public virtual string GetCommandInfo()
        {
            return "Not Implemented: " + this.GetType().Name;
        }

        public virtual void Execute() { throw new NotImplementedException(); }
        public virtual void Abort() { throw new NotImplementedException(); }

        public Boolean IsRunning { get { return _bIsRunning; } }
        public Boolean IsComplete { get { return _bIsComplete; } }

        public double GetProgressRatio()
        {
            throw new NotImplementedException();
        }
    }

public delegate void CommandCompleteEventHandler(object sender, CommandCompleteEventArgs e);

    public interface ICommand
    {
        event CommandCompleteEventHandler OnCommandComplete;
        event UnhandledExceptionEventHandler OnCommandException;
        event ProgressEventHandler OnProgressUpdate;

        double GetProgressRatio();
        string GetCommandInfo();

        void Execute();
        void Abort();
    }

// Für den Prozessläufer suchen Sie nach ProcessRunner von Roger Knapp

JTtheGeek
quelle
1
        string result = String.Empty;
        StreamReader srOutput = null;
        var oInfo = new ProcessStartInfo(exePath, parameters)
        {
            UseShellExecute = false,
            CreateNoWindow = true,
            RedirectStandardOutput = true,
            RedirectStandardError = true
        };

        var output = string.Empty;

        try
        {
            Process process = System.Diagnostics.Process.Start(oInfo);
            output = process.StandardError.ReadToEnd();
            process.WaitForExit();
            process.Close();
        }
        catch (Exception)
        {
            output = string.Empty;
        }
        return output;

Dieser Wrapper lässt die Methode nicht in eine Schleife fallen. Versuchen Sie das, es hat bei mir funktioniert.

Mrinal
quelle
1

Ich habe FFPMEG.net von Codeplex gegabelt.

Wird noch aktiv gearbeitet.

https://github.com/spoiledtechie/FFMpeg.Net

Es werden nicht die DLLs verwendet, sondern die Exe. Es ist also tendenziell stabiler.

SpoiledTechie.com
quelle
Sieht so aus, wie ich es mir vorstelle, aber wie setzt man das in seinem Projekt um?
TEK
Fügen Sie dieses Projekt Ihrem Projekt hinzu und stellen Sie sicher, dass FFMPEG korrekt im Projekt sitzt. Es wird noch daran gearbeitet.
SpoiledTechie.com
Kann ich mit diesem FFMPEG.net einen Frame als Byte [] codieren und decodieren? Beispiel: Byte [] encodeh264 (Byte []) und Byte [] decodeh264 (Byte []).
Ahmad