C # /. NET için katı FFmpeg sarıcı


91

Bir süredir web'de C # /. NET için sağlam bir FFmpeg sarmalayıcı arıyordum . Ama henüz faydalı bir şey bulmadım. Aşağıdaki üç projeyi buldum, ancak hepsi erken alfa aşamasında ölmüş gibi görünüyor.

FFmpeg.NET
ffmpeg keskinliğinde
FFLIB.NET

Öyleyse sorum şu ki, daha olgun bir sarmalayıcı projesi bilen var mı?
İş kuyrukları ve daha fazlasını içeren tam bir kod dönüştürme motoru aramıyorum. Sadece basit bir sarmalayıcı, böylece bir komut satırı çağrısı yapmam ve ardından konsol çıktısını ayrıştırmam gerekmiyor, ancak yöntem çağrıları yapabilir ve ilerleme için olay dinleyicileri kullanabilirim.

Ve henüz erken aşamalarda olsalar bile aktif projelerden bahsetmekten lütfen çekinmeyin.



1
Bununla ilgili yeni bir şey var mı? Sarıcınız herhangi bir ilerleme kaydetti mi?
Avi

3
@Lillemanden sarmalayıcınızı hiç yayınladınız mı veya açık kaynak kodlu hale getirdiniz mi?
Nick Benedict

Sorunun neredeyse 6 yaşında olması ilginç ama OP (@JacobPoulRichardt) yanıtların hiçbirini kabul etmedi.
Ofer Zelig

1
Kendi yaptığım bir sarmalayıcıyı kullandım ve bu nedenle önerilen projelerin hiçbirini kullanmadım. Artık ffmpeg ile çalışmadığım için, geri dönüp herhangi birini deneyecek vaktim de olmadı. Ancak cevapların çoğunu gözden geçirdikten sonra oylarını aldınız. Bu yüzden, yanıtlardan herhangi birinin diğerlerinden daha "doğru" olduğunu gerçekten söyleyebileceğimi sanmıyorum.
Jacob Poul Richardt

Yanıtlar:


24

Bu bana ait bir paketleyicidir: https://github.com/AydinAdn/MediaToolkit

MediaToolkit şunları yapabilir:

  • Video dosyalarını diğer çeşitli video formatlarına dönüştürün.
  • Video kod dönüştürme görevlerini gerçekleştirin.
    • Seçenekler konfigüre edilebilen: Bit rate, Frame rate, Resolution / size, Aspect ratio,Duration of video
  • Ses kod dönüştürme görevlerini gerçekleştirin.
    • Yapılandırılabilir seçenekler: Audio sample rate
  • FILM, PAL veya NTSC tv standartlarını kullanarak videoyu fiziksel formatlara dönüştürün
    • Ortamları şunlardır: DVD, DV, DV50, VCD,SVCD

İlerledikçe onu güncelliyorum ve kullanabilirsiniz, ayrıca Paket Yöneticisi Konsolunu kullanarak da yükleyebilirsiniz.

PM> Install-Package MediaToolkit

Araç kitiniz farklı video ve ses kliplerini belirli bir çıktı çözünürlüğünden birinde işleyebilir mi?
Antonio Petricca

Hayır, basit dönüşümleri kovalayan insanlar için kullanılmak üzere tasarlandı. Bununla birlikte, çok yakında FFmpeg'in teklif etmesi gereken her şeyi yapmanıza izin verecek v2 var.
Aydın

Teşekkürler Aydın, lütfen beni bu yeni sürümden haberdar edin.
Antonio Petricca

Harika görünüyor! Şimdiye kadar iyi iş!
SpoiledTechie.com

Hey Aydın, bu da ekranı kaydedebilir mi?
TEK

14

Birkaç sarmalayıcıyı denedikten sonra, şuna gittim: FFmpeg, C # /. NET ve Mono için otomatik olarak güvenli olmayan bağlar oluşturdu .

FFmpeg ad alanındaki her sınıf için düşük düzeyli birlikte çalışma bağlamaları kümesidir. Kullanmak için gerçek bir paketleyici kadar uygun olmayabilir, ancak IMO, önemsiz şeyler yapmak istiyorsanız .Net'te FFmpeg ile çalışmak için en iyi çözümdür.

Artıları:

  • İşler
  • Güvenilir - FFMpeg'in kendisine güvendiğinizi varsayarak, hatalara yol açacak 3. taraf sarmalayıcı kodu yoktur.
  • Her zaman FFmpeg'in en son sürümüne güncellenir
  • Tüm bağlamalar için tek nuget paketi
  • XML belgeleri dahildir, ancak yine de çevrimiçi belgeleri FFmpeg belgelerini kullanabilirsiniz .

Eksileri:

  • Düşük seviye: C yapılarına işaretçilerle nasıl çalışılacağını bilmelisiniz .
  • Çalışması için başlangıçta biraz çalışma gerektirir. Resmi örneklerden öğrenmenizi öneririm .

Not: Bu iş parçacığı FFmpeg API'sini kullanmakla ilgilidir, ancak bazı kullanım durumları için en iyisi ffmpeg.exe'nin komut satırı arayüzünü kullanmaktır .


Net Framework için hedeflenen (çekirdek değil) bir projeden kullanmayı başardınız mı? Burada neyi özlediğimden emin değilim
Yoav Feuerstein

@YoavFeuerstein Evet.
orca


10

