From 27749ad405b105617fc17e2f17f90e07f360b83a Mon Sep 17 00:00:00 2001 From: N00MKRAD Date: Wed, 5 May 2021 16:42:33 +0200 Subject: [PATCH] Image sequences are now copied if compatible, symlinks for frame imports --- Code/Main/Interpolate.cs | 2 +- Code/Media/FfmpegEncode.cs | 3 -- Code/Media/FfmpegExtract.cs | 92 ++++++++++++++++++++++++++++++++++--- 3 files changed, 87 insertions(+), 10 deletions(-) diff --git a/Code/Main/Interpolate.cs b/Code/Main/Interpolate.cs index 6a82aa4..950ca5a 100644 --- a/Code/Main/Interpolate.cs +++ b/Code/Main/Interpolate.cs @@ -86,7 +86,7 @@ namespace Flowframes if (!current.inputIsFrames) // Extract if input is video, import if image sequence await ExtractFrames(current.inPath, current.framesFolder, current.alpha); else - await FfmpegExtract.ImportImages(current.inPath, current.framesFolder, current.alpha, (await current.GetScaledRes()), true, current.framesExt); + await FfmpegExtract.ImportImagesCheckCompat(current.inPath, current.framesFolder, current.alpha, (await current.GetScaledRes()), true, current.framesExt); } public static async Task ExtractFrames(string inPath, string outPath, bool alpha) diff --git a/Code/Media/FfmpegEncode.cs b/Code/Media/FfmpegEncode.cs index dfed3d8..e4aad71 100644 --- a/Code/Media/FfmpegEncode.cs +++ b/Code/Media/FfmpegEncode.cs @@ -49,9 +49,6 @@ namespace Flowframes.Media public static async Task FramesToFrames(string framesFile, string outDir, Fraction fps, Fraction resampleFps, string format = "png", LogMode logMode = LogMode.OnlyLastLine) { - //if (logMode != LogMode.Hidden) - // Logger.Log((resampleFps.GetFloat() <= 0) ? "Exporting frames..." : $"Exporting frames resampled to {resampleFps.GetString()} FPS..."); - Directory.CreateDirectory(outDir); string inArg = $"-f concat -i {Path.GetFileName(framesFile)}"; string linksDir = Path.Combine(framesFile + Paths.symlinksSuffix); diff --git a/Code/Media/FfmpegExtract.cs b/Code/Media/FfmpegExtract.cs index 5138345..85d7eed 100644 --- a/Code/Media/FfmpegExtract.cs +++ b/Code/Media/FfmpegExtract.cs @@ -92,22 +92,102 @@ namespace Flowframes.Media DeleteSource(inputFile); } + public static async Task ImportImagesCheckCompat(string inpath, string outpath, bool alpha, Size size, bool showLog, string format) + { + if (!alpha && AreImagesCompatible(inpath, size)) + { + if (showLog) Logger.Log($"Copying images from {new DirectoryInfo(inpath).Name}..."); + await Task.Run(async () => { IOUtils.CopyDir(inpath, outpath); }); + } + else + { + await ImportImages(inpath, outpath, alpha, size, showLog, format); + } + } + + static bool AreImagesCompatible (string inpath, Size maxSize) + { + string[] validExtensions = 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("[AreImagesCompatible] 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($"[AreImagesCompatible] Sequence not compatible: Not all files have a valid extension ({string.Join(", ", validExtensions)}).", true); + return false; + } + + Image[] randomSamples = files.OrderBy(arg => Guid.NewGuid()).Take(5).Select(x => IOUtils.GetImage(x.FullName)).ToArray(); + + bool allSameSize = randomSamples.All(i => i.Size == randomSamples.First().Size); + + if (!allSameSize) + { + Logger.Log("[AreImagesCompatible] 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($"[AreImagesCompatible] Sequence not compatible: Not all image dimensions are divisible by {div}.", true); + return false; + } + + bool allSmallEnough = randomSamples.All(i => (i.Width <= maxSize.Width) && (i.Height <= maxSize.Height)); + + if (!allDivBy2) + { + Logger.Log($"[AreImagesCompatible] Sequence not compatible: Image dimensions above max size.", true); + return false; + } + + Interpolate.current.framesExt = files.First().Extension; + return true; + } + public static async Task ImportImages(string inpath, string outpath, bool alpha, Size size, bool showLog, string format) { - if (showLog) Logger.Log("Importing images..."); - Logger.Log($"Importing images from {inpath} to {outpath}.", true); + if (showLog) Logger.Log($"Copying images from {new DirectoryInfo(inpath).Name}..."); Logger.Log($"ImportImages() - Alpha: {alpha} - Size: {size}", true, false, "ffmpeg"); IOUtils.CreateDir(outpath); string concatFile = Path.Combine(Paths.GetDataPath(), "png-concat-temp.ini"); GetConcatFile(inpath, concatFile); + + string inArg = $"-f concat -safe 0 -i {concatFile.Wrap()}"; + string linksDir = Path.Combine(concatFile + Paths.symlinksSuffix); + + if (Config.GetBool("allowSymlinkEncoding", true) && Symlinks.SymlinksAllowed()) + { + if (await Symlinks.MakeSymlinksForEncode(concatFile, linksDir, Padding.interpFrames)) + inArg = $"-i \"{linksDir}/%{Padding.interpFrames}d.png\""; + } + string sizeStr = (size.Width > 1 && size.Height > 1) ? $"-s {size.Width}x{size.Height}" : ""; string vf = alpha ? $"-filter_complex \"[0:v]{GetPadFilter()},split[a][b];[a]palettegen=reserve_transparent=on:transparency_color=ffffff[p];[b][p]paletteuse\"" : $"-vf {GetPadFilter()}"; - string args = $"-f concat -safe 0 -i {concatFile.Wrap()} {GetImgArgs(format, true, alpha)} {sizeStr} -vsync 0 -start_number 0 {vf} \"{outpath}/%{Padding.inputFrames}d{format}\""; + 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); } - public static void GetConcatFile (string inputFilesDir, string concatFilePath) + public static void GetConcatFile(string inputFilesDir, string concatFilePath) { string concatFileContent = ""; string[] files = IOUtils.GetFilesSorted(inputFilesDir); @@ -123,7 +203,7 @@ namespace Flowframes.Media return new string[] { GetTrimArg(true), GetTrimArg(false) }; } - public static string GetTrimArg (bool input) + public static string GetTrimArg(bool input) { if (!QuickSettingsTab.trimEnabled) return ""; @@ -141,7 +221,7 @@ namespace Flowframes.Media } else { - if(fastSeek) + if (fastSeek) { arg += $"-ss {fastSeekThresh}";