Esempio n. 1
0
        /// <summary>
        /// Create a CanonicalPathCache.
        /// </summary>
        ///
        /// <remarks>
        /// Creates the appropriate PathStrategy object which encapsulates
        /// the correct algorithm. Falls back to different implementations
        /// depending on platform.
        /// </remarks>
        ///
        /// <param name="maxCapacity">Size of the cache.</param>
        /// <param name="symlinks">Policy for following symlinks.</param>
        /// <returns>A new CanonicalPathCache.</returns>
        public static CanonicalPathCache Create(ILogger logger, int maxCapacity, Symlinks symlinks)
        {
            PathStrategy pathStrategy;

            switch (symlinks)
            {
            case Symlinks.Follow:
                try
                {
                    pathStrategy = Win32.IsWindows() ?
                                   (PathStrategy) new GetFinalPathNameByHandleStrategy() :
                                   (PathStrategy) new PosixSymlinkStrategy();
                }
                catch (Exception)
                {
                    // Failed to late-bind a suitable library.
                    logger.Log(Severity.Warning, "Preserving symlinks in canonical paths");
                    pathStrategy = new QueryDirectoryStrategy();
                }
                break;

            case Symlinks.Preserve:
                pathStrategy = new QueryDirectoryStrategy();
                break;

            default:
                throw new ArgumentOutOfRangeException("Invalid symlinks option");
            }

            return(new CanonicalPathCache(maxCapacity, pathStrategy));
        }
Esempio n. 2
0
        public static async Task FramesToFrames(string framesFile, string outDir, int startNo, Fraction fps, Fraction resampleFps, string format = "png", int lossyQ = 1, LogMode logMode = LogMode.OnlyLastLine)
        {
            Directory.CreateDirectory(outDir);
            string inArg    = $"-f concat -i {Path.GetFileName(framesFile)}";
            string linksDir = Path.Combine(framesFile + Paths.symlinksSuffix);

            format = format.ToLower();

            if (Config.GetBool(Config.Key.allowSymlinkEncoding, true) && Symlinks.SymlinksAllowed())
            {
                if (await Symlinks.MakeSymlinksForEncode(framesFile, linksDir, Padding.interpFrames))
                {
                    inArg = $"-i {Path.GetFileName(framesFile) + Paths.symlinksSuffix}/%{Padding.interpFrames}d{GetConcatFileExt(framesFile)}";
                }
            }

            string sn          = $"-start_number {startNo}";
            string rate        = fps.ToString().Replace(",", ".");
            string vf          = (resampleFps.GetFloat() < 0.1f) ? "" : $"-vf fps=fps={resampleFps}";
            string compression = format == "png" ? pngCompr : $"-q:v {lossyQ}";
            string codec       = format == "webp" ? "-c:v libwebp" : ""; // Specify libwebp to avoid putting all frames into single animated WEBP
            string args        = $"-vsync 0 -r {rate} {inArg} {codec} {compression} {sn} {vf} \"{outDir}/%{Padding.interpFrames}d.{format}\"";

            await RunFfmpeg(args, framesFile.GetParentDir(), logMode, "error", true);

            IoUtils.TryDeleteIfExists(linksDir);
        }
Esempio n. 3
0
        public static async Task ImportImages(string inPath, string outPath, bool alpha, Size size, bool showLog, string format)
        {
            if (showLog)
            {
                Logger.Log($"Importing images from {new DirectoryInfo(inPath).Name}...");
            }
            Logger.Log($"ImportImages() - Alpha: {alpha} - Size: {size} - Format: {format}", true, false, "ffmpeg");
            IoUtils.CreateDir(outPath);
            string concatFile = Path.Combine(Paths.GetDataPath(), "import-concat-temp.ini");

            FfmpegUtils.CreateConcatFile(inPath, concatFile, Filetypes.imagesInterpCompat);

            string inArg    = $"-f concat -safe 0 -i {concatFile.Wrap()}";
            string linksDir = Path.Combine(concatFile + Paths.symlinksSuffix);

            if (Config.GetBool(Config.Key.allowSymlinkEncoding, true) && Symlinks.SymlinksAllowed())
            {
                if (await Symlinks.MakeSymlinksForEncode(concatFile, linksDir, Padding.interpFrames))
                {
                    inArg = $"-i \"{linksDir}/%{Padding.interpFrames}d{FfmpegEncode.GetConcatFileExt(concatFile)}\"";
                }
            }

            string  sizeStr = (size.Width > 1 && size.Height > 1) ? $"-s {size.Width}x{size.Height}" : "";
            string  vf      = $"-vf {GetPadFilter()}";
            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");
        }
