diff --git a/Code/AudioVideo/AvProcess.cs b/Code/AudioVideo/AvProcess.cs index 1207c18..e143713 100644 --- a/Code/AudioVideo/AvProcess.cs +++ b/Code/AudioVideo/AvProcess.cs @@ -6,7 +6,9 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; +using Flowframes.MiscUtils; namespace Flowframes { @@ -65,6 +67,13 @@ namespace Flowframes if (line.Contains("No NVENC capable devices found")) Interpolate.Cancel($"FFmpeg Error: {line}\nMake sure you have an NVENC-capable Nvidia GPU."); + + if (line.Contains("time=") && !hidden) + { + Regex timeRegex = new Regex("(?<=time=).*(?= )"); + String timestamp = timeRegex.Match(line).Value; + UpdateFfmpegProgress(timeRegex.Match(line).Value); + } } static void FfmpegOutputHandlerSilent (object sendingProcess, DataReceivedEventArgs outLine) @@ -145,6 +154,16 @@ namespace Flowframes return output; } + public static void UpdateFfmpegProgress(String ffmpegTime) + { + long total = Program.mainForm.currInDuration / 100; + if (total == 0) return; + long current = FormatUtils.MsFromTimestamp(ffmpegTime); + int progress = Convert.ToInt32(current / total); + Program.mainForm.SetProgress(progress); + } + + public static async Task RunGifski(string args, LogMode logMode) { lastOutputGifski = ""; diff --git a/Code/AudioVideo/FFmpegCommands.cs b/Code/AudioVideo/FFmpegCommands.cs index a852594..1a39a65 100644 --- a/Code/AudioVideo/FFmpegCommands.cs +++ b/Code/AudioVideo/FFmpegCommands.cs @@ -323,6 +323,15 @@ namespace Flowframes } } + public static long GetDuration(string inputFile) + { + Logger.Log("Reading Duration using ffprobe.", true, false, "ffprobe"); + string args = $" -v panic -select_streams v:0 -show_entries format=duration -of csv=s=x:p=0 -sexagesimal {inputFile.Wrap()}"; + string info = AvProcess.GetFfprobeOutput(args); + return FormatUtils.MsFromTimestamp(info); + return -1; + } + public static float GetFramerate(string inputFile) { Logger.Log("Reading FPS using ffmpeg.", true, false, "ffmpeg"); diff --git a/Code/Form1.cs b/Code/Form1.cs index 4a5dd5b..fc1ed4d 100644 --- a/Code/Form1.cs +++ b/Code/Form1.cs @@ -15,6 +15,7 @@ using HTAlt.WinForms; using Flowframes.Data; using Microsoft.WindowsAPICodePack.Taskbar; using System.Threading.Tasks; +using Flowframes.MiscUtils; namespace Flowframes { @@ -119,11 +120,13 @@ namespace Flowframes public Size currInRes; public float currInFps; public int currInFrames; + public long currInDuration; public void UpdateInputInfo () { string str = $"Resolution: {(!currInRes.IsEmpty ? $"{currInRes.Width}x{currInRes.Height}" : "Unknown")} - "; str += $"Framerate: {(currInFps > 0f ? $"{currInFps.ToStringDot()} FPS" : "Unknown")} - "; - str += $"Frame Count: {(currInFrames > 0 ? $"{currInFrames} Frames" : "Unknown")}"; + str += $"Frame Count: {(currInFrames > 0 ? $"{currInFrames} Frames" : "Unknown")} - "; + str += $"Duration: {(currInDuration > 0 ? $"{FormatUtils.MsToTimestamp(currInDuration)}" : "Unknown")}"; inputInfo.Text = str; } @@ -132,6 +135,7 @@ namespace Flowframes currInRes = new Size(); currInFps = 0; currInFrames = 0; + currInDuration = 0; } void InitAis() diff --git a/Code/Main/InterpolateUtils.cs b/Code/Main/InterpolateUtils.cs index c2a9b66..f13d684 100644 --- a/Code/Main/InterpolateUtils.cs +++ b/Code/Main/InterpolateUtils.cs @@ -442,5 +442,10 @@ namespace Flowframes.Main foreach (string frame in sceneFramesToDelete) IOUtils.TryDeleteIfExists(Path.Combine(sceneFramesPath, frame + ".png")); } + + public static void UpdateVideoDuration(string path) + { + Program.mainForm.currInDuration = FFmpegCommands.GetDuration(path); + } } } diff --git a/Code/MiscUtils/FormatUtils.cs b/Code/MiscUtils/FormatUtils.cs index 9dfcb33..5f21b49 100644 --- a/Code/MiscUtils/FormatUtils.cs +++ b/Code/MiscUtils/FormatUtils.cs @@ -57,6 +57,22 @@ namespace Flowframes.MiscUtils return Time(elapsedMs); } + public static long MsFromTimestamp(String timestamp) + { + string[] values = timestamp.Split(':'); + int hours = Int32.Parse(values[0]); + int minutes = Int32.Parse(values[1]); + int seconds = Int32.Parse(values[2].Split('.')[0]); + int milliseconds = Int32.Parse(values[2].Split('.')[1].Substring(0, 2)) * 10; + long ms = hours * 3600000 + minutes * 60000 + seconds * 1000 + milliseconds; + return ms; + } + + public static String MsToTimestamp(long milliseconds) + { + return (new DateTime(1970, 1, 1)).AddMilliseconds(milliseconds).ToLongTimeString(); + } + public static string Ratio(long numFrom, long numTo) { float ratio = ((float)numTo / (float)numFrom) * 100f; diff --git a/Code/UI/MainUiFunctions.cs b/Code/UI/MainUiFunctions.cs index 27848ba..04e02fa 100644 --- a/Code/UI/MainUiFunctions.cs +++ b/Code/UI/MainUiFunctions.cs @@ -49,6 +49,7 @@ namespace Flowframes.UI Program.mainForm.currInFps = fps; Program.mainForm.currInFrames = frameCount; + InterpolateUtils.UpdateVideoDuration(path); Program.mainForm.UpdateInputInfo(); CheckExistingFolder(path, outputTbox.Text.Trim()); await Task.Delay(10);