Bir ASP.NET / Windows hizmeti (.NET) uygulamasından FFmpeg kullandım. Ancak konsolu ayrıştırmadan komut satırını kullandım. Bunu kullanarak - kontrol etmenin kolay bir yolu vardı - FFmpeg güncellemelerini ve birden çok Çekirdekte birden çok dönüştürme çalıştırmayı.


Tamam, benzer bir şeye başladım. Ama hala birisinin daha iyi bir çözümü olmasını umuyorum.
Jacob Poul Richardt

4

Bu nuget paketini kullanabilirsiniz:

Olgun bir proje sorduğunuzu biliyorum , ancak beklentilerimi karşılayan herhangi bir proje görmedim, bu yüzden kendi projemi yapmaya karar verdim. Dönüşümleri kolayca sıraya koyabilir ve paralel çalıştırabilir, medyayı farklı biçimlere dönüştürme yöntemleri, kendi argümanlarınızı ffmpeg'e gönderebilir ve ffmpeg + olay dinleyicisinden çıktıyı mevcut ilerleme ile ayrıştırabilirsiniz.

Install-Package Xabe.FFmpeg

Kullanımı kolay, çapraz platform FFmpeg sarmalayıcı yapmaya çalışıyorum.

Bununla ilgili daha fazla bilgiyi https://xabe.net/product/xabe_ffmpeg/ adresinde bulabilirsiniz.

Daha fazla bilgi burada: https://xabe.net/product/xabe_ffmpeg/#documentation

Dönüşüm basittir:

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

İlerleme istiyorsanız:

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

Merhaba ... Bir web sayfasından gelen akış verilerini dönüştürmek ve bir RTMP sunucusuna göndermek için FFMPEG kullanmam gerekiyor. C # winform programımda bayt dizisi var. Yalnızca kod dönüştürmem ve RTMP sunucusuna göndermem gerekiyor. Bunu bu ambalajı kullanarak yapabilir miyim? Bunu Linux'ta socketio kullanarak bir nodejs sunucusu kullanarak yaptım. Bu platformda, ikili akışı stdin üzerinden gönderiyorum ve dönüşüm durumunu stderr'de alıyorum. Xabe sarıcı kullanarak yapabilir miyim?
jstuardo

3

MediaHandler Pro adlı bir ffmpeg sarmalayıcı kitaplığıyla oynuyorum

http://www.mediasoftpro.com

şimdiye kadar umut verici görünüyor.


Bu senin için nasıl sonuçlandı? Ayrıca gelmez MediaHandleryumurtlamaya ffmpeg.exeişini yapmak için bir süreç olarak, ya da gerçek P / çağır kütüphane var?
Glenn Slayden

Birkaç projede kullandım. Ağır yük altındaki bir üretim ortamında iyi çalıştı. Kullandığımdan beri bir süre geçti, ama hatırladığım kadarıyla evet, ffmpeg.exe'yi bir işlem olarak ortaya çıkarıyor.
Christophe Chang

3

Aynı şeyi araştırıyordum ve orijinal olarak MediaToolKit'i (başka bir cevapta bahsedildi) kullandım, bu da dönüşümler için harika çalışıyor, ancak şimdi biraz daha sağlam bir şeye ihtiyacım var.

Olgun ve hala aktif görünen bir seçenek: https://github.com/hudl/HudlFfmpeg Burada hakkında daha fazla bilgi edinebilirsiniz: http://public.hudl.com/bits/archives/2014/08/15/announcing -hudlffmpeg-ac-çerçeve-yapmak-ffmpeg-etkileşimi-basit /

Pek çok duruma uygun olmayabilecek başka bir seçenek de exe'yi doğrudan c # kodunuzdan çağırmaktır: http://www.codeproject.com/Articles/774093/Another-FFmpeg-exe-Csharp-Wrapper


2

1
Bağlantı için teşekkürler, ama görebildiğim kadarıyla sizinkini int C # değil, Java ile yazdınız.
Jacob Poul Richardt

Merhaba lillemanden, verdiğim link aslında Java'da uygulanıyor ve yazının altındaki zip dosyasını indirirseniz içinde bir jar arşiv dosyası olduğunu göreceksiniz. Teşekkürler, Ilya
Ilya

Yanıttaki
Pang

2

İşte buyrun ... Bu kodun çoğu 2+ yaşında olduğundan pek çok eşzamansız şey eksik ve eski bir adlandırma kuralı kullanıyor. Bir süredir üretim ortamında çalışıyor ~ 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();
    }

// süreç çalıştırıcı öğeleri için Roger Knapp'ın ProcessRunner'ına bakın


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;

Bu sarmalayıcı, yöntemin bir döngüye girmesine izin vermez. Bunu dene, benim için çalıştı.


1

Codeplex'ten FFPMEG.net'i çatalladım.

Hala aktif olarak üzerinde çalışılıyor.

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

Dll'leri değil, exe'yi kullanır. Bu yüzden daha kararlı olma eğilimindedir.


Peşinde olduğum şeye benziyor, ama insan bunu projesine nasıl uygulayabilir?
TEK

Bu projeyi projenize ekleyin, ardından FFMPEG'in projenin içinde doğru şekilde oturduğundan emin olun. Hala üzerinde çalışılıyor.
SpoiledTechie.com

Bu FFMPEG.net'i kullanarak bir kareyi bayt [] olarak kodlayabilir ve kodunu çözebilir miyim? örneğin, bayt [] encodeh264 (bayt []) ve bayt [] decodeh264 (bayt []).
Ahmad

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.