Esempio n. 1
0
        /// <summary>
        /// Establishes whether the data contains progress information.
        /// </summary>
        /// <param name="rawData">Event data from ffmpeg.</param>
        /// <param name="progressEventArgs">If successful, outputs a <see cref="FFmpegProgressEventArgs"/> which is generated from the data.</param>
        internal static ConversionProgessData GetProgressData(string rawData, ConversionInput inputData)
        {
            if (!HasProgressData(rawData))
            {
                return(null);
            }

            var matchSize    = _expressions[Find.ConvertProgressSize].Match(rawData);
            var matchTime    = _expressions[Find.ConvertProgressTime].Match(rawData);
            var matchBitrate = _expressions[Find.ConvertProgressBitrate].Match(rawData);
            var matchFrame   = _expressions[Find.ConvertProgressFrame].Match(rawData);
            var matchFps     = _expressions[Find.ConvertProgressFps].Match(rawData);
            var matchSpeed   = _expressions[Find.ConvertProgressSpeed].Match(rawData);

            TimeSpan.TryParse(matchTime.Groups[1].Value, out TimeSpan processedDuration);
            long.TryParse(matchFrame.Groups[1].Value, out long frame);
            double.TryParse(matchFps.Groups[1].Value, out double fps);
            int.TryParse(matchSize.Groups[1].Value, out int sizeKb);
            double.TryParse(matchBitrate.Groups[1].Value, out double bitrate);
            double.TryParse(matchSpeed.Groups[1].Value, out double speed);

            return(new ConversionProgessData
            {
                OutputFile = inputData.OutputFile,
                InputFile = inputData.InputFile,
                CommandLine = inputData.CommandLine,
                ProcessedDuration = processedDuration,
                TotalDuration = TimeSpan.Zero,
                Frame = frame,
                Fps = fps,
                SizeKb = sizeKb,
                Bitrate = bitrate,
                Speed = speed
            });
        }
Esempio n. 2
0
        /// <summary>
        /// Establishes whether the data indicates the conversion is complete.
        /// </summary>
        /// <param name="rawData">Event data from ffmpeg.</param>
        /// <param name="conversionCompleteEvent">If successful, outputs a <see cref="FFmpegCompletedEventArgs"/> which is generated from the data.</param>
        /// <returns></returns>
        internal static ConversionCompletedData GetConversionCompletedData(string rawData, ConversionInput inputData)
        {
            if (!HasConversionCompleted(rawData))
            {
                return(null);
            }

            var matchFinished = _expressions[Find.ConvertProgressFinished].Match(rawData);

            double.TryParse(matchFinished.Groups[2].Value, NumberStyles.Any, CultureInfo.InvariantCulture, out double muxingOverhead);

            return(new ConversionCompletedData
            {
                CommandLine = inputData.CommandLine,
                InputFile = inputData.InputFile,
                OutputFile = inputData.OutputFile,
                MuxingOverhead = muxingOverhead,
                TotalDuration = GetMediaDuration(rawData)
            });
        }
Esempio n. 3
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);
                    }
                }
            }));
        }