Exemple #1
0
        public static async Task CreateOutputVid()
        {
            if (!Directory.Exists(current.interpFolder) || IOUtils.GetAmountOfFiles(current.interpFolder, false) < 2)
            {
                Cancel($"There are no interpolated frames to encode!\n\nDid you delete the folder?");
                return;
            }

            if (!(await InterpolateUtils.CheckEncoderValid()))
            {
                return;
            }

            string[] outFrames = IOUtils.GetFilesSorted(current.interpFolder, $"*.{InterpolateUtils.GetOutExt()}");

            if (outFrames.Length > 0 && !IOUtils.CheckImageValid(outFrames[0]))
            {
                InterpolateUtils.ShowMessage("Invalid frame files detected!\n\nIf you used Auto-Encode, this is normal, and you don't need to run " +
                                             "this step as the video was already created in the \"Interpolate\" step.", "Error");
                return;
            }

            string outPath = Path.Combine(current.outPath, Path.GetFileNameWithoutExtension(current.inPath) + IOUtils.GetCurrentExportSuffix() + FFmpegUtils.GetExt(current.outMode));
            await CreateVideo.Export(current.interpFolder, outPath, current.outMode, true);
        }
        static string currentOutFile;   // Keeps track of the out file, in case it gets renamed (FPS limiting, looping, etc) before finishing export

        public static async Task Export(string path, string outFolder, I.OutMode mode, bool stepByStep)
        {
            if (!mode.ToString().ToLower().Contains("vid"))     // Copy interp frames out of temp folder and skip video export for image seq export
            {
                try
                {
                    string folder = Path.Combine(outFolder, IOUtils.GetCurrentExportFilename(false, false));
                    await CopyOutputFrames(path, folder, stepByStep);
                }
                catch (Exception e)
                {
                    Logger.Log("Failed to move interp frames folder: " + e.Message);
                }

                return;
            }

            if (IOUtils.GetAmountOfFiles(path, false, $"*.{InterpolateUtils.GetOutExt()}") <= 1)
            {
                I.Cancel("Output folder does not contain frames - An error must have occured during interpolation!", AiProcess.hasShownError);
                return;
            }

            await Task.Delay(10);

            Program.mainForm.SetStatus("Creating output video from frames...");

            try
            {
                float maxFps   = Config.GetFloat("maxFps");
                bool  fpsLimit = maxFps != 0 && I.current.outFps > maxFps;

                bool dontEncodeFullFpsVid = fpsLimit && Config.GetInt("maxFpsMode") == 0;

                if (!dontEncodeFullFpsVid)
                {
                    await Encode(mode, path, Path.Combine(outFolder, IOUtils.GetCurrentExportFilename(false, true)), I.current.outFps);
                }

                if (fpsLimit)
                {
                    await Encode(mode, path, Path.Combine(outFolder, IOUtils.GetCurrentExportFilename(true, true)), I.current.outFps, maxFps);
                }
            }
            catch (Exception e)
            {
                Logger.Log("FramesToVideo Error: " + e.Message, false);
                MessageBox.Show("An error occured while trying to convert the interpolated frames to a video.\nCheck the log for details.");
            }
        }
