diff --git a/Code/AudioVideo/FFmpegCommands.cs b/Code/AudioVideo/FFmpegCommands.cs index 6fd143c..f3cb6ee 100644 --- a/Code/AudioVideo/FFmpegCommands.cs +++ b/Code/AudioVideo/FFmpegCommands.cs @@ -2,6 +2,7 @@ using Flowframes.Data; using Flowframes.IO; using Flowframes.Main; +using Flowframes.MiscUtils; using System; using System.Drawing; using System.Globalization; @@ -42,10 +43,12 @@ namespace Flowframes 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(frameFolderPath); - string timecodeStr = timecodes ? "-copyts -r 10000 -frame_pts true" : ""; + string timecodeStr = timecodes ? $"-copyts -r {FrameTiming.timebase} -frame_pts true" : ""; string scnDetect = sceneDetect ? $"\"select='gt(scene,{Config.GetFloatString("scnDetectValue")})'\"" : ""; string mpStr = deDupe ? ((Config.GetInt("mpdecimateMode") == 0) ? mpDecDef : mpDecAggr) : ""; - string vf = (scnDetect.Length > 2 || mpStr.Length > 2) ? $"-vf {scnDetect},{mpStr} ".ListCommaFix() : ""; + string fpsFilter = $"\"fps=fps={Interpolate.current.inFps.ToString().Replace(",", ".")}\""; + string filters = FormatUtils.ConcatStrings(new string[] { scnDetect, mpStr, fpsFilter } ); + string vf = filters.Length > 2 ? $"-vf {filters}" : ""; string pad = Padding.inputFrames.ToString(); string args = $"-i {inputFile.Wrap()} {pngComprArg} -vsync 0 -pix_fmt rgb24 {timecodeStr} {vf} {sizeStr} \"{frameFolderPath}/%{pad}d.png\""; AvProcess.LogMode logMode = Interpolate.currentInputFrameCount > 50 ? AvProcess.LogMode.OnlyLastLine : AvProcess.LogMode.Hidden; diff --git a/Code/ExtensionMethods.cs b/Code/ExtensionMethods.cs index d674c43..29b5b11 100644 --- a/Code/ExtensionMethods.cs +++ b/Code/ExtensionMethods.cs @@ -155,10 +155,5 @@ namespace Flowframes return str.Remove(place, stringToReplace.Length).Insert(place, replaceWith); } - - public static string ListCommaFix (this string str) - { - return str.Replace(" , ", " ").Replace(" ,", " ").Replace(", ", " "); - } } } diff --git a/Code/Main/FrameTiming.cs b/Code/Main/FrameTiming.cs index 3802b35..829d0a9 100644 --- a/Code/Main/FrameTiming.cs +++ b/Code/Main/FrameTiming.cs @@ -14,6 +14,8 @@ namespace Flowframes.Main { class FrameTiming { + public static int timebase = 10000; + public static async Task CreateTimecodeFiles(string framesPath, bool loopEnabled, int times, bool noTimestamps) { Logger.Log("Generating timecodes..."); @@ -79,7 +81,7 @@ namespace Flowframes.Main { //Logger.Log($"Writing out frame {frm+1}/{interpFramesAmount}", true); - string durationStr = (durationPerInterpFrame / 10000f).ToString("0.00000", CultureInfo.InvariantCulture); + string durationStr = (durationPerInterpFrame / timebase).ToString("0.0000000", CultureInfo.InvariantCulture); if (discardThisFrame && totalFileCount > 1) // Never discard 1st frame { @@ -115,7 +117,7 @@ namespace Flowframes.Main } // Use average frame duration for last frame - TODO: Use real duration?? - string durationStrLast = ((totalDuration / totalFileCount) / 10000f).ToString("0.00000", CultureInfo.InvariantCulture); + string durationStrLast = ((totalDuration / (totalFileCount - 1)) / timebase).ToString("0.0000000", CultureInfo.InvariantCulture); fileContent += $"file '{interpPath}/{totalFileCount.ToString().PadLeft(Padding.interpFrames, '0')}.{ext}'\nduration {durationStrLast}\n"; totalFileCount++; diff --git a/Code/MiscUtils/FormatUtils.cs b/Code/MiscUtils/FormatUtils.cs index 34b3e1f..9dfcb33 100644 --- a/Code/MiscUtils/FormatUtils.cs +++ b/Code/MiscUtils/FormatUtils.cs @@ -68,5 +68,23 @@ namespace Flowframes.MiscUtils double ratio = Math.Round(((float)numTo / (float)numFrom) * 100f); return ratio + "%"; } + + public static string ConcatStrings(string[] strings, char delimiter = ',', bool distinct = false) + { + string outStr = ""; + + strings = strings.Where(s => !string.IsNullOrWhiteSpace(s)).ToArray(); + if(distinct) + strings = strings.Distinct().ToArray(); + + for (int i = 0; i < strings.Length; i++) + { + outStr += strings[i]; + if (i + 1 != strings.Length) + outStr += delimiter; + } + + return outStr; + } } }