Example #1
0
        public static async Task ExportFrames(string path, string outFolder, I.OutMode mode, bool stepByStep)
        {
            if (Config.GetInt(Config.Key.sceneChangeFillMode) == 1)
            {
                string frameFile = Path.Combine(I.current.tempFolder, Paths.GetFrameOrderFilename(I.current.interpFactor));
                await Blend.BlendSceneChanges(frameFile);
            }

            if (!mode.ToString().ToLower().Contains("vid"))     // Copy interp frames out of temp folder and skip video export for image seq export
            {
                try
                {
                    await ExportImageSequence(path, stepByStep);
                }
                catch (Exception e)
                {
                    Logger.Log("Failed to move interpolated frames: " + e.Message);
                    Logger.Log("Stack Trace:\n " + e.StackTrace, true);
                }

                return;
            }

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

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

            try
            {
                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(Config.Key.maxFpsMode) == 0;

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

                if (fpsLimit)
                {
                    await Encode(mode, path, Path.Combine(outFolder, await 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.");
            }
        }
Example #2
0
        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.");
            }
        }
Example #3
0
        static async Task Encode(I.OutMode mode, string framesPath, string outPath, float fps, float resampleFps = -1)
        {
            currentOutFile = outPath;
            string vfrFile = Path.Combine(framesPath.GetParentDir(), Paths.GetFrameOrderFilename(I.current.interpFactor));

            if (!File.Exists(vfrFile))
            {
                bool sbs = Config.GetInt("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(vfrFile, outPath, fps, true, Config.GetInt("gifColors"), resampleFps);
            }
            else
            {
                await FfmpegEncode.FramesToVideoConcat(vfrFile, outPath, mode, fps, resampleFps);
                await MuxOutputVideo(I.current.inPath, outPath);
                await Loop(currentOutFile, GetLoopTimes());
            }
        }
Example #4
0
        public static async Task EncodeChunk(string outPath, I.OutMode mode, int firstFrameNum, int framesAmount)
        {
            string vfrFileOriginal = Path.Combine(I.current.tempFolder, Paths.GetFrameOrderFilename(I.current.interpFactor));
            string vfrFile         = Path.Combine(I.current.tempFolder, Paths.GetFrameOrderFilenameChunk(firstFrameNum, firstFrameNum + framesAmount));

            File.WriteAllLines(vfrFile, IOUtils.ReadLines(vfrFileOriginal).Skip(firstFrameNum).Take(framesAmount));

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

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

            if (!dontEncodeFullFpsVid)
            {
                await FfmpegEncode.FramesToVideoConcat(vfrFile, outPath, mode, I.current.outFps, AvProcess.LogMode.Hidden, true);     // Encode
            }
            if (fpsLimit)
            {
                string filename     = Path.GetFileName(outPath);
                string newParentDir = outPath.GetParentDir() + Paths.fpsLimitSuffix;
                outPath = Path.Combine(newParentDir, filename);
                await FfmpegEncode.FramesToVideoConcat(vfrFile, outPath, mode, I.current.outFps, maxFps, AvProcess.LogMode.Hidden, true);     // Encode with limited fps
            }
        }
Example #5
0
        static async Task Encode(I.OutMode mode, string framesPath, string outPath, Fraction fps, Fraction resampleFps)
        {
            string framesFile = Path.Combine(framesPath.GetParentDir(), Paths.GetFrameOrderFilename(I.current.interpFactor));

            if (!File.Exists(framesFile))
            {
                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(Config.Key.gifColors), resampleFps, I.current.outItsScale);
            }
            else
            {
                VidExtraData extraData = await FfmpegCommands.GetVidExtraInfo(I.current.inPath);

                await FfmpegEncode.FramesToVideo(framesFile, outPath, mode, fps, resampleFps, I.current.outItsScale, extraData);
                await MuxOutputVideo(I.current.inPath, outPath);
                await Loop(outPath, await GetLoopTimes());
            }
        }
Example #6
0
        public static bool InputIsValid(string inDir, string outDir, Fraction fpsIn, float factor, I.OutMode outMode)
        {
            try
            {
                bool  passes = true;
                bool  isFile = !IoUtils.IsPathDirectory(inDir);
                float fpsOut = fpsIn.GetFloat() * factor;

                if ((passes && isFile && !IoUtils.IsFileValid(inDir)) || (!isFile && !IoUtils.IsDirValid(inDir)))
                {
                    UiUtils.ShowMessageBox("Input path is not valid!");
                    passes = false;
                }

                if (passes && !IoUtils.IsDirValid(outDir))
                {
                    UiUtils.ShowMessageBox("Output path is not valid!");
                    passes = false;
                }

                if (passes && fpsOut < 1f || fpsOut > 1000f)
                {
                    string imgSeqNote = isFile ? "" : "\n\nWhen using an image sequence as input, you always have to specify the frame rate manually.";
                    UiUtils.ShowMessageBox($"Invalid output frame rate ({fpsOut}).\nMust be 1-1000.{imgSeqNote}");
                    passes = false;
                }

                string fpsLimitValue = Config.Get(Config.Key.maxFps);
                float  fpsLimit      = (fpsLimitValue.Contains("/") ? new Fraction(Config.Get(Config.Key.maxFps)).GetFloat() : fpsLimitValue.GetFloat());

                if (outMode == I.OutMode.VidGif && fpsOut > 50 && !(fpsLimit > 0 && fpsLimit <= 50))
                {
                    Logger.Log($"Warning: GIF will be encoded at 50 FPS instead of {fpsOut} as the format doesn't support frame rates that high.");
                }

                if (!passes)
                {
                    I.Cancel("Invalid settings detected.", true);
                }

                return(passes);
            }
            catch (Exception e)
            {
                Logger.Log($"Failed to run InputIsValid: {e.Message}\n{e.StackTrace}", true);
                return(false);
            }
        }
Example #7
0
        public static async Task EncodeChunk(string outPath, string interpDir, int chunkNo, I.OutMode mode, int firstFrameNum, int framesAmount)
        {
            string framesFileFull = Path.Combine(I.current.tempFolder, Paths.GetFrameOrderFilename(I.current.interpFactor));
            string concatFile     = Path.Combine(I.current.tempFolder, Paths.GetFrameOrderFilenameChunk(firstFrameNum, firstFrameNum + framesAmount));

            File.WriteAllLines(concatFile, IoUtils.ReadLines(framesFileFull).Skip(firstFrameNum).Take(framesAmount));

            List <string> inputFrames = JsonConvert.DeserializeObject <List <string> >(File.ReadAllText(framesFileFull + ".inputframes.json")).Skip(firstFrameNum).Take(framesAmount).ToList();

            if (Config.GetInt(Config.Key.sceneChangeFillMode) == 1)
            {
                await Blend.BlendSceneChanges(concatFile, false);
            }

            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(Config.Key.maxFpsMode) == 0;

            if (mode.ToString().ToLower().StartsWith("img"))    // Image Sequence output mode, not video
            {
                string desiredFormat   = Config.Get(Config.Key.imgSeqFormat);
                string availableFormat = Path.GetExtension(IoUtils.GetFilesSorted(interpDir)[0]).Remove(".").ToUpper();

                if (!dontEncodeFullFpsVid)
                {
                    string outFolderPath = Path.Combine(I.current.outPath, await IoUtils.GetCurrentExportFilename(false, false));
                    int    startNo       = IoUtils.GetAmountOfFiles(outFolderPath, false) + 1;

                    if (chunkNo == 1)    // Only check for existing folder on first chunk, otherwise each chunk makes a new folder
                    {
                        IoUtils.RenameExistingFolder(outFolderPath);
                    }

                    if (desiredFormat.ToUpper() == availableFormat.ToUpper())   // Move if frames are already in the desired format
                    {
                        await CopyOutputFrames(interpDir, concatFile, outFolderPath, startNo, fpsLimit, true);
                    }
                    else    // Encode if frames are not in desired format
                    {
                        await FfmpegEncode.FramesToFrames(concatFile, outFolderPath, startNo, I.current.outFps, new Fraction(), desiredFormat, GetImgSeqQ(desiredFormat), AvProcess.LogMode.Hidden);
                    }
                }

                if (fpsLimit)
                {
                    string outputFolderPath = Path.Combine(I.current.outPath, await IoUtils.GetCurrentExportFilename(true, false));
                    int    startNumber      = IoUtils.GetAmountOfFiles(outputFolderPath, false) + 1;
                    await FfmpegEncode.FramesToFrames(concatFile, outputFolderPath, startNumber, I.current.outFps, maxFps, desiredFormat, GetImgSeqQ(desiredFormat), AvProcess.LogMode.Hidden);
                }
            }
            else
            {
                if (!dontEncodeFullFpsVid)
                {
                    await FfmpegEncode.FramesToVideo(concatFile, outPath, mode, I.current.outFps, new Fraction(), I.current.outItsScale, extraData, AvProcess.LogMode.Hidden, true);     // Encode
                }
                if (fpsLimit)
                {
                    string filename     = Path.GetFileName(outPath);
                    string newParentDir = outPath.GetParentDir() + Paths.fpsLimitSuffix;
                    outPath = Path.Combine(newParentDir, filename);
                    await FfmpegEncode.FramesToVideo(concatFile, outPath, mode, I.current.outFps, maxFps, I.current.outItsScale, extraData, AvProcess.LogMode.Hidden, true);     // Encode with limited fps
                }
            }

            AutoEncodeResume.encodedChunks += 1;
            AutoEncodeResume.encodedFrames += framesAmount;
            AutoEncodeResume.processedInputFrames.AddRange(inputFrames);
        }