Solid FFmpeg wrapper for C#/.NET [closed]
Asked Answered
G

12

94

I have been searching the web for some time for a solid FFmpeg wrapper for C#/.NET. But I have yet to come up with something useful. I have found the following three projects, but all of them apears to be dead in early alpha stage.

FFmpeg.NET
ffmpeg-sharp
FFLIB.NET

So my question is if anyone knows of a wrapper project that is more mature?
I am not looking for a full transcoding engine with job queues and more. Just a simple wrapper so I do not have to make a command line call and then parse the console output, but can make method calls and use eventlisteners for progress.

And please feel free to mention any active projects, even if they are stil in the early stages.

Glossolalia answered 29/1, 2010 at 15:44 Comment(3)
possible duplicate of Anyone know of a set of C# bindings for FFMPEG?Km
@Lillemanden did you ever release or open source your wrapper?Granitite
I ended up using a wrapper I made myself, and as such didn't use any of the suggested projects. As I no longer work with ffmpeg, I havn't had the time to go back and try any of them either. But have upvoted most of the answers after skimming them. So I don't really think I can say that any of the answers are more "correct" than the others.Glossolalia
B
26

This is a wrapper of my own: https://github.com/AydinAdn/MediaToolkit

MediaToolkit can:

  • Convert video files into various other video formats.
  • Perform video transcoding tasks.
    • Options configurable: Bit rate, Frame rate, Resolution / size, Aspect ratio, Duration of video
  • Perform audio transcoding tasks.
    • Options configurable: Audio sample rate
  • Convert video to physical formats using FILM, PAL or NTSC tv standards
    • Mediums include: DVD, DV, DV50, VCD, SVCD

I'm updating it as I go along, and you're welcome to use it, you can also install it using the Package Manager Console.