Esempio n. 4
0
        public static async Task CopyImages(string inpath, string outpath, bool showLog)
        {
            if (showLog)
            {
                Logger.Log($"Loading images from {new DirectoryInfo(inpath).Name}...");
            }
            Directory.CreateDirectory(outpath);

            Dictionary <string, string> moveFromTo = new Dictionary <string, string>();
            int counter = 0;

            foreach (FileInfo file in IoUtils.GetFileInfosSorted(inpath))
            {
                string newFilename = counter.ToString().PadLeft(Padding.inputFrames, '0') + file.Extension;
                moveFromTo.Add(file.FullName, Path.Combine(outpath, newFilename));
                counter++;
            }

            if (Config.GetBool(Config.Key.allowSymlinkEncoding) && Config.GetBool(Config.Key.allowSymlinkImport, true))
            {
                Logger.Log($"Symlink Import enabled, creating symlinks for input frames...", true);
                Dictionary <string, string> moveFromToSwapped = moveFromTo.ToDictionary(x => x.Value, x => x.Key);   // From/To => To/From (Link/Target)
                await Symlinks.CreateSymlinksParallel(moveFromToSwapped);
            }
            else
            {
                Logger.Log($"Symlink Import disabled, copying input frames...", true);
                await Task.Run(async() => {
                    foreach (KeyValuePair <string, string> moveFromToPair in moveFromTo)
                    {
                        File.Copy(moveFromToPair.Key, moveFromToPair.Value);
                    }
                });
            }
        }
Esempio n. 5
0
        public static async Task FramesToVideo(string framesFile, string outPath, Interpolate.OutMode outMode, Fraction fps, Fraction resampleFps, float itsScale, VidExtraData extraData, LogMode logMode = LogMode.OnlyLastLine, bool isChunk = false)
        {
            if (logMode != LogMode.Hidden)
            {
                Logger.Log((resampleFps.GetFloat() <= 0) ? "Encoding video..." : $"Encoding video resampled to {resampleFps.GetString()} FPS...");
            }

            IoUtils.RenameExistingFile(outPath);
            Directory.CreateDirectory(outPath.GetParentDir());
            string[] encArgs = Utils.GetEncArgs(Utils.GetCodec(outMode), (Interpolate.current.ScaledResolution.IsEmpty ? Interpolate.current.InputResolution : Interpolate.current.ScaledResolution), Interpolate.current.outFps.GetFloat());

            string inArg    = $"-f concat -i {Path.GetFileName(framesFile)}";
            string linksDir = Path.Combine(framesFile + Paths.symlinksSuffix);

            if (Config.GetBool(Config.Key.allowSymlinkEncoding, true) && Symlinks.SymlinksAllowed())
            {
                if (await Symlinks.MakeSymlinksForEncode(framesFile, linksDir, Padding.interpFrames))
                {
                    inArg = $"-i \"{linksDir}/%{Padding.interpFrames}d{GetConcatFileExt(framesFile)}\"";
                }
            }

            string extraArgs = Config.Get(Config.Key.ffEncArgs);

            List <string> filters = new List <string>();

            if (resampleFps.GetFloat() >= 0.1f)
            {
                filters.Add($"fps=fps={resampleFps}");
            }

            if (Config.GetBool(Config.Key.keepColorSpace) && extraData.HasAllValues())
            {
                Logger.Log($"Applying color transfer ({extraData.colorSpace}).", true, false, "ffmpeg");
                filters.Add($"scale=out_color_matrix={extraData.colorSpace}");
                extraArgs += $" -colorspace {extraData.colorSpace} -color_primaries {extraData.colorPrimaries} -color_trc {extraData.colorTransfer} -color_range:v \"{extraData.colorRange}\"";
            }

            string vf = filters.Count > 0 ? $"-vf {string.Join(",", filters)}" : "";

            fps = fps / new Fraction(itsScale);

            string args = "";

            for (int i = 0; i < encArgs.Length; i++)
            {
                string pre  = i == 0 ? "" : $" && ffmpeg {AvProcess.GetFfmpegDefaultArgs()}";
                string post = (i == 0 && encArgs.Length > 1) ? $"-f null -" : outPath.Wrap();
                string fs   = (!isChunk && outMode == Interpolate.OutMode.VidMp4) ? $"-movflags +faststart" : "";
                args += $"{pre} -vsync 0 -r {fps} {inArg} {encArgs[i]} {vf} {GetAspectArg(extraData)} {extraArgs} -threads {Config.GetInt(Config.Key.ffEncThreads)} {fs} {post} ";
            }

            //string argsOld = $"-vsync 0 -r {fps} {inArg} {encArgs} {vf} {GetAspectArg(extraData)} {extraArgs} -threads {Config.GetInt(Config.Key.ffEncThreads)} {outPath.Wrap()}";
            await RunFfmpeg(args, framesFile.GetParentDir(), logMode, !isChunk);

            IoUtils.TryDeleteIfExists(linksDir);
        }
