using System.Globalization;
using System.Text.RegularExpressions;
namespace AmiReel.Services;
public sealed record FfmpegOutputLine(string Line, TimeSpan? Time, double? FramesPerSecond, double? Speed, int? Frame);
///
/// Parses a single line of FFmpeg stdout/stderr for the `time=`/`frame=`/`fps=`/`speed=`
/// progress fields FFmpeg prints while encoding.
///
public static partial class FfmpegProgressParser
{
public static FfmpegOutputLine Parse(string line)
{
TimeSpan? time = null;
double? fps = null;
double? speed = null;
int? frame = null;
Match timeMatch = TimeRegex().Match(line);
if (timeMatch.Success && TimeSpan.TryParse(timeMatch.Groups[1].Value, CultureInfo.InvariantCulture, out TimeSpan parsedTime))
time = parsedTime;
Match frameMatch = FrameRegex().Match(line);
if (frameMatch.Success)
{
if (int.TryParse(frameMatch.Groups["frame"].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out int parsedFrame))
frame = parsedFrame;
if (double.TryParse(frameMatch.Groups["fps"].Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double parsedFps))
fps = parsedFps;
if (double.TryParse(frameMatch.Groups["speed"].Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double parsedSpeed))
speed = parsedSpeed;
}
return new FfmpegOutputLine(line, time, fps, speed, frame);
}
[GeneratedRegex(@"time=(\d{2}:\d{2}:\d{2}(?:\.\d+)?)", RegexOptions.CultureInvariant)]
private static partial Regex TimeRegex();
[GeneratedRegex(@"frame=\s*(?\d+).*?fps=\s*(?\d+(?:\.\d+)?).*?speed=\s*(?\d+(?:\.\d+)?)x", RegexOptions.CultureInvariant)]
private static partial Regex FrameRegex();
}