PM> Install-Package MediaToolkit
Breakup answered 5/2, 2014 at 22:0 Comment(9)
Can your toolkit mux/render different video and audio clips into one of a given output resolution?Bin
No, it was designed to be used for people chasing simple conversions. That said, there is v2 coming pretty soon which will allow you to do everything that FFmpeg has to put on offer.Breakup
Thank you Aydin, please keep me informed about this new release.Bin
Looks fabulous! Good job so far!Voltcoulomb
Hey Aydin, can this also record the screen?Jurgen
@Jurgen in short, no. Tldr; i was actually thinking of making an app that you can use to record your screen by tapping the print screen button and then finishing the recording by tapping again and automatically uploading it and returning a url you can share... Anyway if my memory serves me right, ffmpeg does support recording your screen... It just isnt broken out in the wrapperBreakup
@AydinAdn Thank you, Aydin. Looking like I'll have to roll my own! I'll certainly use this as a basis, though. It looks great.Jurgen
Trying this out... fwiw this only works with blobs on the filesystem at a path (which makes sense because so does ffmpeg.exe), but using this in a project that targets runtime 4.5.2 seems to cause compiler warnings about ExtensionAttribute being defined in 2 gac assemblies, one of them being this project, the other being mscorlib.Mcclung
I'd downloaded MediaToolkit source code from git, it works like charm..then i'd tried out to convert rtsp stream to mp4 video and it also works fine for single video...i mean video was built and saved into directory path. Now my requirement is to create multiple videos simultaneously in a loop and it creates multiple videos in directory path but each video contains minimum 1 second gap :( how could i remove that gap, can you please help me ?Pourparler
P
15

After trying several wrappers, I went with this: FFmpeg auto generated unsafe bindings for C#/.NET and Mono.

It's a set of low-level interop bindings for every class in the FFmpeg namespace. Maybe not as convenient to use as an actual wrapper, but IMO it's the best solution for working with FFmpeg in .Net, if you want to do non-trivial things.

Pros:

  • Works
  • Trustworthy - no 3rd party wrapper code to introduce bugs, assuming you trust FFMpeg itself.
  • It's always updated to the latest version of FFmpeg
  • Single nuget package for all of the bindings
  • XML documentation is included but you still can use the online documentation FFmpeg documentation.

Cons:

  • Low level: You have to know how to work with pointers to c structs.
  • Requires some work initially to get it working. I suggest to learn from the official examples.

Note: this thread is about using the FFmpeg API, but for some use cases, it's best to simply use ffmpeg.exe's command line interface.

Pazice answered 19/2, 2015 at 9:16 Comment(2)
Did you manage to use it from a project which is targeted for .Net Framework (not core)? I'm not sure what I'm missing hereWavelet
@YoavFeuerstein Yes.Pazice
D
11

I have used FFmpeg from a ASP.NET / Windows service (.NET) application. But I ended up using the command-line, without parsing the console. By using this - I had an easy way to control - updates of FFmpeg and running multiple conversions on multiple Cores.

Dunseath answered 8/2, 2010 at 21:15 Comment(1)
Ok, I started on something similar. But I am stil hoping someone have a better solution.Glossolalia
T
10

Try this, I think I might have written something you can use for a simple wrapper.

http://jasonjano.wordpress.com/2010/02/09/a-simple-c-wrapper-for-ffmpeg/

Testimonial answered 12/2, 2010 at 23:36 Comment(1)
Thanks, but I started writing my own. But I'll if I can't pick up a few ideas.Glossolalia
L
6

You can use this nuget package:

I know that you asked about mature project, but i haven't seen any project fullfilling my expectaction so i decided to make my own. You can easily queue conversions and run it parallel, methods to convert media to different formats, send your own arguments to ffmpeg and parse output from ffmpeg + event listener with current progress.

Install-Package Xabe.FFmpeg

I'm trying to make easy to use, cross-platform FFmpeg wrapper.

You can find more information about this at https://xabe.net/product/xabe_ffmpeg/

More info here: https://xabe.net/product/xabe_ffmpeg/#documentation

Conversion is simple:

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

If you want progress:

IConversion conversion = Conversion.ToMp4(Resources.MkvWithAudio, output);
conversion.OnProgress += (duration, length) => { currentProgress = duration; } 
await conversion.Start();
Lew answered 27/9, 2017 at 7:42 Comment(1)
Hello... I need to use FFMPEG to transcode an streaming data coming from a web page and send it to a RTMP server. I have the array of bytes in my C# winform program. I only need to transcode and send to the RTMP server. Can I do that using this wrapper? I did this using a nodejs server using socketio in Linux. In that platform, I send the binary stream through the stdin and receive the conversion status in stderr. Can I do it using Xabe wrapper?Depth
A
3

I'm playing around with an ffmpeg wrapper library called MediaHandler Pro from

http://www.mediasoftpro.com

seems promising so far.

Anticoagulant answered 16/8, 2011 at 11:45 Comment(2)
How did this work out for you? Also, does MediaHandler spawn ffmpeg.exe as a process to do its work, or is there an actual P/Invoke library?Plosive
I ended up using it in a couple of projects. It worked well in a production environment under heavy load. it been a while since I used it, but from what I remember, yes it does spawn ffmpeg.exe as a process.Anticoagulant
D
3

I have been researching the same thing and originally used MediaToolKit (mentioned in another answer) which worked great for conversions but now I need something a bit more robust.

One option that seems mature and still active is: https://github.com/hudl/HudlFfmpeg Which you can read more about here: http://public.hudl.com/bits/archives/2014/08/15/announcing-hudlffmpeg-a-c-framework-to-make-ffmpeg-interaction-simple/

Another option, which may not suit many cases, is to invoke the exe directly from your c# code: http://www.codeproject.com/Articles/774093/Another-FFmpeg-exe-Csharp-Wrapper

Delve answered 6/6, 2016 at 20:30 Comment(0)
S
2

There is another simple one here: http://ivolo.mit.edu/post/Metamorph-Convert-Audio-Video-to-Any-Format-on-Windows-Linux-and-Mac.aspx

Scuta answered 3/6, 2010 at 6:47 Comment(3)
Thanks for the link, but as far as I can see you wrote yours in Java, not int C#.Glossolalia
Hi lillemanden, the link I gave is actually implemented in Java, and if you download the zip at the bottom of the article, you'll see that there is a jar archive file inside of it. Thanks, IlyaScuta
Link in answer seems dead: "This site can’t be reached - ivolo.mit.edu took too long to respond."Exstipulate
R
2

Here ya go... Most of this code is 2+ years old so missing a lot of asynchronous stuff, and using an outdated naming convention. Running in a production enviornment for quite some time ~ 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();
    }

// for the process runner stuff look up ProcessRunner by Roger Knapp

Reginaldreginauld answered 19/12, 2013 at 2:36 Comment(0)
C
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;

This wrapper will not let the method fall into a loop. Try this,it worked for me.

Cardinal answered 31/7, 2014 at 4:21 Comment(0)
Y
0

See Auto Generated FFmpeg wrapper for C#/.NET and Mono, an awesome project which seems like the only true, complete .NET wrapper for FFmpeg interop out there.

Yesima answered 28/9, 2015 at 22:20 Comment(0)
V
0

I forked FFPMEG.net from codeplex.

Still actively being worked on.

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

It doesn't use the dlls, but rather the exe. So it tends to be more stable.

Voltcoulomb answered 19/10, 2015 at 16:45 Comment(3)
Looks like what I'm after, but how does one implement this in their project?Jurgen
Add this project to your project, then make sure FFMPEG is sitting inside the project correctly. Its still being worked on.Voltcoulomb
Can I encode and decode a frame as byte[] using this FFMPEG.net? for example, byte[] encodeh264(byte[]) and byte[] decodeh264(byte[]).Nemato

© 2022 - 2024 — McMap. All rights reserved.