Exemple #3
0
        static async Task GenerateFrameLines(int number, int startIndex, int count, int factor, bool loopEnabled, bool sceneDetection, bool debug)
        {
            int    totalFileCount     = (startIndex) * factor;
            int    interpFramesAmount = factor;
            string ext = InterpolateUtils.GetOutExt();

            string fileContent = "";

            for (int i = startIndex; i < (startIndex + count); i++)
            {
                if (Interpolate.canceled)
                {
                    return;
                }
                if (i >= frameFilesWithoutLast.Length)
                {
                    break;
                }

                if (debug && i == startIndex)
                {
                    fileContent += $"# NEW THREAD - {startIndex} to {startIndex + count}\n";
                }

                string inputFilenameNoExt = Path.GetFileNameWithoutExtension(frameFilesWithoutLast[i].Name);
                int    dupesAmount        = dupesDict.ContainsKey(inputFilenameNoExt) ? dupesDict[inputFilenameNoExt] : 0;
                bool   discardThisFrame   = (sceneDetection && (i + 2) < frameFilesWithoutLast.Length && sceneFrames.Contains(Path.GetFileNameWithoutExtension(frameFilesWithoutLast[i + 1].Name))); // i+2 is in scene detection folder, means i+1 is ugly interp frame

                if (i + 1 == frameFilesWithoutLast.Length)                                                                                                                                           // Is last frame
                {
                    if (sceneDetection && sceneFrames.Contains(Path.GetFileNameWithoutExtension(frameFiles.Last().Name)))                                                                            // Scene detection for last frame
                    {
                        discardThisFrame = true;
                    }
                }

                if (loopEnabled && i == (frameFiles.Length - 2))    // If loop is enabled, account for the extra frame for loop continuity
                {
                    interpFramesAmount = interpFramesAmount * 2;
                }

                for (int frm = 0; frm < interpFramesAmount; frm++) // Generate frames file lines
                {
                    if (discardThisFrame)                          // If frame is scene cut frame
                    {
                        totalFileCount++;
                        int lastNum = totalFileCount;
                        fileContent = WriteFrameWithDupes(dupesAmount, fileContent, totalFileCount, ext, debug, $"[In: {inputFilenameNoExt}] [{((frm == 0) ? " Source " : $"Interp {frm}")}] [DiscardNext]");
Exemple #4
0
        public static async Task CreateEncFile(string framesPath, bool loopEnabled, float interpFactor, bool notFirstRun)
        {
            if (Interpolate.canceled)
            {
                return;
            }
            Logger.Log($"Generating frame order information for {interpFactor}x...", false, true);

            bool   loop           = Config.GetBool("enableLoop");
            bool   sceneDetection = true;
            string ext            = InterpolateUtils.GetOutExt();

            frameFileContents.Clear();
            lastOutFileCount = 0;

            frameFiles            = new DirectoryInfo(framesPath).GetFiles($"*.png");
            frameFilesWithoutLast = frameFiles;
            Array.Resize(ref frameFilesWithoutLast, frameFilesWithoutLast.Length - 1);
            string vfrFile     = Path.Combine(framesPath.GetParentDir(), Paths.GetFrameOrderFilename(interpFactor));
            string fileContent = "";
            string dupesFile   = Path.Combine(framesPath.GetParentDir(), $"dupes.ini");

            LoadDupesFile(dupesFile);

            string scnFramesPath = Path.Combine(framesPath.GetParentDir(), Paths.scenesDir);

            sceneFrames.Clear();

            if (Directory.Exists(scnFramesPath))
            {
                sceneFrames = Directory.GetFiles(scnFramesPath).Select(file => Path.GetFileNameWithoutExtension(file)).ToList();
            }

            bool        debug = Config.GetBool("frameOrderDebug", false);
            int         interpFramesAmount = (int)interpFactor; // TODO: This code won't work with fractional factors
            List <Task> tasks        = new List <Task>();
            int         linesPerTask = 400 / (int)interpFactor;
            int         num          = 0;

            for (int i = 0; i < frameFilesWithoutLast.Length; i += linesPerTask)
            {
                tasks.Add(GenerateFrameLines(num, i, linesPerTask, (int)interpFactor, loopEnabled, sceneDetection, debug));
                num++;
            }

            await Task.WhenAll(tasks);

            for (int x = 0; x < frameFileContents.Count; x++)
            {
                fileContent += frameFileContents[x];
            }

            lastOutFileCount++;
            fileContent += $"file '{Paths.interpDir}/{lastOutFileCount.ToString().PadLeft(Padding.interpFrames, '0')}.{ext}'";     // Last frame (source)

            if (loop)
            {
                fileContent = fileContent.Remove(fileContent.LastIndexOf("\n"));
            }

            File.WriteAllText(vfrFile, fileContent);

            if (notFirstRun)
            {
                return;                 // Skip all steps that only need to be done once
            }
            if (loop)
            {
                int    lastFileNumber      = frameFiles.Last().Name.GetInt() + 1;
                string loopFrameTargetPath = Path.Combine(frameFilesWithoutLast.First().FullName.GetParentDir(), lastFileNumber.ToString().PadLeft(Padding.inputFrames, '0') + $".png");
                if (File.Exists(loopFrameTargetPath))
                {
                    if (debug)
                    {
                        Logger.Log($"Won't copy loop frame - {Path.GetFileName(loopFrameTargetPath)} already exists.", true);
                    }
                    return;
                }
                File.Copy(frameFilesWithoutLast.First().FullName, loopFrameTargetPath);
                if (debug)
                {
                    Logger.Log($"Copied loop frame to {loopFrameTargetPath}.", true);
                }
            }
        }
Exemple #5
0
 static int GetInterpFramesAmount()
 {
     return(IOUtils.GetAmountOfFiles(interpFramesFolder, false, $"*.{InterpolateUtils.GetOutExt()}"));
 }