public static async Task <string> GetOutputAsync(Process process, bool onlyLastLine = false) { Logger.Log($"Getting output for {process.StartInfo.FileName} {process.StartInfo.Arguments}", true); NmkdStopwatch sw = new NmkdStopwatch(); Stopwatch timeSinceLastOutput = new Stopwatch(); timeSinceLastOutput.Restart(); string output = ""; process.OutputDataReceived += (object sender, DataReceivedEventArgs e) => output += $"{e.Data}\n"; process.ErrorDataReceived += (object sender, DataReceivedEventArgs e) => output += $"{e.Data}\n"; process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); while (!process.HasExited) { await Task.Delay(50); } while (timeSinceLastOutput.ElapsedMilliseconds < 100) { await Task.Delay(50); } output = output.Trim('\r', '\n'); Logger.Log($"Output (after {sw}): {output.Replace("\r", " / ").Replace("\n", " / ").Trunc(250)}", true); if (onlyLastLine) { output = output.SplitIntoLines().LastOrDefault(); } return(output); }
public static async Task ChunksToVideo(string tempFolder, string chunksFolder, string baseOutPath, bool isBackup = false) { if (IoUtils.GetAmountOfFiles(chunksFolder, true, "*" + FfmpegUtils.GetExt(I.current.outMode)) < 1) { I.Cancel("No video chunks found - An error must have occured during chunk encoding!", AiProcess.hasShownError); return; } NmkdStopwatch sw = new NmkdStopwatch(); if (!isBackup) { Program.mainForm.SetStatus("Merging video chunks..."); } try { DirectoryInfo chunksDir = new DirectoryInfo(chunksFolder); foreach (DirectoryInfo dir in chunksDir.GetDirectories()) { string suffix = dir.Name.Replace("chunks", ""); string tempConcatFile = Path.Combine(tempFolder, $"chunks-concat{suffix}.ini"); string concatFileContent = ""; foreach (string vid in IoUtils.GetFilesSorted(dir.FullName)) { concatFileContent += $"file '{Paths.chunksDir}/{dir.Name}/{Path.GetFileName(vid)}'\n"; } File.WriteAllText(tempConcatFile, concatFileContent); Logger.Log($"CreateVideo: Running MergeChunks() for frames file '{Path.GetFileName(tempConcatFile)}'", true); bool fpsLimit = dir.Name.Contains(Paths.fpsLimitSuffix); string outPath = Path.Combine(baseOutPath, await IoUtils.GetCurrentExportFilename(fpsLimit, true)); await MergeChunks(tempConcatFile, outPath, isBackup); if (!isBackup) { Task.Run(async() => { await IoUtils.TryDeleteIfExistsAsync(IoUtils.FilenameSuffix(outPath, Paths.backupSuffix)); }); } } } catch (Exception e) { Logger.Log("ChunksToVideo Error: " + e.Message, isBackup); if (!isBackup) { MessageBox.Show("An error occured while trying to merge the video chunks.\nCheck the log for details."); } } Logger.Log($"Merged video chunks in {sw}", true); }
public static async Task <string> RunFfprobe(string args, LogMode logMode = LogMode.Hidden, string loglevel = "quiet") { bool show = Config.GetInt(Config.Key.cmdDebugMode) > 0; string processOutput = ""; Process ffprobe = OsUtils.NewProcess(!show); NmkdStopwatch timeSinceLastOutput = new NmkdStopwatch(); lastAvProcess = ffprobe; if (string.IsNullOrWhiteSpace(loglevel)) { loglevel = defLogLevel; } ffprobe.StartInfo.Arguments = $"{GetCmdArg()} cd /D {GetAvDir().Wrap()} & ffprobe -v {loglevel} {args}"; if (logMode != LogMode.Hidden) { Logger.Log("Running FFprobe...", false); } Logger.Log($"ffprobe -v {loglevel} {args}", true, false, "ffmpeg"); if (!show) { 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(); }; } ffprobe.Start(); ffprobe.PriorityClass = ProcessPriorityClass.BelowNormal; if (!show) { ffprobe.BeginOutputReadLine(); ffprobe.BeginErrorReadLine(); } while (!ffprobe.HasExited) { await Task.Delay(10); } while (timeSinceLastOutput.ElapsedMs < 200) { await Task.Delay(50); } return(processOutput); }
public static string GetHash(string path, Hash hashType, bool log = true) { string hashStr = ""; NmkdStopwatch sw = new NmkdStopwatch(); if (IsPathDirectory(path)) { Logger.Log($"Path '{path}' is directory! Returning empty hash.", true); return(hashStr); } try { var stream = File.OpenRead(path); if (hashType == Hash.MD5) { MD5 md5 = MD5.Create(); var hash = md5.ComputeHash(stream); hashStr = BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); } if (hashType == Hash.CRC32) { var crc = new Crc32Algorithm(); var crc32bytes = crc.ComputeHash(stream); hashStr = BitConverter.ToUInt32(crc32bytes, 0).ToString(); } stream.Close(); } catch (Exception e) { Logger.Log($"Error getting file hash for {Path.GetFileName(path)}: {e.Message}", true); return(""); } if (log) { Logger.Log($"Computed {hashType} for '{Path.GetFileNameWithoutExtension(path).Trunc(40) + Path.GetExtension(path)}' ({GetFilesizeStr(path)}): {hashStr} ({sw})", true); } return(hashStr); }
public static void SaveGrid(DataGridView grid) { NmkdStopwatch sw = new NmkdStopwatch(); Dictionary <string, string> dict = new Dictionary <string, string>(); foreach (DataGridViewRow row in grid.Rows) { string key = row.Cells[0].Value?.ToString(); string val = row.Cells[1].Value?.ToString(); if (key == null || val == null || string.IsNullOrWhiteSpace(key.Trim()) || string.IsNullOrWhiteSpace(val.Trim())) { continue; } dict.Add(key, val); } Config.Set(dict); Logger.Log($"Config Editor: Saved {grid.Rows.Count} config keys in {sw}", true); }
public static async Task <string> RunFfmpeg(string args, string workingDir, LogMode logMode, string loglevel, bool reliableOutput = true, bool progressBar = false) { bool show = Config.GetInt(Config.Key.cmdDebugMode) > 0; string processOutput = ""; Process ffmpeg = OsUtils.NewProcess(!show); NmkdStopwatch timeSinceLastOutput = new NmkdStopwatch(); lastAvProcess = ffmpeg; if (string.IsNullOrWhiteSpace(loglevel)) { loglevel = defLogLevel; } 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 {beforeArgs} {args}"; } if (logMode != LogMode.Hidden) { Logger.Log("Running FFmpeg...", false); } 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.PriorityClass = ProcessPriorityClass.BelowNormal; if (!show) { ffmpeg.BeginOutputReadLine(); ffmpeg.BeginErrorReadLine(); } while (!ffmpeg.HasExited) { await Task.Delay(10); } while (reliableOutput && timeSinceLastOutput.ElapsedMs < 200) { await Task.Delay(50); } if (progressBar) { Program.mainForm.SetProgress(0); } return(processOutput); }
static bool AreImagesCompatible(string inpath, int maxHeight) { NmkdStopwatch sw = new NmkdStopwatch(); string[] validExtensions = Filetypes.imagesInterpCompat; // = new string[] { ".jpg", ".jpeg", ".png" }; FileInfo[] files = IoUtils.GetFileInfosSorted(inpath); if (files.Length < 1) { Logger.Log("[AreImagesCompatible] Sequence not compatible: No files found.", true); return(false); } bool allSameExtension = files.All(x => x.Extension == files.First().Extension); if (!allSameExtension) { Logger.Log($"Sequence not compatible: Not all files have the same extension.", true); return(false); } bool allValidExtension = files.All(x => validExtensions.Contains(x.Extension)); if (!allValidExtension) { Logger.Log($"Sequence not compatible: Not all files have a valid extension ({string.Join(", ", validExtensions)}).", true); return(false); } int sampleCount = Config.GetInt(Config.Key.imgSeqSampleCount, 10); Image[] randomSamples = files.OrderBy(arg => Guid.NewGuid()).Take(sampleCount).Select(x => IoUtils.GetImage(x.FullName)).ToArray(); bool allSameSize = randomSamples.All(i => i.Size == randomSamples.First().Size); if (!allSameSize) { Logger.Log($"Sequence not compatible: Not all images have the same dimensions.", true); return(false); } int div = GetPadding(); bool allDivBy2 = randomSamples.All(i => (i.Width % div == 0) && (i.Height % div == 0)); if (!allDivBy2) { Logger.Log($"Sequence not compatible: Not all image dimensions are divisible by {div}.", true); return(false); } bool allSmallEnough = randomSamples.All(i => (i.Height <= maxHeight)); if (!allSmallEnough) { Logger.Log($"Sequence not compatible: Image dimensions above max size.", true); return(false); } bool all24Bit = randomSamples.All(i => (i.PixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb)); if (!all24Bit) { 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!", true); return(true); }