mirror of
https://github.com/n00mkrad/flowframes.git
synced 2025-12-23 03:39:26 +01:00
Hardcoded config key names to avoid string typos
This commit is contained in:
@@ -182,7 +182,7 @@ namespace Flowframes
|
||||
{
|
||||
try
|
||||
{
|
||||
bool alphaEnabled = Config.GetBool("enableAlpha", false);
|
||||
bool alphaEnabled = Config.GetBool(Config.Key.enableAlpha, false);
|
||||
bool outputSupportsAlpha = (outMode == Interpolate.OutMode.ImgPng || outMode == Interpolate.OutMode.VidGif);
|
||||
string ext = inputIsFrames ? Path.GetExtension(IOUtils.GetFilesSorted(inPath).First()).ToLower() : Path.GetExtension(inPath).ToLower();
|
||||
alpha = (alphaEnabled && outputSupportsAlpha && (ext == ".gif" || ext == ".png" || ext == ".apng"));
|
||||
@@ -199,8 +199,8 @@ namespace Flowframes
|
||||
public void RefreshExtensions()
|
||||
{
|
||||
bool pngOutput = outMode == Interpolate.OutMode.ImgPng;
|
||||
bool aviHqChroma = outMode == Interpolate.OutMode.VidAvi && Config.Get("aviColors") != "yuv420p";
|
||||
bool proresHqChroma = outMode == Interpolate.OutMode.VidProRes && Config.GetInt("proResProfile") > 3;
|
||||
bool aviHqChroma = outMode == Interpolate.OutMode.VidAvi && Config.Get(Config.Key.aviColors) != "yuv420p";
|
||||
bool proresHqChroma = outMode == Interpolate.OutMode.VidProRes && Config.GetInt(Config.Key.proResProfile) > 3;
|
||||
|
||||
bool forceHqChroma = pngOutput || aviHqChroma || proresHqChroma;
|
||||
|
||||
@@ -211,8 +211,8 @@ namespace Flowframes
|
||||
}
|
||||
else
|
||||
{
|
||||
framesExt = (Config.GetBool("jpegFrames") ? ".jpg" : ".png");
|
||||
interpExt = (Config.GetBool("jpegInterp") ? ".jpg" : ".png");
|
||||
framesExt = (Config.GetBool(Config.Key.jpegFrames) ? ".jpg" : ".png");
|
||||
interpExt = (Config.GetBool(Config.Key.jpegInterp) ? ".jpg" : ".png");
|
||||
}
|
||||
|
||||
Logger.Log($"RefreshExtensions - Using '{framesExt}' for imported frames, using '{interpExt}' for interpolated frames", true);
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Flowframes.Data
|
||||
{
|
||||
string[] lines = ffprobeOutput.SplitIntoLines();
|
||||
|
||||
if (!Config.GetBool("keepColorSpace", true))
|
||||
if (!Config.GetBool(Config.Key.keepColorSpace, true))
|
||||
return;
|
||||
|
||||
foreach (string line in lines)
|
||||
@@ -52,7 +52,7 @@ namespace Flowframes.Data
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line.Contains("display_aspect_ratio") && Config.GetBool("keepAspectRatio", true))
|
||||
if (line.Contains("display_aspect_ratio") && Config.GetBool(Config.Key.keepAspectRatio, true))
|
||||
{
|
||||
displayRatio = line.Split('=').LastOrDefault();
|
||||
continue;
|
||||
|
||||
@@ -339,7 +339,7 @@ namespace Flowframes
|
||||
if (!initialized)
|
||||
return;
|
||||
string aiName = GetAi().aiName.Replace("_", "-");
|
||||
if (!Program.busy && guiInterpFactor > 2 && !GetAi().supportsAnyExp && Config.GetInt("autoEncMode") > 0 && !Logger.GetLastLine().Contains(aiName))
|
||||
if (!Program.busy && guiInterpFactor > 2 && !GetAi().supportsAnyExp && Config.GetInt(Config.Key.autoEncMode) > 0 && !Logger.GetLastLine().Contains(aiName))
|
||||
Logger.Log($"Warning: {aiName} doesn't natively support 4x/8x and will run multiple times for {guiInterpFactor}x. Auto-Encode will only work on the last run.");
|
||||
}
|
||||
|
||||
@@ -509,7 +509,7 @@ namespace Flowframes
|
||||
if(stepSelector.SelectedIndex < 0)
|
||||
stepSelector.SelectedIndex = 0;
|
||||
|
||||
bool stepByStep = Config.GetInt("processingMode") == 1;
|
||||
bool stepByStep = Config.GetInt(Config.Key.processingMode) == 1;
|
||||
runBtn.Visible = !stepByStep && !Program.busy;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Flowframes.IO
|
||||
{
|
||||
@@ -21,10 +20,15 @@ namespace Flowframes.IO
|
||||
Reload();
|
||||
}
|
||||
|
||||
public static void Set(string key, string value)
|
||||
public static void Set(Key key, string value)
|
||||
{
|
||||
Set(key.ToString(), value);
|
||||
}
|
||||
|
||||
public static void Set(string str, string value)
|
||||
{
|
||||
Reload();
|
||||
cachedValues[key] = value;
|
||||
cachedValues[str] = value;
|
||||
WriteConfig();
|
||||
}
|
||||
|
||||
@@ -65,29 +69,57 @@ namespace Flowframes.IO
|
||||
}
|
||||
}
|
||||
|
||||
// Get using fixed key
|
||||
public static string Get(Key key, string defaultVal)
|
||||
{
|
||||
WriteIfDoesntExist(key.ToString(), defaultVal);
|
||||
return Get(key);
|
||||
}
|
||||
|
||||
// Get using string
|
||||
public static string Get(string key, string defaultVal)
|
||||
{
|
||||
WriteIfDoesntExist(key, defaultVal);
|
||||
return Get(key);
|
||||
}
|
||||
|
||||
public static string Get(Key key, Type type = Type.String)
|
||||
{
|
||||
return Get(key.ToString(), type);
|
||||
}
|
||||
|
||||
public static string Get(string key, Type type = Type.String)
|
||||
{
|
||||
string keyStr = key.ToString();
|
||||
|
||||
try
|
||||
{
|
||||
if (cachedValues.ContainsKey(key))
|
||||
return cachedValues[key];
|
||||
if (cachedValues.ContainsKey(keyStr))
|
||||
return cachedValues[keyStr];
|
||||
|
||||
return WriteDefaultValIfExists(key, type);
|
||||
return WriteDefaultValIfExists(key.ToString(), type);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log($"Failed to get {key.Wrap()} from config! {e.Message}");
|
||||
Logger.Log($"Failed to get {keyStr.Wrap()} from config! {e.Message}");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#region Get Bool
|
||||
|
||||
public static bool GetBool(Key key)
|
||||
{
|
||||
return bool.Parse(Get(key, Type.Bool));
|
||||
}
|
||||
|
||||
public static bool GetBool(Key key, bool defaultVal)
|
||||
{
|
||||
WriteIfDoesntExist(key.ToString(), (defaultVal ? "True" : "False"));
|
||||
return bool.Parse(Get(key, Type.Bool));
|
||||
}
|
||||
|
||||
public static bool GetBool(string key)
|
||||
{
|
||||
return bool.Parse(Get(key, Type.Bool));
|
||||
@@ -95,10 +127,25 @@ namespace Flowframes.IO
|
||||
|
||||
public static bool GetBool(string key, bool defaultVal)
|
||||
{
|
||||
WriteIfDoesntExist(key, (defaultVal ? "True" : "False"));
|
||||
WriteIfDoesntExist(key.ToString(), (defaultVal ? "True" : "False"));
|
||||
return bool.Parse(Get(key, Type.Bool));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get Int
|
||||
|
||||
public static int GetInt(Key key)
|
||||
{
|
||||
return Get(key, Type.Int).GetInt();
|
||||
}
|
||||
|
||||
public static int GetInt(Key key, int defaultVal)
|
||||
{
|
||||
WriteIfDoesntExist(key.ToString(), defaultVal.ToString());
|
||||
return GetInt(key);
|
||||
}
|
||||
|
||||
public static int GetInt(string key)
|
||||
{
|
||||
return Get(key, Type.Int).GetInt();
|
||||
@@ -106,10 +153,25 @@ namespace Flowframes.IO
|
||||
|
||||
public static int GetInt(string key, int defaultVal)
|
||||
{
|
||||
WriteIfDoesntExist(key, defaultVal.ToString());
|
||||
WriteIfDoesntExist(key.ToString(), defaultVal.ToString());
|
||||
return GetInt(key);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get Float
|
||||
|
||||
public static float GetFloat(Key key)
|
||||
{
|
||||
return float.Parse(Get(key, Type.Float), CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public static float GetFloat(Key key, float defaultVal)
|
||||
{
|
||||
WriteIfDoesntExist(key.ToString(), defaultVal.ToStringDot());
|
||||
return float.Parse(Get(key, Type.Float), CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public static float GetFloat(string key)
|
||||
{
|
||||
return float.Parse(Get(key, Type.Float), CultureInfo.InvariantCulture);
|
||||
@@ -117,75 +179,180 @@ namespace Flowframes.IO
|
||||
|
||||
public static float GetFloat(string key, float defaultVal)
|
||||
{
|
||||
WriteIfDoesntExist(key, defaultVal.ToStringDot());
|
||||
WriteIfDoesntExist(key.ToString(), defaultVal.ToStringDot());
|
||||
return float.Parse(Get(key, Type.Float), CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public static string GetFloatString (string key)
|
||||
public static string GetFloatString (Key key)
|
||||
{
|
||||
return Get(key, Type.Float).Replace(",", ".");
|
||||
}
|
||||
|
||||
public static string GetFloatString(string key)
|
||||
{
|
||||
return Get(key, Type.Float).Replace(",", ".");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
static void WriteIfDoesntExist (string key, string val)
|
||||
{
|
||||
if (cachedValues.ContainsKey(key))
|
||||
if (cachedValues.ContainsKey(key.ToString()))
|
||||
return;
|
||||
|
||||
Set(key, val);
|
||||
}
|
||||
|
||||
public enum Type { String, Int, Float, Bool }
|
||||
private static string WriteDefaultValIfExists(string key, Type type)
|
||||
private static string WriteDefaultValIfExists(string keyStr, Type type)
|
||||
{
|
||||
if (key == "maxVidHeight") return WriteDefault(key, "2160");
|
||||
if (key == "delLogsOnStartup") return WriteDefault(key, "True");
|
||||
if (key == "clearLogOnInput") return WriteDefault(key, "True");
|
||||
if (key == "tempDirCustom") return WriteDefault(key, "D:/");
|
||||
if (key == "exportNamePattern") return WriteDefault(key, "[NAME]-[FACTOR]x-[AI]-[MODEL]-[FPS]fps");
|
||||
if (key == "exportNamePatternLoop") return WriteDefault(key, "-Loop[LOOPS]");
|
||||
Key key;
|
||||
|
||||
try
|
||||
{
|
||||
key = (Key)Enum.Parse(typeof(Key), keyStr);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return WriteDefault(keyStr, "");
|
||||
}
|
||||
|
||||
if (key == Key.maxVidHeight) return WriteDefault(key, "2160");
|
||||
if (key == Key.delLogsOnStartup) return WriteDefault(key, "True");
|
||||
if (key == Key.clearLogOnInput) return WriteDefault(key, "True");
|
||||
if (key == Key.tempDirCustom) return WriteDefault(key, "D:/");
|
||||
if (key == Key.exportNamePattern) return WriteDefault(key, "[NAME]-[FACTOR]x-[AI]-[MODEL]-[FPS]fps");
|
||||
if (key == Key.exportNamePatternLoop) return WriteDefault(key, "-Loop[LOOPS]");
|
||||
// Interpolation
|
||||
if (key == "dedupThresh") return WriteDefault(key, "2");
|
||||
if (key == "keepAudio") return WriteDefault(key, "True");
|
||||
if (key == "keepSubs") return WriteDefault(key, "True");
|
||||
if (key == "keepMeta") return WriteDefault(key, "True");
|
||||
if (key == "autoDedupFrames") return WriteDefault(key, "100");
|
||||
if (key == "scnDetect") return WriteDefault(key, "True");
|
||||
if (key == "scnDetectValue") return WriteDefault(key, "0.2");
|
||||
if (key == "sceneChangeFillMode") return WriteDefault(key, "1");
|
||||
if (key == "autoEncMode") return WriteDefault(key, "2");
|
||||
if (key == "jpegFrames") return WriteDefault(key, "True");
|
||||
if (key == Key.dedupThresh) return WriteDefault(key, "2");
|
||||
if (key == Key.keepAudio) return WriteDefault(key, "True");
|
||||
if (key == Key.keepSubs) return WriteDefault(key, "True");
|
||||
if (key == Key.keepMeta) return WriteDefault(key, "True");
|
||||
if (key == Key.autoDedupFrames) return WriteDefault(key, "100");
|
||||
if (key == Key.scnDetect) return WriteDefault(key, "True");
|
||||
if (key == Key.scnDetectValue) return WriteDefault(key, "0.2");
|
||||
if (key == Key.sceneChangeFillMode) return WriteDefault(key, "1");
|
||||
if (key == Key.autoEncMode) return WriteDefault(key, "2");
|
||||
if (key == Key.jpegFrames) return WriteDefault(key, "True");
|
||||
// Video Export
|
||||
if (key == "minOutVidLength") return WriteDefault(key, "5");
|
||||
if (key == "h264Crf") return WriteDefault(key, "20");
|
||||
if (key == "h265Crf") return WriteDefault(key, "24");
|
||||
if (key == "av1Crf") return WriteDefault(key, "27");
|
||||
if (key == "vp9Crf") return WriteDefault(key, "28");
|
||||
if (key == "proResProfile") return WriteDefault(key, "2");
|
||||
if (key == "aviCodec") return WriteDefault(key, "ffv1");
|
||||
if (key == "imgSeqFormat") return WriteDefault(key, "PNG");
|
||||
if (key == "aviColors") return WriteDefault(key, "yuv420p");
|
||||
if (key == "gifColors") return WriteDefault(key, "128 (High)");
|
||||
if (key == "gifDitherType") return WriteDefault(key, "bayer (Recommended)");
|
||||
if (key == "minVidLength") return WriteDefault(key, "5");
|
||||
if (key == Key.minOutVidLength) return WriteDefault(key, "5");
|
||||
if (key == Key.h264Crf) return WriteDefault(key, "20");
|
||||
if (key == Key.h265Crf) return WriteDefault(key, "24");
|
||||
if (key == Key.av1Crf) return WriteDefault(key, "27");
|
||||
if (key == Key.vp9Crf) return WriteDefault(key, "28");
|
||||
if (key == Key.proResProfile) return WriteDefault(key, "2");
|
||||
if (key == Key.aviCodec) return WriteDefault(key, "ffv1");
|
||||
if (key == Key.imgSeqFormat) return WriteDefault(key, "PNG");
|
||||
if (key == Key.aviColors) return WriteDefault(key, "yuv420p");
|
||||
if (key == Key.gifColors) return WriteDefault(key, "128 (High)");
|
||||
if (key == Key.gifDitherType) return WriteDefault(key, "bayer (Recommended)");
|
||||
if (key == Key.minVidLength) return WriteDefault(key, "5");
|
||||
// AI
|
||||
if (key == "uhdThresh") return WriteDefault(key, "1600");
|
||||
if (key == "torchGpus") return WriteDefault(key, "0");
|
||||
if (key == "ncnnGpus") return WriteDefault(key, "0");
|
||||
if (key == "ncnnThreads") return WriteDefault(key, "1");
|
||||
if (key == "dainNcnnTilesize") return WriteDefault(key, "768");
|
||||
if (key == Key.uhdThresh) return WriteDefault(key, "1600");
|
||||
if (key == Key.torchGpus) return WriteDefault(key, "0");
|
||||
if (key == Key.ncnnGpus) return WriteDefault(key, "0");
|
||||
if (key == Key.ncnnThreads) return WriteDefault(key, "1");
|
||||
if (key == Key.dainNcnnTilesize) return WriteDefault(key, "768");
|
||||
// Debug / Other / Experimental
|
||||
if (key == "mdlBaseUrl") return WriteDefault(key, "https://dl.nmkd.de/flowframes/mdl/");
|
||||
if (key == "ffEncPreset") return WriteDefault(key, "medium");
|
||||
if (key == Key.mdlBaseUrl) return WriteDefault(key, "https://dl.nmkd.de/flowframes/mdl/");
|
||||
if (key == Key.ffEncPreset) return WriteDefault(key, "medium");
|
||||
|
||||
if (type == Type.Int || type == Type.Float) return WriteDefault(key, "0"); // Write default int/float (0)
|
||||
if (type == Type.Bool) return WriteDefault(key, "False"); // Write default bool (False)
|
||||
return WriteDefault(key, "");
|
||||
}
|
||||
|
||||
private static string WriteDefault(Key key, string def)
|
||||
{
|
||||
Set(key, def);
|
||||
return def;
|
||||
}
|
||||
|
||||
private static string WriteDefault(string key, string def)
|
||||
{
|
||||
Set(key, def);
|
||||
return def;
|
||||
}
|
||||
|
||||
public enum Key
|
||||
{
|
||||
aacBitrate,
|
||||
askedForDevModeVersion,
|
||||
aiCombox,
|
||||
allowConsecutiveSceneChanges,
|
||||
allowCustomInputRate,
|
||||
allowSymlinkEncoding,
|
||||
audioSubTransferMode,
|
||||
autoDedupFrames,
|
||||
autoEncDebug,
|
||||
autoEncMode,
|
||||
autoEncSafeBufferFlavrCuda,
|
||||
autoEncSafeBufferNcnn,
|
||||
autoEncSafeBufferRifeCuda,
|
||||
aviCodec,
|
||||
aviColors,
|
||||
clearLogOnInput,
|
||||
cmdDebugMode,
|
||||
compressedPyVersion,
|
||||
dainNcnnTilesize,
|
||||
dedupMode,
|
||||
dedupThresh,
|
||||
delLogsOnStartup,
|
||||
dupeScanDebug,
|
||||
enableAlpha,
|
||||
enableLoop,
|
||||
exportNamePattern,
|
||||
exportNamePatternLoop,
|
||||
fetchModelsFromRepo,
|
||||
ffEncArgs,
|
||||
ffEncPreset,
|
||||
ffEncThreads,
|
||||
ffprobeFrameCount,
|
||||
fixOutputDuration,
|
||||
frameOrderDebug,
|
||||
gifColors,
|
||||
gifDitherType,
|
||||
h264Crf,
|
||||
h265Crf,
|
||||
av1Crf,
|
||||
imgSeqFormat,
|
||||
jpegFrames,
|
||||
jpegInterp,
|
||||
keepAspectRatio,
|
||||
keepAudio,
|
||||
keepColorSpace,
|
||||
keepMeta,
|
||||
keepSubs,
|
||||
keepTempFolder,
|
||||
loopMode,
|
||||
lowDiskSpaceCancelGb,
|
||||
lowDiskSpacePauseGb,
|
||||
maxFps,
|
||||
maxFpsMode,
|
||||
maxVidHeight,
|
||||
mdlBaseUrl,
|
||||
minOutVidLength,
|
||||
minVidLength,
|
||||
mp4Enc,
|
||||
mpdecimateMode,
|
||||
ncnnGpus,
|
||||
ncnnThreads,
|
||||
opusBitrate,
|
||||
processingMode,
|
||||
proResProfile,
|
||||
rifeCudaBufferSize,
|
||||
rifeCudaFp16,
|
||||
rifeNcnnUseTta,
|
||||
sbsAllowAutoEnc,
|
||||
sceneChangeFillMode,
|
||||
scnDetect,
|
||||
scnDetectValue,
|
||||
silentDevmodeCheck,
|
||||
tempDirCustom,
|
||||
tempFolderLoc,
|
||||
torchGpus,
|
||||
uhdThresh,
|
||||
vp9Crf
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,7 +514,7 @@ namespace Flowframes.IO
|
||||
public static async Task<string> GetCurrentExportFilename(bool fpsLimit, bool withExt)
|
||||
{
|
||||
InterpSettings curr = Interpolate.current;
|
||||
string max = Config.Get("maxFps");
|
||||
string max = Config.Get(Config.Key.maxFps);
|
||||
Fraction maxFps = max.Contains("/") ? new Fraction(max) : new Fraction(max.GetFloat());
|
||||
float fps = fpsLimit ? maxFps.GetFloat() : curr.outFps.GetFloat();
|
||||
|
||||
@@ -522,9 +522,9 @@ namespace Flowframes.IO
|
||||
fps = 50f;
|
||||
|
||||
Size outRes = await InterpolateUtils.GetOutputResolution(curr.inPath, false, false);
|
||||
string pattern = Config.Get("exportNamePattern");
|
||||
string pattern = Config.Get(Config.Key.exportNamePattern);
|
||||
string inName = Interpolate.current.inputIsFrames ? Path.GetFileName(curr.inPath) : Path.GetFileNameWithoutExtension(curr.inPath);
|
||||
bool encodeBoth = Config.GetInt("maxFpsMode") == 0;
|
||||
bool encodeBoth = Config.GetInt(Config.Key.maxFpsMode) == 0;
|
||||
bool addSuffix = fpsLimit && (!pattern.Contains("[FPS]") && !pattern.Contains("[ROUNDFPS]")) && encodeBoth;
|
||||
string filename = pattern;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Flowframes.IO
|
||||
|
||||
static string GetMdlUrl (string ai, string model)
|
||||
{
|
||||
string baseUrl = Config.Get("mdlBaseUrl");
|
||||
string baseUrl = Config.Get(Config.Key.mdlBaseUrl);
|
||||
return Path.Combine(baseUrl, ai.ToLower(), model);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Flowframes.Magick
|
||||
if(setStatus)
|
||||
Program.mainForm.SetStatus("Running frame de-duplication");
|
||||
|
||||
currentThreshold = Config.GetFloat("dedupThresh");
|
||||
currentThreshold = Config.GetFloat(Config.Key.dedupThresh);
|
||||
Logger.Log("Running accurate frame de-duplication...");
|
||||
|
||||
if (currentMode == Mode.Enabled || currentMode == Mode.Auto)
|
||||
@@ -72,7 +72,7 @@ namespace Flowframes.Magick
|
||||
int statsFramesKept = 0;
|
||||
int statsFramesDeleted = 0;
|
||||
|
||||
int skipAfterNoDupesFrames = Config.GetInt("autoDedupFrames");
|
||||
int skipAfterNoDupesFrames = Config.GetInt(Config.Key.autoDedupFrames);
|
||||
bool hasEncounteredAnyDupes = false;
|
||||
bool skipped = false;
|
||||
|
||||
|
||||
@@ -34,13 +34,13 @@ namespace Flowframes.Main
|
||||
safetyBufferFrames = 90;
|
||||
|
||||
if (Interpolate.current.ai.aiName.ToUpper().Contains("NCNN"))
|
||||
safetyBufferFrames = Config.GetInt("autoEncSafeBufferNcnn", 150);
|
||||
safetyBufferFrames = Config.GetInt(Config.Key.autoEncSafeBufferNcnn, 150);
|
||||
|
||||
if (Interpolate.current.ai.aiName == Networks.rifeCuda.aiName)
|
||||
safetyBufferFrames = Config.GetInt("autoEncSafeBufferRifeCuda", 90);
|
||||
safetyBufferFrames = Config.GetInt(Config.Key.autoEncSafeBufferRifeCuda, 90);
|
||||
|
||||
if (Interpolate.current.ai.aiName == Networks.flavrCuda.aiName)
|
||||
safetyBufferFrames = Config.GetInt("autoEncSafeBufferFlavrCuda", 90);
|
||||
safetyBufferFrames = Config.GetInt(Config.Key.autoEncSafeBufferFlavrCuda, 90);
|
||||
}
|
||||
|
||||
public static async Task MainLoop(string interpFramesPath)
|
||||
@@ -117,7 +117,7 @@ namespace Flowframes.Main
|
||||
|
||||
if (Interpolate.canceled) return;
|
||||
|
||||
if (aiRunning && Config.GetInt("autoEncMode") == 2)
|
||||
if (aiRunning && Config.GetInt(Config.Key.autoEncMode) == 2)
|
||||
Task.Run(() => DeleteOldFramesAsync(interpFramesPath, frameLinesToEncode));
|
||||
|
||||
if (Interpolate.canceled) return;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Flowframes.Main
|
||||
|
||||
public static async void Start()
|
||||
{
|
||||
if (Config.GetBool("clearLogOnInput"))
|
||||
if (Config.GetBool(Config.Key.clearLogOnInput))
|
||||
Logger.ClearLogBox();
|
||||
|
||||
stopped = false;
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Flowframes.Main
|
||||
|
||||
public static async Task Export(string path, string outFolder, I.OutMode mode, bool stepByStep)
|
||||
{
|
||||
if(Config.GetInt("sceneChangeFillMode") == 1)
|
||||
if(Config.GetInt(Config.Key.sceneChangeFillMode) == 1)
|
||||
{
|
||||
string frameFile = Path.Combine(I.current.tempFolder, Paths.GetFrameOrderFilename(I.current.interpFactor));
|
||||
await Blend.BlendSceneChanges(frameFile);
|
||||
@@ -52,10 +52,10 @@ namespace Flowframes.Main
|
||||
|
||||
try
|
||||
{
|
||||
string max = Config.Get("maxFps");
|
||||
string max = Config.Get(Config.Key.maxFps);
|
||||
Fraction maxFps = max.Contains("/") ? new Fraction(max) : new Fraction(max.GetFloat());
|
||||
bool fpsLimit = maxFps.GetFloat() > 0f && I.current.outFps.GetFloat() > maxFps.GetFloat();
|
||||
bool dontEncodeFullFpsVid = fpsLimit && Config.GetInt("maxFpsMode") == 0;
|
||||
bool dontEncodeFullFpsVid = fpsLimit && Config.GetInt(Config.Key.maxFpsMode) == 0;
|
||||
|
||||
if (!dontEncodeFullFpsVid)
|
||||
await Encode(mode, path, Path.Combine(outFolder, await IOUtils.GetCurrentExportFilename(false, true)), I.current.outFps, new Fraction());
|
||||
@@ -73,12 +73,12 @@ namespace Flowframes.Main
|
||||
static async Task ExportFrames (string framesPath, bool stepByStep)
|
||||
{
|
||||
Program.mainForm.SetStatus("Copying output frames...");
|
||||
string desiredFormat = Config.Get("imgSeqFormat").ToUpper();
|
||||
string desiredFormat = Config.Get(Config.Key.imgSeqFormat).ToUpper();
|
||||
string availableFormat = Path.GetExtension(IOUtils.GetFilesSorted(framesPath)[0]).Remove(".").ToUpper();
|
||||
string max = Config.Get("maxFps");
|
||||
string max = Config.Get(Config.Key.maxFps);
|
||||
Fraction maxFps = max.Contains("/") ? new Fraction(max) : new Fraction(max.GetFloat());
|
||||
bool fpsLimit = maxFps.GetFloat() > 0f && I.current.outFps.GetFloat() > maxFps.GetFloat();
|
||||
bool dontEncodeFullFpsVid = fpsLimit && Config.GetInt("maxFpsMode") == 0;
|
||||
bool dontEncodeFullFpsVid = fpsLimit && Config.GetInt(Config.Key.maxFpsMode) == 0;
|
||||
string framesFile = Path.Combine(framesPath.GetParentDir(), Paths.GetFrameOrderFilename(I.current.interpFactor));
|
||||
|
||||
|
||||
@@ -142,14 +142,14 @@ namespace Flowframes.Main
|
||||
|
||||
if (!File.Exists(framesFile))
|
||||
{
|
||||
bool sbs = Config.GetInt("processingMode") == 1;
|
||||
bool sbs = Config.GetInt(Config.Key.processingMode) == 1;
|
||||
I.Cancel($"Frame order file for this interpolation factor not found!{(sbs ? "\n\nDid you run the interpolation step with the current factor?" : "")}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == I.OutMode.VidGif)
|
||||
{
|
||||
await FfmpegEncode.FramesToGifConcat(framesFile, outPath, fps, true, Config.GetInt("gifColors"), resampleFps);
|
||||
await FfmpegEncode.FramesToGifConcat(framesFile, outPath, fps, true, Config.GetInt(Config.Key.gifColors), resampleFps);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -209,15 +209,15 @@ namespace Flowframes.Main
|
||||
string framesFileChunk = Path.Combine(I.current.tempFolder, Paths.GetFrameOrderFilenameChunk(firstFrameNum, firstFrameNum + framesAmount));
|
||||
File.WriteAllLines(framesFileChunk, IOUtils.ReadLines(framesFileFull).Skip(firstFrameNum).Take(framesAmount));
|
||||
|
||||
if (Config.GetInt("sceneChangeFillMode") == 1)
|
||||
if (Config.GetInt(Config.Key.sceneChangeFillMode) == 1)
|
||||
await Blend.BlendSceneChanges(framesFileChunk, false);
|
||||
|
||||
string max = Config.Get("maxFps");
|
||||
string max = Config.Get(Config.Key.maxFps);
|
||||
Fraction maxFps = max.Contains("/") ? new Fraction(max) : new Fraction(max.GetFloat());
|
||||
bool fpsLimit = maxFps.GetFloat() != 0 && I.current.outFps.GetFloat() > maxFps.GetFloat();
|
||||
VidExtraData extraData = await FfmpegCommands.GetVidExtraInfo(I.current.inPath);
|
||||
|
||||
bool dontEncodeFullFpsVid = fpsLimit && Config.GetInt("maxFpsMode") == 0;
|
||||
bool dontEncodeFullFpsVid = fpsLimit && Config.GetInt(Config.Key.maxFpsMode) == 0;
|
||||
|
||||
if (!dontEncodeFullFpsVid)
|
||||
await FfmpegEncode.FramesToVideo(framesFileChunk, outPath, mode, I.current.outFps, new Fraction(), extraData, AvProcess.LogMode.Hidden, true); // Encode
|
||||
@@ -233,15 +233,15 @@ namespace Flowframes.Main
|
||||
|
||||
static async Task Loop(string outPath, int looptimes)
|
||||
{
|
||||
if (looptimes < 1 || !Config.GetBool("enableLoop")) return;
|
||||
Logger.Log($"Looping {looptimes} {(looptimes == 1 ? "time" : "times")} to reach target length of {Config.GetInt("minOutVidLength")}s...");
|
||||
await FfmpegCommands.LoopVideo(outPath, looptimes, Config.GetInt("loopMode") == 0);
|
||||
if (looptimes < 1 || !Config.GetBool(Config.Key.enableLoop)) return;
|
||||
Logger.Log($"Looping {looptimes} {(looptimes == 1 ? "time" : "times")} to reach target length of {Config.GetInt(Config.Key.minOutVidLength)}s...");
|
||||
await FfmpegCommands.LoopVideo(outPath, looptimes, Config.GetInt(Config.Key.loopMode) == 0);
|
||||
}
|
||||
|
||||
static async Task<int> GetLoopTimes()
|
||||
{
|
||||
int times = -1;
|
||||
int minLength = Config.GetInt("minOutVidLength");
|
||||
int minLength = Config.GetInt(Config.Key.minOutVidLength);
|
||||
int minFrameCount = (minLength * I.current.outFps.GetFloat()).RoundToInt();
|
||||
int outFrames = ((await I.GetCurrentInputFrameCount()) * I.current.interpFactor).RoundToInt();
|
||||
if (outFrames / I.current.outFps.GetFloat() < minLength)
|
||||
@@ -259,12 +259,12 @@ namespace Flowframes.Main
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Config.GetBool("keepAudio") && !Config.GetBool("keepAudio"))
|
||||
if (!Config.GetBool(Config.Key.keepAudio) && !Config.GetBool(Config.Key.keepAudio))
|
||||
return;
|
||||
|
||||
Program.mainForm.SetStatus("Muxing audio/subtitles into video...");
|
||||
|
||||
bool muxFromInput = Config.GetInt("audioSubTransferMode") == 0;
|
||||
bool muxFromInput = Config.GetInt(Config.Key.audioSubTransferMode) == 0;
|
||||
|
||||
if (muxFromInput && I.current.inputIsFrames)
|
||||
{
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace Flowframes.Main
|
||||
if (Interpolate.canceled) return;
|
||||
Logger.Log($"Generating frame order information for {interpFactor}x...", false, true);
|
||||
|
||||
bool loop = Config.GetBool("enableLoop");
|
||||
bool loop = Config.GetBool(Config.Key.enableLoop);
|
||||
bool sceneDetection = true;
|
||||
string ext = Interpolate.current.interpExt;
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace Flowframes.Main
|
||||
fileContent += frameFileContents[x];
|
||||
|
||||
lastOutFileCount++;
|
||||
int lastFrameTimes = Config.GetBool("fixOutputDuration") ? (int)interpFactor : 1;
|
||||
int lastFrameTimes = Config.GetBool(Config.Key.fixOutputDuration) ? (int)interpFactor : 1;
|
||||
|
||||
for(int i = 0; i < lastFrameTimes; i++)
|
||||
fileContent += $"{(i > 0 ? "\n" : "")}file '{Paths.interpDir}/{lastOutFileCount.ToString().PadLeft(Padding.interpFrames, '0')}{ext}'"; // Last frame (source)
|
||||
@@ -137,7 +137,7 @@ namespace Flowframes.Main
|
||||
totalFileCount++;
|
||||
fileContent = WriteFrameWithDupes(dupesAmount, fileContent, totalFileCount, ext, debug, $"[In: {frameName}] [{((frm == 0) ? " Source " : $"Interp {frm}")}]", scnChangeNote);
|
||||
|
||||
if (Config.GetInt("sceneChangeFillMode") == 0) // Duplicate last frame
|
||||
if (Config.GetInt(Config.Key.sceneChangeFillMode) == 0) // Duplicate last frame
|
||||
{
|
||||
int lastNum = totalFileCount;
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace Flowframes
|
||||
if(!currentlyUsingAutoEnc)
|
||||
await CreateVideo.Export(current.interpFolder, current.outPath, current.outMode, false);
|
||||
|
||||
if (Config.GetBool("keepTempFolder"))
|
||||
if (Config.GetBool(Config.Key.keepTempFolder))
|
||||
await Task.Run(async () => { await FrameRename.Unrename(); });
|
||||
|
||||
await Cleanup();
|
||||
@@ -85,7 +85,7 @@ namespace Flowframes
|
||||
{
|
||||
current.RefreshAlpha();
|
||||
|
||||
if (Config.GetBool("scnDetect"))
|
||||
if (Config.GetBool(Config.Key.scnDetect))
|
||||
{
|
||||
Program.mainForm.SetStatus("Extracting scenes from video...");
|
||||
await FfmpegExtract.ExtractSceneChanges(current.inPath, Path.Combine(current.tempFolder, Paths.scenesDir), current.inFpsDetected, current.inputIsFrames, current.framesExt);
|
||||
@@ -101,7 +101,7 @@ namespace Flowframes
|
||||
{
|
||||
if (canceled) return;
|
||||
Program.mainForm.SetStatus("Extracting frames from video...");
|
||||
bool mpdecimate = Config.GetInt("dedupMode") == 2;
|
||||
bool mpdecimate = Config.GetInt(Config.Key.dedupMode) == 2;
|
||||
Size res = await Utils.GetOutputResolution(inPath, true, true);
|
||||
await FfmpegExtract.VideoToFrames(inPath, outPath, alpha, current.inFpsDetected, mpdecimate, false, res, current.framesExt);
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace Flowframes
|
||||
|
||||
if (canceled) return;
|
||||
|
||||
if (Config.GetBool("keepAudio") && Config.GetInt("audioSubTransferMode") == 1)
|
||||
if (Config.GetBool(Config.Key.keepAudio) && Config.GetInt(Config.Key.audioSubTransferMode) == 1)
|
||||
{
|
||||
Program.mainForm.SetStatus("Extracting audio from video...");
|
||||
await FfmpegAudioAndMetadata.ExtractAudioTracks(inPath, current.tempFolder);
|
||||
@@ -131,7 +131,7 @@ namespace Flowframes
|
||||
|
||||
if (canceled) return;
|
||||
|
||||
if (Config.GetBool("keepSubs") && Config.GetInt("audioSubTransferMode") == 1)
|
||||
if (Config.GetBool(Config.Key.keepSubs) && Config.GetInt(Config.Key.audioSubTransferMode) == 1)
|
||||
{
|
||||
Program.mainForm.SetStatus("Extracting subtitles from video...");
|
||||
await FfmpegAudioAndMetadata.ExtractSubtitles(inPath, current.tempFolder, current.outMode);
|
||||
@@ -153,12 +153,12 @@ namespace Flowframes
|
||||
Cancel("Frame extraction failed!\n\nYour input file might be incompatible.");
|
||||
}
|
||||
|
||||
if (Config.GetInt("dedupMode") == 1)
|
||||
if (Config.GetInt(Config.Key.dedupMode) == 1)
|
||||
await Dedupe.Run(current.framesFolder);
|
||||
else
|
||||
Dedupe.ClearCache();
|
||||
|
||||
if (!Config.GetBool("enableLoop"))
|
||||
if (!Config.GetBool(Config.Key.enableLoop))
|
||||
{
|
||||
await Utils.CopyLastFrame(currentInputFrameCount);
|
||||
}
|
||||
@@ -190,7 +190,7 @@ namespace Flowframes
|
||||
|
||||
await Task.Run(async () => { await Dedupe.CreateDupesFile(current.framesFolder, currentInputFrameCount, current.framesExt); });
|
||||
await Task.Run(async () => { await FrameRename.Rename(); });
|
||||
await Task.Run(async () => { await FrameOrder.CreateFrameOrderFile(current.framesFolder, Config.GetBool("enableLoop"), current.interpFactor); });
|
||||
await Task.Run(async () => { await FrameOrder.CreateFrameOrderFile(current.framesFolder, Config.GetBool(Config.Key.enableLoop), current.interpFactor); });
|
||||
|
||||
Program.mainForm.SetStatus("Downloading models...");
|
||||
await ModelDownloader.DownloadModelFiles(ai, current.model.dir);
|
||||
@@ -212,7 +212,7 @@ namespace Flowframes
|
||||
tasks.Add(AiProcess.RunFlavrCuda(current.framesFolder, current.interpFactor, current.model.dir));
|
||||
|
||||
if (ai.aiName == Networks.dainNcnn.aiName)
|
||||
tasks.Add(AiProcess.RunDainNcnn(current.framesFolder, outpath, current.interpFactor, current.model.dir, Config.GetInt("dainNcnnTilesize", 512)));
|
||||
tasks.Add(AiProcess.RunDainNcnn(current.framesFolder, outpath, current.interpFactor, current.model.dir, Config.GetInt(Config.Key.dainNcnnTilesize, 512)));
|
||||
|
||||
if (currentlyUsingAutoEnc)
|
||||
{
|
||||
@@ -232,7 +232,7 @@ namespace Flowframes
|
||||
AiProcess.Kill();
|
||||
AvProcess.Kill();
|
||||
|
||||
if (!current.stepByStep && !Config.GetBool("keepTempFolder"))
|
||||
if (!current.stepByStep && !Config.GetBool(Config.Key.keepTempFolder))
|
||||
{
|
||||
if(false /* IOUtils.GetAmountOfFiles(Path.Combine(current.tempFolder, Paths.resumeDir), true) > 0 */) // TODO: Uncomment for 1.23
|
||||
{
|
||||
@@ -257,7 +257,7 @@ namespace Flowframes
|
||||
|
||||
public static async Task Cleanup(bool ignoreKeepSetting = false, int retriesLeft = 3, bool isRetry = false)
|
||||
{
|
||||
if ((!ignoreKeepSetting && Config.GetBool("keepTempFolder")) || !Program.busy) return;
|
||||
if ((!ignoreKeepSetting && Config.GetBool(Config.Key.keepTempFolder)) || !Program.busy) return;
|
||||
if (!isRetry)
|
||||
Logger.Log("Deleting temporary files...");
|
||||
try
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace Flowframes.Main
|
||||
|
||||
currentInputFrameCount = await GetFrameCountCached.GetFrameCountAsync(current.inPath);
|
||||
|
||||
if (Config.GetBool("sbsAllowAutoEnc") && !(await InterpolateUtils.CheckEncoderValid())) return;
|
||||
if (Config.GetBool(Config.Key.sbsAllowAutoEnc) && !(await InterpolateUtils.CheckEncoderValid())) return;
|
||||
|
||||
if (canceled) return;
|
||||
Program.mainForm.SetStatus("Running AI...");
|
||||
|
||||
@@ -75,18 +75,18 @@ namespace Flowframes.Main
|
||||
{
|
||||
string basePath = inPath.GetParentDir();
|
||||
|
||||
if (Config.GetInt("tempFolderLoc") == 1)
|
||||
if (Config.GetInt(Config.Key.tempFolderLoc) == 1)
|
||||
basePath = outPath.GetParentDir();
|
||||
|
||||
if (Config.GetInt("tempFolderLoc") == 2)
|
||||
if (Config.GetInt(Config.Key.tempFolderLoc) == 2)
|
||||
basePath = outPath;
|
||||
|
||||
if (Config.GetInt("tempFolderLoc") == 3)
|
||||
if (Config.GetInt(Config.Key.tempFolderLoc) == 3)
|
||||
basePath = Paths.GetExeDir();
|
||||
|
||||
if (Config.GetInt("tempFolderLoc") == 4)
|
||||
if (Config.GetInt(Config.Key.tempFolderLoc) == 4)
|
||||
{
|
||||
string custPath = Config.Get("tempDirCustom");
|
||||
string custPath = Config.Get(Config.Key.tempDirCustom);
|
||||
if (IOUtils.IsDirValid(custPath))
|
||||
basePath = custPath;
|
||||
}
|
||||
@@ -118,7 +118,9 @@ namespace Flowframes.Main
|
||||
passes = false;
|
||||
}
|
||||
|
||||
if (outMode == I.OutMode.VidGif && fpsOut.GetFloat() > 50 && !(Config.GetFloat("maxFps") != 0 && Config.GetFloat("maxFps") <= 50))
|
||||
Fraction fpsLimit = new Fraction(Config.Get(Config.Key.maxFps));
|
||||
|
||||
if (outMode == I.OutMode.VidGif && fpsOut.GetFloat() > 50 && !(fpsLimit.GetFloat() > 0 && fpsLimit.GetFloat() <= 50))
|
||||
Logger.Log($"Warning: GIF will be encoded at 50 FPS instead of {fpsOut.GetFloat()} as the format doesn't support frame rates that high.");
|
||||
|
||||
if (!passes)
|
||||
@@ -222,11 +224,13 @@ namespace Flowframes.Main
|
||||
|
||||
public static Size GetOutputResolution(Size inputRes, bool print = false, bool returnZeroIfUnchanged = false)
|
||||
{
|
||||
int maxHeight = RoundDivisibleBy(Config.GetInt("maxVidHeight"), FfmpegCommands.GetPadding());
|
||||
int maxHeightValue = Config.GetInt(Config.Key.maxVidHeight);
|
||||
int maxHeight = RoundDivisibleBy(maxHeightValue, FfmpegCommands.GetPadding());
|
||||
|
||||
if (inputRes.Height > maxHeight)
|
||||
{
|
||||
float factor = (float)maxHeight / inputRes.Height;
|
||||
Logger.Log($"Un-rounded downscaled size: {(inputRes.Width * factor).ToString("0.00")}x{Config.GetInt("maxVidHeight")}", true);
|
||||
Logger.Log($"Un-rounded downscaled size: {(inputRes.Width * factor).ToString("0.00")}x{maxHeightValue}", true);
|
||||
int width = RoundDivisibleBy((inputRes.Width * factor).RoundToInt(), FfmpegCommands.GetPadding());
|
||||
if (print)
|
||||
Logger.Log($"Video is bigger than the maximum - Downscaling to {width}x{maxHeight}.");
|
||||
@@ -264,13 +268,13 @@ namespace Flowframes.Main
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stepByStep && !Config.GetBool("sbsAllowAutoEnc"))
|
||||
if (stepByStep && !Config.GetBool(Config.Key.sbsAllowAutoEnc))
|
||||
{
|
||||
Logger.Log($"Not Using AutoEnc: Using step-by-step mode, but 'sbsAllowAutoEnc' is false.", true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!stepByStep && Config.GetInt("autoEncMode") == 0)
|
||||
if (!stepByStep && Config.GetInt(Config.Key.autoEncMode) == 0)
|
||||
{
|
||||
Logger.Log($"Not Using AutoEnc: 'autoEncMode' is 0.", true);
|
||||
return false;
|
||||
@@ -288,7 +292,7 @@ namespace Flowframes.Main
|
||||
|
||||
public static async Task<bool> UseUhd()
|
||||
{
|
||||
return (await GetOutputResolution(I.current.inPath, false)).Height >= Config.GetInt("uhdThresh");
|
||||
return (await GetOutputResolution(I.current.inPath, false)).Height >= Config.GetInt(Config.Key.uhdThresh);
|
||||
}
|
||||
|
||||
public static void FixConsecutiveSceneFrames(string sceneFramesPath, string sourceFramesPath)
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Flowframes.Media
|
||||
{
|
||||
if (mode == Interpolate.OutMode.VidMp4 || mode == Interpolate.OutMode.VidMkv)
|
||||
{
|
||||
int mp4Enc = Config.GetInt("mp4Enc");
|
||||
int mp4Enc = Config.GetInt(Config.Key.mp4Enc);
|
||||
if (mp4Enc == 0) return Codec.H264;
|
||||
if (mp4Enc == 1) return Codec.H265;
|
||||
if (mp4Enc == 2) return Codec.H264NVENC;
|
||||
@@ -46,7 +46,7 @@ namespace Flowframes.Media
|
||||
case Codec.AV1: return "libsvtav1";
|
||||
case Codec.VP9: return "libvpx-vp9";
|
||||
case Codec.ProRes: return "prores_ks";
|
||||
case Codec.AviRaw: return Config.Get("aviCodec");
|
||||
case Codec.AviRaw: return Config.Get(Config.Key.aviCodec);
|
||||
}
|
||||
return "libx264";
|
||||
}
|
||||
@@ -57,50 +57,50 @@ namespace Flowframes.Media
|
||||
|
||||
if(codec == Codec.H264)
|
||||
{
|
||||
string preset = Config.Get("ffEncPreset").ToLower().Remove(" ");
|
||||
args += $"-crf {Config.GetInt("h264Crf")} -preset {preset} -pix_fmt yuv420p";
|
||||
string preset = Config.Get(Config.Key.ffEncPreset).ToLower().Remove(" ");
|
||||
args += $"-crf {Config.GetInt(Config.Key.h264Crf)} -preset {preset} -pix_fmt yuv420p";
|
||||
}
|
||||
|
||||
if (codec == Codec.H265)
|
||||
{
|
||||
string preset = Config.Get("ffEncPreset").ToLower().Remove(" ");
|
||||
int crf = Config.GetInt("h265Crf");
|
||||
string preset = Config.Get(Config.Key.ffEncPreset).ToLower().Remove(" ");
|
||||
int crf = Config.GetInt(Config.Key.h265Crf);
|
||||
args += $"{(crf > 0 ? $"-crf {crf}" : "-x265-params lossless=1")} -preset {preset} -pix_fmt yuv420p";
|
||||
}
|
||||
|
||||
if (codec == Codec.H264NVENC)
|
||||
{
|
||||
int cq = (Config.GetInt("h264Crf") * 1.1f).RoundToInt();
|
||||
int cq = (Config.GetInt(Config.Key.h264Crf) * 1.1f).RoundToInt();
|
||||
args += $"-b:v 0 {(cq > 0 ? $"-cq {cq} -preset p7" : "-preset lossless")} -pix_fmt yuv420p";
|
||||
}
|
||||
|
||||
if (codec == Codec.H265NVENC)
|
||||
{
|
||||
int cq = (Config.GetInt("h265Crf") * 1.1f).RoundToInt();
|
||||
int cq = (Config.GetInt(Config.Key.h265Crf) * 1.1f).RoundToInt();
|
||||
args += $"-b:v 0 {(cq > 0 ? $"-cq {cq} -preset p7" : "-preset lossless")} -pix_fmt yuv420p";
|
||||
}
|
||||
|
||||
if (codec == Codec.AV1)
|
||||
{
|
||||
int cq = (Config.GetInt("av1Crf") * 1.0f).RoundToInt();
|
||||
int cq = (Config.GetInt(Config.Key.av1Crf) * 1.0f).RoundToInt();
|
||||
args += $"-b:v 0 -qp {cq} -g 240 {GetSvtAv1Speed()} -tile_rows 2 -tile_columns 2 -pix_fmt yuv420p";
|
||||
}
|
||||
|
||||
if (codec == Codec.VP9)
|
||||
{
|
||||
int crf = Config.GetInt("vp9Crf");
|
||||
int crf = Config.GetInt(Config.Key.vp9Crf);
|
||||
string qualityStr = (crf > 0) ? $"-b:v 0 -crf {crf}" : "-lossless 1";
|
||||
args += $"{qualityStr} {GetVp9Speed()} -tile-columns 2 -tile-rows 2 -row-mt 1 -pix_fmt yuv420p";
|
||||
}
|
||||
|
||||
if(codec == Codec.ProRes)
|
||||
{
|
||||
args += $"-profile:v {Config.GetInt("proResProfile")} -pix_fmt yuv420p";
|
||||
args += $"-profile:v {Config.GetInt(Config.Key.proResProfile)} -pix_fmt yuv420p";
|
||||
}
|
||||
|
||||
if (codec == Codec.AviRaw)
|
||||
{
|
||||
args += $"-pix_fmt {Config.Get("aviColors")}";
|
||||
args += $"-pix_fmt {Config.Get(Config.Key.aviColors)}";
|
||||
}
|
||||
|
||||
return args;
|
||||
@@ -108,7 +108,7 @@ namespace Flowframes.Media
|
||||
|
||||
static string GetVp9Speed ()
|
||||
{
|
||||
string preset = Config.Get("ffEncPreset").ToLower().Remove(" ");
|
||||
string preset = Config.Get(Config.Key.ffEncPreset).ToLower().Remove(" ");
|
||||
string arg = "";
|
||||
|
||||
if (preset == "veryslow") arg = "0";
|
||||
@@ -124,7 +124,7 @@ namespace Flowframes.Media
|
||||
|
||||
static string GetSvtAv1Speed()
|
||||
{
|
||||
string preset = Config.Get("ffEncPreset").ToLower().Remove(" ");
|
||||
string preset = Config.Get(Config.Key.ffEncPreset).ToLower().Remove(" ");
|
||||
string arg = "";
|
||||
|
||||
if (preset == "veryslow") arg = "2";
|
||||
@@ -225,12 +225,12 @@ namespace Flowframes.Media
|
||||
public static string GetAudioFallbackArgs (Interpolate.OutMode outMode)
|
||||
{
|
||||
string codec = "aac";
|
||||
string bitrate = $"{Config.GetInt("aacBitrate", 160)}";
|
||||
string bitrate = $"{Config.GetInt(Config.Key.aacBitrate, 160)}";
|
||||
|
||||
if(outMode == Interpolate.OutMode.VidMkv || outMode == Interpolate.OutMode.VidWebm)
|
||||
{
|
||||
codec = "libopus";
|
||||
bitrate = $"{Config.GetInt("opusBitrate", 128)}";
|
||||
bitrate = $"{Config.GetInt(Config.Key.opusBitrate, 128)}";
|
||||
}
|
||||
|
||||
return $"-c:a {codec} -b:a {bitrate}k -ac 2";
|
||||
@@ -263,7 +263,7 @@ namespace Flowframes.Media
|
||||
bool supported = (containerExt == "mp4" || containerExt == "mkv" || containerExt == "webm" || containerExt == "mov");
|
||||
Logger.Log($"Subtitles {(supported ? "are supported" : "not supported")} by {containerExt.ToUpper()}", true);
|
||||
|
||||
if (showWarningIfNotSupported && Config.GetBool("keepSubs") && !supported)
|
||||
if (showWarningIfNotSupported && Config.GetBool(Config.Key.keepSubs) && !supported)
|
||||
Logger.Log($"Warning: Subtitle transfer is enabled, but {containerExt.ToUpper()} does not support subtitles properly. MKV is recommended instead.");
|
||||
|
||||
return supported;
|
||||
|
||||
@@ -194,9 +194,9 @@ namespace Flowframes.Media
|
||||
if (!audioCompat)
|
||||
Logger.Log("Warning: Input audio format(s) not fully supported in output container - Will re-encode.", true, false, "ffmpeg");
|
||||
|
||||
bool audio = Config.GetBool("keepAudio");
|
||||
bool subs = Config.GetBool("keepSubs");
|
||||
bool meta = Config.GetBool("keepMeta");
|
||||
bool audio = Config.GetBool(Config.Key.keepAudio);
|
||||
bool subs = Config.GetBool(Config.Key.keepSubs);
|
||||
bool meta = Config.GetBool(Config.Key.keepMeta);
|
||||
|
||||
if (!audio)
|
||||
audioArgs = "-an";
|
||||
@@ -251,8 +251,8 @@ namespace Flowframes.Media
|
||||
string inName = Path.GetFileName(tempPath);
|
||||
string outName = Path.GetFileName(outPath);
|
||||
|
||||
bool audio = Config.GetBool("keepAudio");
|
||||
bool subs = Config.GetBool("keepSubs") && Utils.ContainerSupportsSubs(containerExt, false);
|
||||
bool audio = Config.GetBool(Config.Key.keepAudio);
|
||||
bool subs = Config.GetBool(Config.Key.keepSubs) && Utils.ContainerSupportsSubs(containerExt, false);
|
||||
|
||||
string[] audioTracks = audio ? IOUtils.GetFilesSorted(tempFolder, false, "*_audio.*") : new string[0]; // Find audio files
|
||||
string[] subTracks = subs ? IOUtils.GetFilesSorted(tempFolder, false, "*.srt") : new string[0]; // Find subtitle files
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Flowframes
|
||||
{
|
||||
string pathNoExt = Path.ChangeExtension(inputFile, null);
|
||||
string ext = Path.GetExtension(inputFile);
|
||||
string loopSuffix = Config.Get("exportNamePatternLoop").Replace("[LOOPS]", $"{times}").Replace("[PLAYS]", $"{times + 1}");
|
||||
string loopSuffix = Config.Get(Config.Key.exportNamePatternLoop).Replace("[LOOPS]", $"{times}").Replace("[PLAYS]", $"{times + 1}");
|
||||
string outpath = $"{pathNoExt}{loopSuffix}{ext}";
|
||||
IOUtils.RenameExistingFile(outpath);
|
||||
string args = $" -stream_loop {times} -i {inputFile.Wrap()} -c copy {outpath.Wrap()}";
|
||||
@@ -144,7 +144,7 @@ namespace Flowframes
|
||||
{
|
||||
Logger.Log($"GetFrameCountAsync('{inputFile}') - Trying ffprobe first.", true, false, "ffmpeg");
|
||||
|
||||
int frames = await ReadFrameCountFfprobeAsync(inputFile, Config.GetBool("ffprobeFrameCount")); // Try reading frame count with ffprobe
|
||||
int frames = await ReadFrameCountFfprobeAsync(inputFile, Config.GetBool(Config.Key.ffprobeFrameCount)); // Try reading frame count with ffprobe
|
||||
if (frames > 0) return frames;
|
||||
|
||||
Logger.Log($"Failed to get frame count using ffprobe (frames = {frames}). Trying to read with ffmpeg.", true, false, "ffmpeg");
|
||||
|
||||
@@ -29,13 +29,13 @@ namespace Flowframes.Media
|
||||
string inArg = $"-f concat -i {Path.GetFileName(framesFile)}";
|
||||
string linksDir = Path.Combine(framesFile + Paths.symlinksSuffix);
|
||||
|
||||
if (Config.GetBool("allowSymlinkEncoding", true) && Symlinks.SymlinksAllowed())
|
||||
if (Config.GetBool(Config.Key.allowSymlinkEncoding, true) && Symlinks.SymlinksAllowed())
|
||||
{
|
||||
if (await Symlinks.MakeSymlinksForEncode(framesFile, linksDir, Padding.interpFrames))
|
||||
inArg = $"-i {Path.GetFileName(framesFile) + Paths.symlinksSuffix}/%{Padding.interpFrames}d.png";
|
||||
}
|
||||
|
||||
string extraArgs = Config.Get("ffEncArgs");
|
||||
string extraArgs = Config.Get(Config.Key.ffEncArgs);
|
||||
string rate = fps.ToString().Replace(",", ".");
|
||||
|
||||
List<string> filters = new List<string>();
|
||||
@@ -51,7 +51,7 @@ namespace Flowframes.Media
|
||||
}
|
||||
|
||||
string vf = filters.Count > 0 ? $"-vf {string.Join(",", filters)}" : "";
|
||||
string args = $"-vsync 0 -r {rate} {inArg} {encArgs} {vf} {GetAspectArg(extraData)} {extraArgs} -threads {Config.GetInt("ffEncThreads")} {outPath.Wrap()}";
|
||||
string args = $"-vsync 0 -r {rate} {inArg} {encArgs} {vf} {GetAspectArg(extraData)} {extraArgs} -threads {Config.GetInt(Config.Key.ffEncThreads)} {outPath.Wrap()}";
|
||||
await RunFfmpeg(args, framesFile.GetParentDir(), logMode, "error", TaskType.Encode, !isChunk);
|
||||
IOUtils.TryDeleteIfExists(linksDir);
|
||||
}
|
||||
@@ -70,7 +70,7 @@ namespace Flowframes.Media
|
||||
string inArg = $"-f concat -i {Path.GetFileName(framesFile)}";
|
||||
string linksDir = Path.Combine(framesFile + Paths.symlinksSuffix);
|
||||
|
||||
if (Config.GetBool("allowSymlinkEncoding", true) && Symlinks.SymlinksAllowed())
|
||||
if (Config.GetBool(Config.Key.allowSymlinkEncoding, true) && Symlinks.SymlinksAllowed())
|
||||
{
|
||||
if (await Symlinks.MakeSymlinksForEncode(framesFile, linksDir, Padding.interpFrames))
|
||||
inArg = $"-i {Path.GetFileName(framesFile) + Paths.symlinksSuffix}/%{Padding.interpFrames}d.png";
|
||||
@@ -93,7 +93,7 @@ namespace Flowframes.Media
|
||||
Logger.Log((resampleFps.GetFloat() <= 0) ? $"Encoding GIF..." : $"Encoding GIF resampled to {resampleFps.ToString().Replace(",", ".")} FPS...");
|
||||
|
||||
string framesFilename = Path.GetFileName(framesFile);
|
||||
string dither = Config.Get("gifDitherType").Split(' ').First();
|
||||
string dither = Config.Get(Config.Key.gifDitherType).Split(' ').First();
|
||||
string paletteFilter = palette ? $"-vf \"split[s0][s1];[s0]palettegen={colors}[p];[s1][p]paletteuse=dither={dither}\"" : "";
|
||||
string fpsFilter = (resampleFps.GetFloat() <= 0) ? "" : $"fps=fps={resampleFps}";
|
||||
string vf = FormatUtils.ConcatStrings(new string[] { paletteFilter, fpsFilter });
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Flowframes.Media
|
||||
inArg = $"-f concat -safe 0 -i {concatFile.Wrap()}";
|
||||
}
|
||||
|
||||
string scnDetect = $"-vf \"select='gt(scene,{Config.GetFloatString("scnDetectValue")})'\"";
|
||||
string scnDetect = $"-vf \"select='gt(scene,{Config.GetFloatString(Config.Key.scnDetectValue)})'\"";
|
||||
string rateArg = (rate.GetFloat() > 0) ? $"-r {rate}" : "";
|
||||
string args = $"-vsync 0 {GetTrimArg(true)} {inArg} {GetImgArgs(format)} {rateArg} {scnDetect} -frame_pts 1 -s 256x144 {GetTrimArg(false)} \"{outDir}/%{Padding.inputFrames}d{format}\"";
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace Flowframes.Media
|
||||
Logger.Log($"VideoToFrames() - Alpha: {alpha} - Size: {size}", true, false, "ffmpeg");
|
||||
string sizeStr = (size.Width > 1 && size.Height > 1) ? $"-s {size.Width}x{size.Height}" : "";
|
||||
IOUtils.CreateDir(framesDir);
|
||||
string mpStr = deDupe ? ((Config.GetInt("mpdecimateMode") == 0) ? mpDecDef : mpDecAggr) : "";
|
||||
string mpStr = deDupe ? ((Config.GetInt(Config.Key.mpdecimateMode) == 0) ? mpDecDef : mpDecAggr) : "";
|
||||
string filters = FormatUtils.ConcatStrings(new[] { GetPadFilter(), mpStr });
|
||||
string vf = filters.Length > 2 ? $"-vf {filters}" : "";
|
||||
string rateArg = (rate.GetFloat() > 0) ? $" -r {rate}" : "";
|
||||
@@ -94,7 +94,7 @@ namespace Flowframes.Media
|
||||
|
||||
public static async Task ImportImagesCheckCompat(string inpath, string outpath, bool alpha, Size size, bool showLog, string format)
|
||||
{
|
||||
bool compatible = await Task.Run(async () => { return AreImagesCompatible(inpath, Config.GetInt("maxVidHeight")); });
|
||||
bool compatible = await Task.Run(async () => { return AreImagesCompatible(inpath, Config.GetInt(Config.Key.maxVidHeight)); });
|
||||
|
||||
if (!alpha && compatible)
|
||||
{
|
||||
|
||||
@@ -150,16 +150,16 @@ namespace Flowframes
|
||||
Directory.CreateDirectory(outPath);
|
||||
string uhdStr = await InterpolateUtils.UseUhd() ? "--UHD" : "";
|
||||
string wthreads = $"--wthreads {2 * (int)interpFactor}";
|
||||
string rbuffer = $"--rbuffer {Config.GetInt("rifeCudaBufferSize", 200)}";
|
||||
string rbuffer = $"--rbuffer {Config.GetInt(Config.Key.rifeCudaBufferSize, 200)}";
|
||||
//string scale = $"--scale {Config.GetFloat("rifeCudaScale", 1.0f).ToStringDot()}";
|
||||
string prec = Config.GetBool("rifeCudaFp16") ? "--fp16" : "";
|
||||
string prec = Config.GetBool(Config.Key.rifeCudaFp16) ? "--fp16" : "";
|
||||
string args = $" --input {inPath.Wrap()} --output {outDir} --model {mdl} --exp {(int)Math.Log(interpFactor, 2)} {uhdStr} {wthreads} {rbuffer} {prec}";
|
||||
|
||||
Process rifePy = OSUtils.NewProcess(!OSUtils.ShowHiddenCmd());
|
||||
AiStarted(rifePy, 3500);
|
||||
SetProgressCheck(Path.Combine(Interpolate.current.tempFolder, outDir), interpFactor);
|
||||
rifePy.StartInfo.Arguments = $"{OSUtils.GetCmdArg()} cd /D {Path.Combine(Paths.GetPkgPath(), Networks.rifeCuda.pkgDir).Wrap()} & " +
|
||||
$"set CUDA_VISIBLE_DEVICES={Config.Get("torchGpus")} & {Python.GetPyCmd()} {script} {args}";
|
||||
$"set CUDA_VISIBLE_DEVICES={Config.Get(Config.Key.torchGpus)} & {Python.GetPyCmd()} {script} {args}";
|
||||
Logger.Log($"Running RIFE (CUDA){(await InterpolateUtils.UseUhd() ? " (UHD Mode)" : "")}...", false);
|
||||
Logger.Log("cmd.exe " + rifePy.StartInfo.Arguments, true);
|
||||
|
||||
@@ -223,7 +223,7 @@ namespace Flowframes
|
||||
AiStarted(flavrPy, 4500);
|
||||
SetProgressCheck(Path.Combine(Interpolate.current.tempFolder, outDir), interpFactor);
|
||||
flavrPy.StartInfo.Arguments = $"{OSUtils.GetCmdArg()} cd /D {Path.Combine(Paths.GetPkgPath(), Networks.flavrCuda.pkgDir).Wrap()} & " +
|
||||
$"set CUDA_VISIBLE_DEVICES={Config.Get("torchGpus")} & {Python.GetPyCmd()} {script} {args}";
|
||||
$"set CUDA_VISIBLE_DEVICES={Config.Get(Config.Key.torchGpus)} & {Python.GetPyCmd()} {script} {args}";
|
||||
Logger.Log($"Running FLAVR (CUDA)...", false);
|
||||
Logger.Log("cmd.exe " + flavrPy.StartInfo.Arguments, true);
|
||||
|
||||
@@ -308,10 +308,10 @@ namespace Flowframes
|
||||
SetProgressCheck(outPath, 2);
|
||||
|
||||
string uhdStr = await InterpolateUtils.UseUhd() ? "-u" : "";
|
||||
string ttaStr = Config.GetBool("rifeNcnnUseTta", false) ? "-x" : "";
|
||||
string ttaStr = Config.GetBool(Config.Key.rifeNcnnUseTta, false) ? "-x" : "";
|
||||
|
||||
rifeNcnn.StartInfo.Arguments = $"{OSUtils.GetCmdArg()} cd /D {Path.Combine(Paths.GetPkgPath(), Networks.rifeNcnn.pkgDir).Wrap()} & rife-ncnn-vulkan.exe " +
|
||||
$" -v -i {inPath.Wrap()} -o {outPath.Wrap()} -m {mdl.ToLower()} {ttaStr} {uhdStr} -g {Config.Get("ncnnGpus")} -f {GetNcnnPattern()} -j {GetNcnnThreads()}";
|
||||
$" -v -i {inPath.Wrap()} -o {outPath.Wrap()} -m {mdl.ToLower()} {ttaStr} {uhdStr} -g {Config.Get(Config.Key.ncnnGpus)} -f {GetNcnnPattern()} -j {GetNcnnThreads()}";
|
||||
|
||||
Logger.Log("cmd.exe " + rifeNcnn.StartInfo.Arguments, true);
|
||||
|
||||
@@ -366,7 +366,7 @@ namespace Flowframes
|
||||
int targetFrames = ((IOUtils.GetAmountOfFiles(lastInPath, false, "*.*") * factor).RoundToInt()) - (factor.RoundToInt() - 1); // TODO: Won't work with fractional factors
|
||||
|
||||
string args = $" -v -i {framesPath.Wrap()} -o {outPath.Wrap()} -n {targetFrames} -m {mdl.ToLower()}" +
|
||||
$" -t {GetNcnnTilesize(tilesize)} -g {Config.Get("ncnnGpus")} -f {GetNcnnPattern()} -j 2:1:2";
|
||||
$" -t {GetNcnnTilesize(tilesize)} -g {Config.Get(Config.Key.ncnnGpus)} -f {GetNcnnPattern()} -j 2:1:2";
|
||||
|
||||
dain.StartInfo.Arguments = $"{OSUtils.GetCmdArg()} cd /D {dainDir.Wrap()} & dain-ncnn-vulkan.exe {args}";
|
||||
Logger.Log("Running DAIN...", false);
|
||||
@@ -498,7 +498,7 @@ namespace Flowframes
|
||||
|
||||
static string GetNcnnTilesize(int tilesize)
|
||||
{
|
||||
int gpusAmount = Config.Get("ncnnGpus").Split(',').Length;
|
||||
int gpusAmount = Config.Get(Config.Key.ncnnGpus).Split(',').Length;
|
||||
string tilesizeStr = $"{tilesize}";
|
||||
|
||||
for (int i = 1; i < gpusAmount; i++)
|
||||
@@ -509,8 +509,8 @@ namespace Flowframes
|
||||
|
||||
static string GetNcnnThreads ()
|
||||
{
|
||||
int gpusAmount = Config.Get("ncnnGpus").Split(',').Length;
|
||||
int procThreads = Config.GetInt("ncnnThreads");
|
||||
int gpusAmount = Config.Get(Config.Key.ncnnGpus).Split(',').Length;
|
||||
int procThreads = Config.GetInt(Config.Key.ncnnThreads);
|
||||
string progThreadsStr = $"{procThreads}";
|
||||
|
||||
for (int i = 1; i < gpusAmount; i++)
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace Flowframes.OS
|
||||
|
||||
public static string GetCmdArg()
|
||||
{
|
||||
bool stayOpen = Config.GetInt("cmdDebugMode") == 2;
|
||||
bool stayOpen = Config.GetInt(Config.Key.cmdDebugMode) == 2;
|
||||
if (stayOpen)
|
||||
return "/K";
|
||||
else
|
||||
@@ -97,7 +97,7 @@ namespace Flowframes.OS
|
||||
|
||||
public static bool ShowHiddenCmd()
|
||||
{
|
||||
return Config.GetInt("cmdDebugMode") > 0;
|
||||
return Config.GetInt(Config.Key.cmdDebugMode) > 0;
|
||||
}
|
||||
|
||||
public static bool DriveIsSSD(string path)
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Flowframes.OS
|
||||
|
||||
public static async Task CheckCompression ()
|
||||
{
|
||||
if(HasEmbeddedPyFolder() && (Config.Get("compressedPyVersion") != Updater.GetInstalledVer().ToString()))
|
||||
if(HasEmbeddedPyFolder() && (Config.Get(Config.Key.compressedPyVersion) != Updater.GetInstalledVer().ToString()))
|
||||
{
|
||||
Program.mainForm.SetWorking(true, false);
|
||||
Stopwatch sw = new Stopwatch();
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace Flowframes.OS
|
||||
bool symlinksAllowed = Symlinks.SymlinksAllowed();
|
||||
Logger.Log($"SymlinksAllowed: {symlinksAllowed}", true);
|
||||
|
||||
if (!symlinksAllowed && Config.Get("askedForDevModeVersion") != ver)
|
||||
if (!symlinksAllowed && Config.Get(Config.Key.askedForDevModeVersion) != ver)
|
||||
{
|
||||
if (!silent)
|
||||
{
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Flowframes
|
||||
{
|
||||
Config.Init();
|
||||
|
||||
if (Config.GetBool("delLogsOnStartup"))
|
||||
if (Config.GetBool(Config.Key.delLogsOnStartup))
|
||||
IOUtils.DeleteContentsOfDir(Paths.GetLogPath()); // Clear out older logs from previous session
|
||||
|
||||
Networks.Init();
|
||||
@@ -82,8 +82,8 @@ namespace Flowframes
|
||||
|
||||
Logger.Log($"Disk space check for '{drivePath}/': {(mb / 1024f).ToString("0.0")} GB free.", true);
|
||||
|
||||
bool lowDiskSpace = mb < (Config.GetInt("lowDiskSpacePauseGb", 5) * 1024);
|
||||
bool tooLowDiskSpace = mb < (Config.GetInt("lowDiskSpaceCancelGb", 2) * 1024);
|
||||
bool lowDiskSpace = mb < (Config.GetInt(Config.Key.lowDiskSpacePauseGb, 5) * 1024);
|
||||
bool tooLowDiskSpace = mb < (Config.GetInt(Config.Key.lowDiskSpaceCancelGb, 2) * 1024);
|
||||
string spaceGb = (mb / 1024f).ToString("0.0");
|
||||
|
||||
if (!Interpolate.canceled && (AiProcess.lastAiProcess != null && !AiProcess.lastAiProcess.HasExited) && lowDiskSpace)
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Flowframes.UI
|
||||
Program.mainForm.ResetInputInfo();
|
||||
string path = inputTbox.Text.Trim();
|
||||
|
||||
if (Config.GetBool("clearLogOnInput"))
|
||||
if (Config.GetBool(Config.Key.clearLogOnInput))
|
||||
Logger.ClearLogBox();
|
||||
|
||||
outputTbox.Text = inputTbox.Text.Trim().GetParentDir();
|
||||
|
||||
Reference in New Issue
Block a user