diff --git a/Code/Flowframes.csproj b/Code/Flowframes.csproj index 15b2ec9..104f7c3 100644 --- a/Code/Flowframes.csproj +++ b/Code/Flowframes.csproj @@ -69,8 +69,8 @@ bin\x64\Release\ - TRACE - true + DEBUG;TRACE + false pdbonly x64 7.3 @@ -403,6 +403,7 @@ + diff --git a/Code/Form1.cs b/Code/Form1.cs index 2314cc9..7b1905c 100644 --- a/Code/Form1.cs +++ b/Code/Form1.cs @@ -194,7 +194,7 @@ namespace Flowframes public void LoadBatchEntry(InterpSettings entry) { inputTbox.Text = entry.inPath; - MainUiFunctions.SetOutPath(inputTbox, entry.outPath); + MainUiFunctions.SetOutPath(outputTbox, entry.outPath); interpFactorCombox.Text = entry.interpFactor.ToString(); aiCombox.SelectedIndex = Implementations.networks.IndexOf(Implementations.networks.Where(x => x.aiName == entry.ai.aiName).FirstOrDefault()); SetOutMode(entry.outMode); diff --git a/Code/IO/IoUtils.cs b/Code/IO/IoUtils.cs index f2a5246..4ded55e 100644 --- a/Code/IO/IoUtils.cs +++ b/Code/IO/IoUtils.cs @@ -743,7 +743,7 @@ namespace Flowframes.IO } if (log) - Logger.Log($"Computed {hashType} for '{Path.GetFileNameWithoutExtension(path).Trunc(40) + Path.GetExtension(path)}' ({GetFilesizeStr(path)}): {hashStr} ({sw.GetElapsedStr()})", true); + Logger.Log($"Computed {hashType} for '{Path.GetFileNameWithoutExtension(path).Trunc(40) + Path.GetExtension(path)}' ({GetFilesizeStr(path)}): {hashStr} ({sw})", true); return hashStr; } diff --git a/Code/Main/Export.cs b/Code/Main/Export.cs index 4903fa0..a645b1a 100644 --- a/Code/Main/Export.cs +++ b/Code/Main/Export.cs @@ -232,7 +232,7 @@ namespace Flowframes.Main MessageBox.Show("An error occured while trying to merge the video chunks.\nCheck the log for details."); } - Logger.Log($"Merged video chunks in {sw.GetElapsedStr()}", true); + Logger.Log($"Merged video chunks in {sw}", true); } static async Task MergeChunks(string framesFile, string outPath, bool isBackup = false) diff --git a/Code/Media/AvOutputHandler.cs b/Code/Media/AvOutputHandler.cs new file mode 100644 index 0000000..79bb060 --- /dev/null +++ b/Code/Media/AvOutputHandler.cs @@ -0,0 +1,132 @@ +using Flowframes.MiscUtils; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using static Flowframes.AvProcess; + +namespace Flowframes.Media +{ + class AvOutputHandler + { + public static readonly string prefix = "[ffmpeg]"; + + public static void LogOutput(string line, ref string appendStr, string logFilename, LogMode logMode, bool showProgressBar) + { + if (Interpolate.canceled || string.IsNullOrWhiteSpace(line) || line.Trim().Length < 1) + return; + + bool hidden = logMode == LogMode.Hidden; + + if (HideMessage(line)) // Don't print certain warnings + hidden = true; + + bool replaceLastLine = logMode == LogMode.OnlyLastLine; + + if (line.Contains("time=") && (line.StartsWith("frame=") || line.StartsWith("size="))) + line = FormatUtils.BeautifyFfmpegStats(line); + + appendStr += Environment.NewLine + line; + Logger.Log($"{prefix} {line}", hidden, replaceLastLine, logFilename); + + if (!hidden && showProgressBar && line.Contains("Time:")) + { + Regex timeRegex = new Regex("(?<=Time:).*(?= )"); + UpdateFfmpegProgress(timeRegex.Match(line).Value); + } + + + if (line.Contains("Unable to")) + { + Interpolate.Cancel($"Error: {line}"); + return; + } + + if (line.Contains("Could not open file")) + { + Interpolate.Cancel($"Error: {line}"); + return; + } + + if (line.Contains("No NVENC capable devices found") || line.MatchesWildcard("*nvcuda.dll*")) + { + Interpolate.Cancel($"Error: {line}\n\nMake sure you have an NVENC-capable Nvidia GPU."); + return; + } + + if (line.Contains("not currently supported in container") || line.Contains("Unsupported codec id")) + { + Interpolate.Cancel($"Error: {line}\n\nIt looks like you are trying to copy a stream into a container that doesn't support this codec."); + return; + } + + if (line.Contains("Subtitle encoding currently only possible from text to text or bitmap to bitmap")) + { + Interpolate.Cancel($"Error: {line}\n\nYou cannot encode image-based subtitles into text-based subtitles. Please use the Copy Subtitles option instead, with a compatible container."); + return; + } + + if (line.Contains("Only VP8 or VP9 or AV1 video and Vorbis or Opus audio and WebVTT subtitles are supported for WebM")) + { + Interpolate.Cancel($"Error: {line}\n\nIt looks like you are trying to copy an unsupported stream into WEBM!"); + return; + } + + if (line.MatchesWildcard("*codec*not supported*")) + { + Interpolate.Cancel($"Error: {line}\n\nTry using a different codec."); + return; + } + + if (line.Contains("GIF muxer supports only a single video GIF stream")) + { + Interpolate.Cancel($"Error: {line}\n\nYou tried to mux a non-GIF stream into a GIF file."); + return; + } + + if (line.Contains("Width and height of input videos must be same")) + { + Interpolate.Cancel($"Error: {line}"); + return; + } + } + + public static void UpdateFfmpegProgress(string ffmpegTime) + { + try + { + Form1 form = Program.mainForm; + long currInDuration = (form.currInDurationCut < form.currInDuration) ? form.currInDurationCut : form.currInDuration; + + if (currInDuration < 1) + { + Program.mainForm.SetProgress(0); + return; + } + + long total = currInDuration / 100; + long current = FormatUtils.TimestampToMs(ffmpegTime); + int progress = Convert.ToInt32(current / total); + Program.mainForm.SetProgress(progress); + } + catch (Exception e) + { + Logger.Log($"Failed to get ffmpeg progress: {e.Message}", true); + } + } + + static bool HideMessage(string msg) + { + string[] hiddenMsgs = new string[] { "can produce invalid output", "pixel format", "provided invalid" }; + + foreach (string str in hiddenMsgs) + if (msg.MatchesWildcard($"*{str}*")) + return true; + + return false; + } + } +} diff --git a/Code/Media/AvProcess.cs b/Code/Media/AvProcess.cs index 68a9bab..f7c15f9 100644 --- a/Code/Media/AvProcess.cs +++ b/Code/Media/AvProcess.cs @@ -10,6 +10,7 @@ using System.Text.RegularExpressions; using System.Threading.Tasks; using Flowframes.MiscUtils; using Microsoft.VisualBasic; +using Flowframes.Media; namespace Flowframes { @@ -17,8 +18,6 @@ namespace Flowframes { public static Process lastAvProcess; public static Stopwatch timeSinceLastOutput = new Stopwatch(); - public enum TaskType { ExtractFrames, ExtractOther, Encode, GetInfo, Merge, Other }; - public static TaskType lastTask = TaskType.Other; public static string lastOutputFfmpeg; @@ -42,52 +41,64 @@ namespace Flowframes } } - public static async Task RunFfmpeg(string args, LogMode logMode, TaskType taskType = TaskType.Other, bool progressBar = false) + public static async Task RunFfmpeg(string args, LogMode logMode, bool reliableOutput = true, bool progressBar = false) { - await RunFfmpeg(args, "", logMode, defLogLevel, taskType, progressBar); + return await RunFfmpeg(args, "", logMode, defLogLevel, reliableOutput, progressBar); } - public static async Task RunFfmpeg(string args, LogMode logMode, string loglevel, TaskType taskType = TaskType.Other, bool progressBar = false) + public static async Task RunFfmpeg(string args, LogMode logMode, string loglevel, bool reliableOutput = true, bool progressBar = false) { - await RunFfmpeg(args, "", logMode, loglevel, taskType, progressBar); + return await RunFfmpeg(args, "", logMode, loglevel, reliableOutput, progressBar); } - public static async Task RunFfmpeg(string args, string workingDir, LogMode logMode, TaskType taskType = TaskType.Other, bool progressBar = false) + public static async Task RunFfmpeg(string args, string workingDir, LogMode logMode, bool reliableOutput = true, bool progressBar = false) { - await RunFfmpeg(args, workingDir, logMode, defLogLevel, taskType, progressBar); + return await RunFfmpeg(args, workingDir, logMode, defLogLevel, reliableOutput, progressBar); } - public static async Task RunFfmpeg(string args, string workingDir, LogMode logMode, string loglevel, TaskType taskType = TaskType.Other, bool progressBar = false) + public static async Task RunFfmpeg(string args, string workingDir, LogMode logMode, string loglevel, bool reliableOutput = true, bool progressBar = false) { - lastOutputFfmpeg = ""; - currentLogMode = logMode; - showProgressBar = progressBar; - Process ffmpeg = OsUtils.NewProcess(true); - timeSinceLastOutput.Restart(); + bool show = Config.GetInt(Config.Key.cmdDebugMode) > 0; + string processOutput = ""; + Process ffmpeg = OsUtils.NewProcess(!show); + NmkdStopwatch timeSinceLastOutput = new NmkdStopwatch(); lastAvProcess = ffmpeg; - lastTask = taskType; if (string.IsNullOrWhiteSpace(loglevel)) loglevel = defLogLevel; - if(!string.IsNullOrWhiteSpace(workingDir)) - ffmpeg.StartInfo.Arguments = $"{GetCmdArg()} cd /D {workingDir.Wrap()} & {Path.Combine(GetAvDir(), "ffmpeg.exe").Wrap()} {GetFfmpegDefaultArgs(loglevel)} {args}"; + string beforeArgs = $"-hide_banner -stats -loglevel {loglevel} -y"; + + if (!string.IsNullOrWhiteSpace(workingDir)) + ffmpeg.StartInfo.Arguments = $"{GetCmdArg()} cd /D {workingDir.Wrap()} & {Path.Combine(GetAvDir(), "ffmpeg.exe").Wrap()} {beforeArgs} {args}"; else - ffmpeg.StartInfo.Arguments = $"{GetCmdArg()} cd /D {GetAvDir().Wrap()} & ffmpeg.exe {GetFfmpegDefaultArgs(loglevel)} {args}"; - + ffmpeg.StartInfo.Arguments = $"{GetCmdArg()} cd /D {GetAvDir().Wrap()} & ffmpeg {beforeArgs} {args}"; + if (logMode != LogMode.Hidden) Logger.Log("Running FFmpeg...", false); - Logger.Log($"ffmpeg {GetFfmpegDefaultArgs(loglevel)} {args}", true, false, "ffmpeg"); - ffmpeg.OutputDataReceived += FfmpegOutputHandler; - ffmpeg.ErrorDataReceived += FfmpegOutputHandler; + Logger.Log($"ffmpeg {beforeArgs} {args}", true, false, "ffmpeg"); + + if (!show) + { + ffmpeg.OutputDataReceived += (sender, outLine) => { AvOutputHandler.LogOutput(outLine.Data, ref processOutput, "ffmpeg", logMode, progressBar); timeSinceLastOutput.sw.Restart(); }; + ffmpeg.ErrorDataReceived += (sender, outLine) => { AvOutputHandler.LogOutput(outLine.Data, ref processOutput, "ffmpeg", logMode, progressBar); timeSinceLastOutput.sw.Restart(); }; + } + ffmpeg.Start(); - ffmpeg.BeginOutputReadLine(); - ffmpeg.BeginErrorReadLine(); + ffmpeg.PriorityClass = ProcessPriorityClass.BelowNormal; - while (!ffmpeg.HasExited) - await Task.Delay(1); + if (!show) + { + ffmpeg.BeginOutputReadLine(); + ffmpeg.BeginErrorReadLine(); + } - if(progressBar) + while (!ffmpeg.HasExited) await Task.Delay(10); + while (reliableOutput && timeSinceLastOutput.ElapsedMs < 200) await Task.Delay(50); + + if (progressBar) Program.mainForm.SetProgress(0); + + return processOutput; } public static string GetFfmpegDefaultArgs (string loglevel = "warning") @@ -95,71 +106,41 @@ namespace Flowframes return $"-hide_banner -stats -loglevel {loglevel} -y"; } - static void FfmpegOutputHandler(object sendingProcess, DataReceivedEventArgs outLine) + public static async Task RunFfprobe(string args, LogMode logMode = LogMode.Hidden, string loglevel = "quiet") { - timeSinceLastOutput.Restart(); + bool show = Config.GetInt(Config.Key.cmdDebugMode) > 0; + string processOutput = ""; + Process ffprobe = OsUtils.NewProcess(!show); + NmkdStopwatch timeSinceLastOutput = new NmkdStopwatch(); + lastAvProcess = ffprobe; - if (Interpolate.canceled || outLine == null || outLine.Data == null) - return; + if (string.IsNullOrWhiteSpace(loglevel)) + loglevel = defLogLevel; - string line = outLine.Data; - lastOutputFfmpeg = lastOutputFfmpeg + "\n" + line; + ffprobe.StartInfo.Arguments = $"{GetCmdArg()} cd /D {GetAvDir().Wrap()} & ffprobe -v {loglevel} {args}"; - bool hidden = currentLogMode == LogMode.Hidden; + if (logMode != LogMode.Hidden) Logger.Log("Running FFprobe...", false); + Logger.Log($"ffprobe -v {loglevel} {args}", true, false, "ffmpeg"); - if (HideMessage(line)) // Don't print certain warnings - hidden = true; - - bool replaceLastLine = currentLogMode == LogMode.OnlyLastLine; - - if (line.StartsWith("frame=")) - line = FormatUtils.BeautifyFfmpegStats(line); - - Logger.Log(line, hidden, replaceLastLine, "ffmpeg"); - - if (line.Contains(".srt: Invalid data found")) - Logger.Log($"Warning: Failed to encode subtitle track {line.Split(':')[2]}. This track will be missing in the output file."); - - if (line.Contains("Could not open file")) - Interpolate.Cancel($"FFmpeg Error: {line}"); - - if (line.Contains("No NVENC capable devices found") || line.MatchesWildcard("*nvcuda.dll*")) - Interpolate.Cancel($"FFmpeg Error: {line}\nMake sure you have an NVENC-capable Nvidia GPU."); - - if (!hidden && showProgressBar && line.Contains("Time:")) + if (!show) { - Regex timeRegex = new Regex("(?<=Time:).*(?= )"); - UpdateFfmpegProgress(timeRegex.Match(line).Value); + ffprobe.OutputDataReceived += (sender, outLine) => { AvOutputHandler.LogOutput(outLine.Data, ref processOutput, "ffmpeg", logMode, false); timeSinceLastOutput.sw.Restart(); }; + ffprobe.ErrorDataReceived += (sender, outLine) => { AvOutputHandler.LogOutput(outLine.Data, ref processOutput, "ffmpeg", logMode, false); timeSinceLastOutput.sw.Restart(); }; } - } - static bool HideMessage (string msg) - { - string[] hiddenMsgs = new string[] { "can produce invalid output", "pixel format", "provided invalid" }; + ffprobe.Start(); + ffprobe.PriorityClass = ProcessPriorityClass.BelowNormal; - foreach (string str in hiddenMsgs) - if (msg.MatchesWildcard($"*{str}*")) - return true; + if (!show) + { + ffprobe.BeginOutputReadLine(); + ffprobe.BeginErrorReadLine(); + } - return false; - } + while (!ffprobe.HasExited) await Task.Delay(10); + while (timeSinceLastOutput.ElapsedMs < 200) await Task.Delay(50); - public static async Task GetFfmpegOutputAsync(string args, bool setBusy = false, bool progressBar = false) - { - timeSinceLastOutput.Restart(); - if (Program.busy) setBusy = false; - lastOutputFfmpeg = ""; - showProgressBar = progressBar; - Process ffmpeg = OsUtils.NewProcess(true); - lastAvProcess = ffmpeg; - ffmpeg.StartInfo.Arguments = $"{GetCmdArg()} cd /D {GetAvDir().Wrap()} & ffmpeg.exe -hide_banner -y -stats {args}"; - Logger.Log($"ffmpeg {args}", true, false, "ffmpeg"); - if (setBusy) Program.mainForm.SetWorking(true); - lastOutputFfmpeg = await OsUtils.GetOutputAsync(ffmpeg); - while (!ffmpeg.HasExited) await Task.Delay(50); - while(timeSinceLastOutput.ElapsedMilliseconds < 200) await Task.Delay(50); - if (setBusy) Program.mainForm.SetWorking(false); - return lastOutputFfmpeg; + return processOutput; } public static string GetFfprobeOutput (string args) @@ -174,30 +155,6 @@ namespace Flowframes if (!string.IsNullOrWhiteSpace(err)) output += "\n" + err; return output; } - - public static void UpdateFfmpegProgress(string ffmpegTime) - { - try - { - Form1 form = Program.mainForm; - long currInDuration = (form.currInDurationCut < form.currInDuration) ? form.currInDurationCut : form.currInDuration; - - if (currInDuration < 1) - { - Program.mainForm.SetProgress(0); - return; - } - - long total = currInDuration / 100; - long current = FormatUtils.TimestampToMs(ffmpegTime); - int progress = Convert.ToInt32(current / total); - Program.mainForm.SetProgress(progress); - } - catch (Exception e) - { - Logger.Log($"Failed to get ffmpeg progress: {e.Message}", true); - } - } static string GetAvDir () { diff --git a/Code/Media/FfmpegCommands.cs b/Code/Media/FfmpegCommands.cs index c65e0a6..caaf237 100644 --- a/Code/Media/FfmpegCommands.cs +++ b/Code/Media/FfmpegCommands.cs @@ -45,7 +45,7 @@ namespace Flowframes string loopStr = (looptimes > 0) ? $"-stream_loop {looptimes}" : ""; string vfrFilename = Path.GetFileName(concatFile); string args = $" {loopStr} -vsync 1 -f concat -i {vfrFilename} -c copy -movflags +faststart -fflags +genpts {outPath.Wrap()}"; - await RunFfmpeg(args, concatFile.GetParentDir(), LogMode.Hidden, TaskType.Merge); + await RunFfmpeg(args, concatFile.GetParentDir(), LogMode.Hidden); } public static async Task LoopVideo(string inputFile, int times, bool delSrc = false) @@ -157,9 +157,13 @@ namespace Flowframes public static async Task GetFrameCountAsync(string inputFile) { - Logger.Log($"GetFrameCountAsync('{inputFile}') - Trying ffprobe first.", true, false, "ffmpeg"); + Logger.Log($"GetFrameCountAsync('{inputFile}') - Trying ffprobe packet counting first (fastest).", true, false, "ffmpeg"); + int frames = await ReadFrameCountFfprobePacketCount(inputFile); // Try reading frame count with ffprobe packet counting + if (frames > 0) return frames; - int frames = await ReadFrameCountFfprobeAsync(inputFile, Config.GetBool(Config.Key.ffprobeFrameCount)); // Try reading frame count with ffprobe + Logger.Log($"GetFrameCountAsync('{inputFile}') - Trying ffprobe decoding now.", true, false, "ffmpeg"); + + frames = await ReadFrameCountFfprobe(inputFile); // Try reading frame count with ffprobe decoding if (frames > 0) return frames; Logger.Log($"Failed to get frame count using ffprobe (frames = {frames}). Trying to read with ffmpeg.", true, false, "ffmpeg"); @@ -170,7 +174,7 @@ namespace Flowframes return 0; } - static int ReadFrameCountFromDuration (string inputFile, long durationMs, float fps) + static int ReadFrameCountFromDuration(string inputFile, long durationMs, float fps) { float durationSeconds = durationMs / 1000f; float frameCount = durationSeconds * fps; @@ -179,21 +183,25 @@ namespace Flowframes return frameCountRounded; } - static async Task ReadFrameCountFfprobeAsync(string inputFile, bool readFramesSlow) + public static async Task ReadFrameCountFfprobePacketCount(string filePath) { - string args = $" -v panic -threads 0 -select_streams v:0 -show_entries stream=nb_frames -of default=noprint_wrappers=1 {inputFile.Wrap()}"; - if (readFramesSlow) - { - Logger.Log("Counting total frames using FFprobe. This can take a moment..."); - await Task.Delay(10); - args = $" -v panic -threads 0 -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 {inputFile.Wrap()}"; - } - string info = GetFfprobeOutput(args); + string output = await RunFfprobe($"-select_streams v:0 -count_packets -show_entries stream=nb_read_packets -of csv=p=0 {filePath.Wrap()}", LogMode.Hidden, "error"); + string[] lines = output.SplitIntoLines().Where(x => !string.IsNullOrWhiteSpace(x)).ToArray(); + + if (lines == null || lines.Length < 1) + return 0; + + return lines.Last().GetInt(); + } + + public static async Task ReadFrameCountFfprobe(string filePath) + { + string args = $" -v panic {filePath.Wrap()} -threads 0 -select_streams v:0 -show_entries stream=nb_frames -of default=noprint_wrappers=1 {filePath.Wrap()}"; + string info = await RunFfprobe(args); string[] entries = info.SplitIntoLines(); + try { - if (readFramesSlow) - return info.GetInt(); foreach (string entry in entries) { if (entry.Contains("nb_frames=")) @@ -201,17 +209,18 @@ namespace Flowframes } } catch { } + return -1; } - static async Task ReadFrameCountFfmpegAsync (string inputFile) + public static async Task ReadFrameCountFfmpegAsync(string filePath) { - string args = $" -loglevel panic -stats -i {inputFile.Wrap()} -map 0:v:0 -c copy -f null - "; - string info = await GetFfmpegOutputAsync(args, true, true); + string args = $" -loglevel panic -stats {filePath.Wrap()} -i {filePath.Wrap()} -map 0:v:0 -c copy -f null - "; + string info = await RunFfmpeg(args, LogMode.Hidden); try { string[] lines = info.SplitIntoLines(); - string lastLine = lines.Last(); + string lastLine = lines.Last().ToLower(); return lastLine.Substring(0, lastLine.IndexOf("fps")).GetInt(); } catch @@ -231,7 +240,7 @@ namespace Flowframes { Logger.Log($"IsEncoderCompatible('{enc}')", true, false, "ffmpeg"); string args = $"-loglevel error -f lavfi -i color=black:s=540x540 -vframes 1 -an -c:v {enc} -f null -"; - string output = await GetFfmpegOutputAsync(args); + string output = await RunFfmpeg(args, LogMode.Hidden); return !output.ToLower().Contains("error"); } diff --git a/Code/Media/FfmpegEncode.cs b/Code/Media/FfmpegEncode.cs index bd5438a..60bf3d2 100644 --- a/Code/Media/FfmpegEncode.cs +++ b/Code/Media/FfmpegEncode.cs @@ -59,7 +59,7 @@ namespace Flowframes.Media } //string argsOld = $"-vsync 0 -r {fps} {inArg} {encArgs} {vf} {GetAspectArg(extraData)} {extraArgs} -threads {Config.GetInt(Config.Key.ffEncThreads)} {outPath.Wrap()}"; - await RunFfmpeg(args, framesFile.GetParentDir(), logMode, "error", TaskType.Encode, !isChunk); + await RunFfmpeg(args, framesFile.GetParentDir(), logMode, !isChunk); IoUtils.TryDeleteIfExists(linksDir); } @@ -95,7 +95,7 @@ namespace Flowframes.Media string compression = format == "png" ? pngCompr : $"-q:v {lossyQ}"; string codec = format == "webp" ? "-c:v libwebp" : ""; // Specify libwebp to avoid putting all frames into single animated WEBP string args = $"-vsync 0 -r {rate} {inArg} {codec} {compression} {sn} {vf} \"{outDir}/%{Padding.interpFrames}d.{format}\""; - await RunFfmpeg(args, framesFile.GetParentDir(), logMode, "error", TaskType.Encode, true); + await RunFfmpeg(args, framesFile.GetParentDir(), logMode, "error", true); IoUtils.TryDeleteIfExists(linksDir); } @@ -115,7 +115,7 @@ namespace Flowframes.Media string extraArgs = Config.Get(Config.Key.ffEncArgs); rate = rate / new Fraction(itsScale); string args = $"-f concat -r {rate} -i {framesFilename.Wrap()} -gifflags -offsetting {vf} {extraArgs} {outPath.Wrap()}"; - await RunFfmpeg(args, framesFile.GetParentDir(), LogMode.OnlyLastLine, "error", TaskType.Encode); + await RunFfmpeg(args, framesFile.GetParentDir(), LogMode.OnlyLastLine, "error"); } } } diff --git a/Code/Media/FfmpegExtract.cs b/Code/Media/FfmpegExtract.cs index 3c270ab..d18ee11 100644 --- a/Code/Media/FfmpegExtract.cs +++ b/Code/Media/FfmpegExtract.cs @@ -35,7 +35,7 @@ namespace Flowframes.Media string args = $"-vsync 0 {GetTrimArg(true)} {inArg} {GetImgArgs(format)} {rateArg} {scnDetect} -frame_pts 1 -s 256x144 {GetTrimArg(false)} \"{outDir}/%{Padding.inputFrames}d{format}\""; LogMode logMode = await Interpolate.GetCurrentInputFrameCount() > 50 ? LogMode.OnlyLastLine : LogMode.Hidden; - await RunFfmpeg(args, logMode, inputIsFrames ? "panic" : "warning", TaskType.ExtractFrames, true); + await RunFfmpeg(args, logMode, inputIsFrames ? "panic" : "warning", true); bool hiddenLog = await Interpolate.GetCurrentInputFrameCount() <= 50; int amount = IoUtils.GetAmountOfFiles(outDir, false); @@ -84,7 +84,7 @@ namespace Flowframes.Media string rateArg = (rate.GetFloat() > 0) ? $" -r {rate}" : ""; string args = $"{GetTrimArg(true)} -i {inputFile.Wrap()} {GetImgArgs(format, true, alpha)} -vsync 0 {rateArg} -frame_pts 1 {vf} {sizeStr} {GetTrimArg(false)} \"{framesDir}/%{Padding.inputFrames}d{format}\""; LogMode logMode = await Interpolate.GetCurrentInputFrameCount() > 50 ? LogMode.OnlyLastLine : LogMode.Hidden; - await RunFfmpeg(args, logMode, TaskType.ExtractFrames, true); + await RunFfmpeg(args, logMode, true); int amount = IoUtils.GetAmountOfFiles(framesDir, false, "*" + format); Logger.Log($"Extracted {amount} {(amount == 1 ? "frame" : "frames")} from input.", false, true); await Task.Delay(1); @@ -173,7 +173,7 @@ namespace Flowframes.Media if (!allSameSize) { - Logger.Log($"Sequence not compatible: Not all images have the same dimensions [{sw.GetElapsedStr()}].", true); + Logger.Log($"Sequence not compatible: Not all images have the same dimensions.", true); return false; } @@ -182,7 +182,7 @@ namespace Flowframes.Media if (!allDivBy2) { - Logger.Log($"Sequence not compatible: Not all image dimensions are divisible by {div} [{sw.GetElapsedStr()}].", true); + Logger.Log($"Sequence not compatible: Not all image dimensions are divisible by {div}.", true); return false; } @@ -190,7 +190,7 @@ namespace Flowframes.Media if (!allSmallEnough) { - Logger.Log($"Sequence not compatible: Image dimensions above max size [{sw.GetElapsedStr()}].", true); + Logger.Log($"Sequence not compatible: Image dimensions above max size.", true); return false; } @@ -198,12 +198,12 @@ namespace Flowframes.Media if (!all24Bit) { - Logger.Log($"Sequence not compatible: Some images are not 24-bit (8bpp) [{sw.GetElapsedStr()}].", true); + Logger.Log($"Sequence not compatible: Some images are not 24-bit (8bpp).", true); return false; } Interpolate.current.framesExt = files.First().Extension; - Logger.Log($"Sequence compatible! [{sw.GetElapsedStr()}]", true); + Logger.Log($"Sequence compatible!", true); return true; } @@ -228,7 +228,7 @@ namespace Flowframes.Media string vf = $"-vf {GetPadFilter()}"; string args = $"-r 25 {inArg} {GetImgArgs(format, true, alpha)} {sizeStr} -vsync 0 -start_number 0 {vf} \"{outPath}/%{Padding.inputFrames}d{format}\""; LogMode logMode = IoUtils.GetAmountOfFiles(inPath, false) > 50 ? LogMode.OnlyLastLine : LogMode.Hidden; - await RunFfmpeg(args, logMode, "panic", TaskType.ExtractFrames); + await RunFfmpeg(args, logMode, "panic"); } public static string[] GetTrimArgs() @@ -282,7 +282,7 @@ namespace Flowframes.Media string comprArg = isPng ? pngCompr : ""; string pixFmt = "-pix_fmt " + (isPng ? $"rgb24 {comprArg}" : "yuvj420p"); string args = $"-i {inputFile.Wrap()} {comprArg} {sizeStr} {pixFmt} -vf {GetPadFilter()} {outPath.Wrap()}"; - await RunFfmpeg(args, LogMode.Hidden, TaskType.ExtractFrames); + await RunFfmpeg(args, LogMode.Hidden); } public static async Task ExtractSingleFrame(string inputFile, string outputPath, int frameNum) @@ -291,7 +291,7 @@ namespace Flowframes.Media string comprArg = isPng ? pngCompr : ""; string pixFmt = "-pix_fmt " + (isPng ? $"rgb24 {comprArg}" : "yuvj420p"); string args = $"-i {inputFile.Wrap()} -vf \"select=eq(n\\,{frameNum})\" -vframes 1 {pixFmt} {outputPath.Wrap()}"; - await RunFfmpeg(args, LogMode.Hidden, TaskType.ExtractFrames); + await RunFfmpeg(args, LogMode.Hidden); } public static async Task ExtractLastFrame(string inputFile, string outputPath, Size size) @@ -309,7 +309,7 @@ namespace Flowframes.Media string trim = QuickSettingsTab.trimEnabled ? $"-ss {QuickSettingsTab.GetTrimEndMinusOne()} -to {QuickSettingsTab.trimEnd}" : ""; string sseof = string.IsNullOrWhiteSpace(trim) ? "-sseof -1" : ""; string args = $"{sseof} -i {inputFile.Wrap()} -update 1 {pixFmt} {sizeStr} {trim} {outputPath.Wrap()}"; - await RunFfmpeg(args, LogMode.Hidden, TaskType.ExtractFrames); + await RunFfmpeg(args, LogMode.Hidden); } } } diff --git a/Code/MiscUtils/BackgroundTaskManager.cs b/Code/MiscUtils/BackgroundTaskManager.cs index da1bac2..d5573e8 100644 --- a/Code/MiscUtils/BackgroundTaskManager.cs +++ b/Code/MiscUtils/BackgroundTaskManager.cs @@ -39,7 +39,7 @@ namespace Flowframes.MiscUtils { if(task.timer.sw.ElapsedMilliseconds > task.timeoutSeconds * 1000) { - Logger.Log($"[BgTaskMgr] Task with ID {task.id} timed out, has been running for {task.timer.GetElapsedStr()}!", true); + Logger.Log($"[BgTaskMgr] Task with ID {task.id} timed out, has been running for {task.timer}!", true); runningTasks.Remove(task); } } @@ -59,7 +59,7 @@ namespace Flowframes.MiscUtils { if(task.id == id) { - Logger.Log($"[BgTaskMgr] Task '{task.name}' has finished after {task.timer.GetElapsedStr()} (Timeout {task.timeoutSeconds}s)", true); + Logger.Log($"[BgTaskMgr] Task '{task.name}' has finished after {task.timer} (Timeout {task.timeoutSeconds}s)", true); runningTasks.Remove(task); } } diff --git a/Code/MiscUtils/Benchmarker.cs b/Code/MiscUtils/Benchmarker.cs index e7120de..ad0c368 100644 --- a/Code/MiscUtils/Benchmarker.cs +++ b/Code/MiscUtils/Benchmarker.cs @@ -9,7 +9,7 @@ namespace Flowframes.MiscUtils { NmkdStopwatch sw = new NmkdStopwatch(); var returnVal = method.DynamicInvoke(args); - Logger.Log($"Ran {methodName} in {sw.GetElapsedStr()}", true); + Logger.Log($"Ran {methodName} in {sw}", true); return returnVal; } @@ -18,7 +18,7 @@ namespace Flowframes.MiscUtils { NmkdStopwatch sw = new NmkdStopwatch(); method.DynamicInvoke(args); - Logger.Log($"Ran {methodName} in {sw.GetElapsedStr()}", true); + Logger.Log($"Ran {methodName} in {sw}", true); } } } diff --git a/Code/MiscUtils/NmkdStopwatch.cs b/Code/MiscUtils/NmkdStopwatch.cs index d9d696c..d643488 100644 --- a/Code/MiscUtils/NmkdStopwatch.cs +++ b/Code/MiscUtils/NmkdStopwatch.cs @@ -6,15 +6,16 @@ namespace Flowframes.MiscUtils { class NmkdStopwatch { - public Stopwatch sw = new Stopwatch(); + public Stopwatch sw = new Stopwatch(); + public long ElapsedMs { get { return sw.ElapsedMilliseconds; } } - public NmkdStopwatch (bool startOnCreation = true) + public NmkdStopwatch(bool startOnCreation = true) { if (startOnCreation) sw.Restart(); } - public string GetElapsedStr () + public override string ToString() { return FormatUtils.TimeSw(sw); } diff --git a/Code/Os/AiProcess.cs b/Code/Os/AiProcess.cs index 93a6929..61c2df2 100644 --- a/Code/Os/AiProcess.cs +++ b/Code/Os/AiProcess.cs @@ -90,7 +90,7 @@ namespace Flowframes.Os while (Interpolate.currentlyUsingAutoEnc && Program.busy) { - if (AvProcess.lastAvProcess != null && !AvProcess.lastAvProcess.HasExited && AvProcess.lastTask == AvProcess.TaskType.Encode) + if (AvProcess.lastAvProcess != null && !AvProcess.lastAvProcess.HasExited) { string lastLine = AvProcess.lastOutputFfmpeg.SplitIntoLines().Last(); Logger.Log(FormatUtils.BeautifyFfmpegStats(lastLine), false, Logger.GetLastLine().ToLower().Contains("frame")); diff --git a/Code/Os/OsUtils.cs b/Code/Os/OsUtils.cs index c3ee87a..2418402 100644 --- a/Code/Os/OsUtils.cs +++ b/Code/Os/OsUtils.cs @@ -226,7 +226,7 @@ namespace Flowframes.Os while (timeSinceLastOutput.ElapsedMilliseconds < 100) await Task.Delay(50); output = output.Trim('\r', '\n'); - Logger.Log($"Output (after {sw.GetElapsedStr()}): {output.Replace("\r", " / ").Replace("\n", " / ").Trunc(250)}", true); + Logger.Log($"Output (after {sw}): {output.Replace("\r", " / ").Replace("\n", " / ").Trunc(250)}", true); if (onlyLastLine) output = output.SplitIntoLines().LastOrDefault(); diff --git a/Code/Ui/DebugFormHelper.cs b/Code/Ui/DebugFormHelper.cs index d580e48..09eb3dd 100644 --- a/Code/Ui/DebugFormHelper.cs +++ b/Code/Ui/DebugFormHelper.cs @@ -112,7 +112,7 @@ namespace Flowframes.Ui } Config.Set(dict); - Logger.Log($"Config Editor: Saved {grid.Rows.Count} config keys in {sw.GetElapsedStr()}", true); + Logger.Log($"Config Editor: Saved {grid.Rows.Count} config keys in {sw}", true); } #endregion diff --git a/Code/Ui/MainUiFunctions.cs b/Code/Ui/MainUiFunctions.cs index abcaae9..1f0f4dc 100644 --- a/Code/Ui/MainUiFunctions.cs +++ b/Code/Ui/MainUiFunctions.cs @@ -26,7 +26,7 @@ namespace Flowframes.Ui if (Config.GetBool(Config.Key.clearLogOnInput)) Logger.ClearLogBox(); - SetOutPath(inputTbox, inputTbox.Text.Trim().GetParentDir()); + SetOutPath(outputTbox, inputTbox.Text.Trim().GetParentDir()); Program.lastInputPath = path; Program.lastInputPathIsSsd = OsUtils.DriveIsSSD(path);