Esempio n. 1
0
        private Task StartConversion(ConversionInput input, CancellationToken cancellationToken)
        {
            return(Task.Run(() =>
            {
                var receivedMessagesLog = new List <string>();
                Exception caughtException = null;

                var processStartInfo = GenerateStartInfo(input.CommandLine);

                OnData?.Invoke(this, new FFmpegRawDataEventArgs(input.CommandLine));

                using (FFmpegProcess = Process.Start(processStartInfo))
                {
                    FFmpegProcess.ErrorDataReceived += (sender, received) =>
                    {
                        if (received.Data == null)
                        {
                            return;
                        }

                        try
                        {
                            receivedMessagesLog.Insert(0, received.Data);

                            OnData?.Invoke(this, new FFmpegRawDataEventArgs(received.Data));

                            if (RegexEngine.HasProgressData(received.Data))
                            {
                                OnProgress?.Invoke(this, new FFmpegProgressEventArgs(RegexEngine.GetProgressData(received.Data, input)));
                            }
                            else if (RegexEngine.HasConversionCompleted(received.Data))
                            {
                                OnCompleted?.Invoke(this, new FFmpegCompletedEventArgs(RegexEngine.GetConversionCompletedData(received.Data, input)));
                            }
                        }
                        catch (Exception ex)
                        {
                            // catch the exception and kill the process since we're in a faulted state
                            caughtException = ex;

                            try
                            {
                                FFmpegProcess.Kill();
                            }
                            catch (InvalidOperationException)
                            {
                                // Swallow exceptions that are thrown when killing the process, ie. the application is ending naturally before we get a chance to kill it.
                            }
                        }
                    };

                    FFmpegProcess.BeginErrorReadLine();
                    if (cancellationToken != null)
                    {
                        while (!FFmpegProcess.WaitForExit(100))
                        {
                            if (!cancellationToken.IsCancellationRequested)
                            {
                                continue;
                            }

                            try
                            {
                                FFmpegProcess.Kill();
                            }
                            catch (Win32Exception)
                            {
                                // The associated process could not be terminated or the process is terminating.
                            }
                        }
                    }
                    else
                    {
                        FFmpegProcess.WaitForExit();
                    }

                    if (cancellationToken.IsCancellationRequested)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                    }

                    if (FFmpegProcess.ExitCode == 0 && caughtException == null)
                    {
                        return;
                    }

                    if (FFmpegProcess.ExitCode != 1 && receivedMessagesLog.Count >= 2)
                    {
                        throw new FFmpegException(FFmpegProcess.ExitCode + ": " + receivedMessagesLog[1] + receivedMessagesLog[0], caughtException);
                    }
                    else
                    {
                        throw new FFmpegException(string.Format($"ffmpeg exited with exitcode {FFmpegProcess.ExitCode}"), caughtException);
                    }
                }
            }));
        }
Esempio n. 2
0
        private void FFmpegRunner(string inputFile, string outputFile, string ffmpegCommandLine, CancellationToken cancellationToken)
        {
            List <string> receivedMessagesLog     = new List <string>();
            TimeSpan      totalMediaDuration      = new TimeSpan();
            bool          totalMediaDurationKnown = false;
            Exception     caughtException         = null;

            ProcessStartInfo processStartInfo = this.GenerateStartInfo(ffmpegCommandLine);

            this.OnData?.Invoke(this, new FFmpegDataEventArgs(ffmpegCommandLine));

            using (this.FFmpegProcess = Process.Start(processStartInfo))
            {
                this.FFmpegProcess.ErrorDataReceived += (sender, received) =>
                {
                    if (received.Data == null)
                    {
                        return;
                    }

                    try
                    {
                        receivedMessagesLog.Insert(0, received.Data);

                        this.OnData?.Invoke(this, new FFmpegDataEventArgs(received.Data));

                        if (!totalMediaDurationKnown)
                        {
                            totalMediaDurationKnown = RegexEngine.MediaDuration(received.Data, out totalMediaDuration);
                        }

                        if (RegexEngine.IsProgressData(received.Data, out FFmpegProgressEventArgs progressEvent))
                        {
                            progressEvent.InputFile     = inputFile;
                            progressEvent.OutputFile    = outputFile;
                            progressEvent.TotalDuration = totalMediaDuration;
                            this.OnProgress?.Invoke(this, progressEvent);
                        }
                        else if (RegexEngine.IsConvertCompleteData(received.Data, out FFmpegCompletedEventArgs convertCompleteEvent))
                        {
                            convertCompleteEvent.InputFile     = inputFile;
                            convertCompleteEvent.OutputFile    = outputFile;
                            convertCompleteEvent.TotalDuration = totalMediaDuration;
                            this.OnCompleted?.Invoke(this, convertCompleteEvent);
                        }
                    }
                    catch (Exception ex)
                    {
                        // catch the exception and kill the process since we're in a faulted state
                        caughtException = ex;

                        try
                        {
                            this.FFmpegProcess.Kill();
                        }
                        catch (InvalidOperationException)
                        {
                            // Swallow exceptions that are thrown when killing the process, ie. the application is ending naturally before we get a chance to kill it.
                        }
                    }
                };

                this.FFmpegProcess.BeginErrorReadLine();
                if (cancellationToken != null)
                {
                    while (!this.FFmpegProcess.WaitForExit(100))
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            try
                            {
                                this.FFmpegProcess.Kill();
                            }
                            catch (Win32Exception)
                            {
                                // The associated process could not be terminated or the process is terminating.
                            }
                        }
                    }
                }
                else
                {
                    this.FFmpegProcess.WaitForExit();
                }

                if (cancellationToken.IsCancellationRequested)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                }

                if (this.FFmpegProcess.ExitCode != 0 || caughtException != null)
                {
                    if (this.FFmpegProcess.ExitCode != 1 && receivedMessagesLog.Count >= 2)
                    {
                        throw new FFmpegException(this.FFmpegProcess.ExitCode + ": " + receivedMessagesLog[1] + receivedMessagesLog[0], caughtException);
                    }
                    else
                    {
                        throw new FFmpegException(string.Format($"ffmpeg exited with exitcode {this.FFmpegProcess.ExitCode}"), caughtException);
                    }
                }
            }
        }