mirror of
https://github.com/n00mkrad/flowframes.git
synced 2025-12-24 04:09:29 +01:00
Faster trimming
This commit is contained in:
@@ -26,6 +26,8 @@ namespace Flowframes.Main
|
||||
|
||||
public static async Task CopyLastFrame(int lastFrameNum)
|
||||
{
|
||||
if (I.canceled) return;
|
||||
|
||||
try
|
||||
{
|
||||
lastFrameNum--; // We have to do this as extracted frames start at 0, not 1
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Flowframes
|
||||
class FfmpegCommands
|
||||
{
|
||||
public static string divisionFilter = "pad=width=ceil(iw/2)*2:height=ceil(ih/2)*2:color=black@0";
|
||||
public static string pngComprArg = "-compression_level 3";
|
||||
public static string compr = "-compression_level 3";
|
||||
public static string mpDecDef = "\"mpdecimate\"";
|
||||
public static string mpDecAggr = "\"mpdecimate=hi=64*32:lo=64*32:frac=0.1\"";
|
||||
|
||||
|
||||
@@ -35,14 +35,14 @@ namespace Flowframes.Media
|
||||
if (!sceneDetect) Logger.Log("Extracting video frames from input video...");
|
||||
string sizeStr = (size.Width > 1 && size.Height > 1) ? $"-s {size.Width}x{size.Height}" : "";
|
||||
IOUtils.CreateDir(framesDir);
|
||||
string timecodeStr = /* timecodes ? $"-copyts -r {FrameOrder.timebase} -frame_pts true" : */ "-copyts -frame_pts true";
|
||||
string timecodeStr = /* timecodes ? $"-copyts -r {FrameOrder.timebase} -frame_pts true" : */ "-frame_pts true";
|
||||
string scnDetect = sceneDetect ? $"\"select='gt(scene,{Config.GetFloatString("scnDetectValue")})'\"" : "";
|
||||
string mpStr = deDupe ? ((Config.GetInt("mpdecimateMode") == 0) ? mpDecDef : mpDecAggr) : "";
|
||||
string filters = FormatUtils.ConcatStrings(new string[] { divisionFilter, scnDetect, mpStr });
|
||||
string vf = filters.Length > 2 ? $"-vf {filters}" : "";
|
||||
string rateArg = (rate > 0) ? $" -r {rate.ToStringDot()}" : "";
|
||||
string pixFmt = alpha ? "-pix_fmt rgba" : "-pix_fmt rgb24"; // Use RGBA for GIF for alpha support
|
||||
string args = $"{rateArg} -i {inputFile.Wrap()} {pngComprArg} -vsync 0 {pixFmt} {timecodeStr} {vf} {sizeStr} {GetTrimArg()} \"{framesDir}/%{Padding.inputFrames}d.png\"";
|
||||
string args = $"{rateArg} {GetTrimArg(true)} -i {inputFile.Wrap()} {compr} -vsync 0 {pixFmt} {timecodeStr} {vf} {sizeStr} {GetTrimArg(false)} \"{framesDir}/%{Padding.inputFrames}d.png\"";
|
||||
LogMode logMode = Interpolate.currentInputFrameCount > 50 ? LogMode.OnlyLastLine : LogMode.Hidden;
|
||||
await RunFfmpeg(args, logMode, TaskType.ExtractFrames, true);
|
||||
int amount = IOUtils.GetAmountOfFiles(framesDir, false, "*.png");
|
||||
@@ -67,22 +67,48 @@ namespace Flowframes.Media
|
||||
string sizeStr = (size.Width > 1 && size.Height > 1) ? $"-s {size.Width}x{size.Height}" : "";
|
||||
string pixFmt = alpha ? "-pix_fmt rgba" : "-pix_fmt rgb24"; // Use RGBA for GIF for alpha support
|
||||
string vf = alpha ? $"-filter_complex \"[0:v]{divisionFilter},split[a][b];[a]palettegen=reserve_transparent=on:transparency_color=ffffff[p];[b][p]paletteuse\"" : $"-vf {divisionFilter}";
|
||||
string args = $" -loglevel panic -f concat -safe 0 -i {concatFile.Wrap()} {pngComprArg} {sizeStr} {pixFmt} -vsync 0 {vf} \"{outpath}/%{Padding.inputFrames}d.png\"";
|
||||
string args = $" -loglevel panic -f concat -safe 0 -i {concatFile.Wrap()} {compr} {sizeStr} {pixFmt} -vsync 0 {vf} \"{outpath}/%{Padding.inputFrames}d.png\"";
|
||||
LogMode logMode = IOUtils.GetAmountOfFiles(inpath, false) > 50 ? LogMode.OnlyLastLine : LogMode.Hidden;
|
||||
await RunFfmpeg(args, logMode, TaskType.ExtractFrames);
|
||||
if (delSrc)
|
||||
DeleteSource(inpath);
|
||||
}
|
||||
|
||||
static string GetTrimArg ()
|
||||
static string GetTrimArg (bool input)
|
||||
{
|
||||
if (!QuickSettingsTab.trimEnabled)
|
||||
return "";
|
||||
|
||||
string arg = $"-ss {QuickSettingsTab.trimStart}";
|
||||
int fastSeekThresh = 180;
|
||||
bool fastSeek = QuickSettingsTab.trimStartSecs > fastSeekThresh;
|
||||
string arg = "";
|
||||
|
||||
if(QuickSettingsTab.doTrimEnd)
|
||||
arg += $" -to {QuickSettingsTab.trimEnd}";
|
||||
if (input)
|
||||
{
|
||||
if (fastSeek)
|
||||
arg += $"-ss {QuickSettingsTab.trimStartSecs - fastSeekThresh}";
|
||||
else
|
||||
return arg;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fastSeek)
|
||||
{
|
||||
arg += $"-ss {fastSeekThresh}";
|
||||
|
||||
long trimTimeSecs = QuickSettingsTab.trimEndSecs - QuickSettingsTab.trimStartSecs;
|
||||
|
||||
if (QuickSettingsTab.doTrimEnd)
|
||||
arg += $" -to {fastSeekThresh + trimTimeSecs}";
|
||||
}
|
||||
else
|
||||
{
|
||||
arg += $"-ss {QuickSettingsTab.trimStart}";
|
||||
|
||||
if (QuickSettingsTab.doTrimEnd)
|
||||
arg += $" -to {QuickSettingsTab.trimEnd}";
|
||||
}
|
||||
}
|
||||
|
||||
return arg;
|
||||
}
|
||||
@@ -91,7 +117,7 @@ namespace Flowframes.Media
|
||||
{
|
||||
string sizeStr = (size.Width > 1 && size.Height > 1) ? $"-s {size.Width}x{size.Height}" : "";
|
||||
bool isPng = (Path.GetExtension(outPath).ToLower() == ".png");
|
||||
string comprArg = isPng ? pngComprArg : "";
|
||||
string comprArg = isPng ? compr : "";
|
||||
string pixFmt = "-pix_fmt " + (isPng ? $"rgb24 {comprArg}" : "yuvj420p");
|
||||
string args = $"-i {inputFile.Wrap()} {comprArg} {sizeStr} {pixFmt} -vf {divisionFilter} {outPath.Wrap()}";
|
||||
await RunFfmpeg(args, LogMode.Hidden, TaskType.ExtractFrames);
|
||||
@@ -100,7 +126,7 @@ namespace Flowframes.Media
|
||||
public static async Task ExtractSingleFrame(string inputFile, string outputPath, int frameNum)
|
||||
{
|
||||
bool isPng = (Path.GetExtension(outputPath).ToLower() == ".png");
|
||||
string comprArg = isPng ? pngComprArg : "";
|
||||
string comprArg = isPng ? compr : "";
|
||||
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);
|
||||
@@ -115,7 +141,7 @@ namespace Flowframes.Media
|
||||
outputPath = Path.Combine(outputPath, "last.png");
|
||||
|
||||
bool isPng = (Path.GetExtension(outputPath).ToLower() == ".png");
|
||||
string comprArg = isPng ? pngComprArg : "";
|
||||
string comprArg = isPng ? compr : "";
|
||||
string pixFmt = "-pix_fmt " + (isPng ? $"rgb24 {comprArg}" : "yuvj420p");
|
||||
string sizeStr = (size.Width > 1 && size.Height > 1) ? $"-s {size.Width}x{size.Height}" : "";
|
||||
string trim = QuickSettingsTab.trimEnabled ? $"-ss {QuickSettingsTab.GetTrimEndMinusOne()} -to {QuickSettingsTab.trimEnd}" : "";
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace Flowframes.MiscUtils
|
||||
int hours = int.Parse(values[0]);
|
||||
int minutes = int.Parse(values[1]);
|
||||
int seconds = int.Parse(values[2].Split('.')[0]);
|
||||
long secs = hours * 3600000 + minutes * 60000 + seconds;
|
||||
long secs = hours * 3600 + minutes * 60 + seconds;
|
||||
|
||||
if (hasMilliseconds)
|
||||
{
|
||||
|
||||
@@ -19,17 +19,19 @@ namespace Flowframes.UI
|
||||
public static bool doTrimEnd;
|
||||
public static string trimStart;
|
||||
public static string trimEnd;
|
||||
public static long trimStartSecs;
|
||||
public static long trimEndSecs;
|
||||
|
||||
public static void UpdateTrim (TextBox trimStartBox, TextBox trimEndBox)
|
||||
{
|
||||
trimStart = trimStartBox.Text.Trim();
|
||||
trimEnd = trimEndBox.Text.Trim();
|
||||
|
||||
long startSecs = FormatUtils.TimestampToSecs(trimStart, false);
|
||||
long endSecs = FormatUtils.TimestampToSecs(trimEnd, false);
|
||||
trimStartSecs = FormatUtils.TimestampToSecs(trimStart, false);
|
||||
trimEndSecs = FormatUtils.TimestampToSecs(trimEnd, false);
|
||||
|
||||
if (endSecs <= startSecs)
|
||||
trimEndBox.Text = FormatUtils.SecsToTimestamp(startSecs + 1);
|
||||
if (trimEndSecs <= trimStartSecs)
|
||||
trimEndBox.Text = FormatUtils.SecsToTimestamp(trimStartSecs + 1);
|
||||
|
||||
long dur = FormatUtils.TimestampToMs(trimEnd, false) - FormatUtils.TimestampToMs(trimStart, false);
|
||||
Program.mainForm.currInDurationCut = dur;
|
||||
|
||||
Reference in New Issue
Block a user