Esempio n. 6
0
        public static async Task SymlinksCheck()
        {
            if (!IsWin10Or11())
            {
                return;
            }

            bool   silent          = Config.GetBool("silentDevmodeCheck", true);
            string ver             = Updater.GetInstalledVer().ToString();
            bool   symlinksAllowed = Symlinks.SymlinksAllowed();

            Logger.Log($"SymlinksAllowed: {symlinksAllowed}", true);

            if (!symlinksAllowed && Config.Get(Config.Key.askedForDevModeVersion) != ver)
            {
                if (!silent)
                {
                    MessageBox.Show("Flowframes will now enable Windows' Developer Mode which is required for video encoding improvements.\n\n" +
                                    "This requires administrator privileges once.", "Message");
                }

                Logger.Log($"Trying to enable dev mode.", true);

                string devmodeBatchPath = Path.Combine(Paths.GetDataPath(), "devmode.bat");
                File.WriteAllText(devmodeBatchPath, Properties.Resources.devmode);

                Process devmodeProc = OsUtils.NewProcess(true);
                devmodeProc.StartInfo.Arguments = $"/C {devmodeBatchPath.Wrap()}";
                devmodeProc.Start();
                while (!devmodeProc.HasExited)
                {
                    await Task.Delay(100);
                }

                bool symlinksWorksNow = false;

                for (int retries = 8; retries > 0; retries--)
                {
                    symlinksWorksNow = Symlinks.SymlinksAllowed();

                    if (symlinksWorksNow)
                    {
                        break;
                    }

                    await Task.Delay(500);
                }

                if (!symlinksWorksNow)
                {
                    if (!silent)
                    {
                        MessageBox.Show("Failed to enable developer mode - Perhaps you do not have sufficient privileges.\n\n" +
                                        "Without Developer Mode, video encoding will be noticably slower.\n\nYou can still try enabling " +
                                        "it manually in the Windows 10 Settings:\nSettings -> Update & security -> For developers -> Developer mode.", "Message");
                    }

                    Logger.Log("Failed to enable dev mode.", true);
                    Config.Set("askedForDevModeVersion", ver);
                }
                else
                {
                    Logger.Log("Enabled Windows Developer Mode.", silent);
                }

                IoUtils.TryDeleteIfExists(devmodeBatchPath);
            }
        }