예제 #1
0
        public static async Task <Size> GetSizeAsync(string path)
        {
            Logger.Log($"Getting media resolution ({path})", true);

            long      filesize = IoUtils.GetFilesize(path);
            QueryInfo hash     = new QueryInfo(path, filesize);

            if (filesize > 0 && CacheContains(hash))
            {
                Logger.Log($"Cache contains this hash, using cached value.", true);
                return(GetFromCache(hash));
            }
            else
            {
                Logger.Log($"Hash not cached, reading resolution.", true);
            }

            Size size;

            size = await IoUtils.GetVideoOrFramesRes(path);

            if (size.Width > 0 && size.Height > 0)
            {
                Logger.Log($"Adding hash with value {size} to cache.", true);
                cache.Add(hash, size);
            }

            return(size);
        }
예제 #2
0
        public static async Task <int> GetFrameCountAsync(string path, int retryCount = 3)
        {
            Logger.Log($"Getting frame count ({path})", true);

            long      filesize = IoUtils.GetFilesize(path);
            QueryInfo hash     = new QueryInfo(path, filesize);

            if (filesize > 0 && CacheContains(hash))
            {
                Logger.Log($"Cache contains this hash, using cached value.", true);
                return(GetFromCache(hash));
            }
            else
            {
                Logger.Log($"Hash not cached, reading frame count.", true);
            }

            int frameCount;

            if (IoUtils.IsPathDirectory(path))
            {
                frameCount = IoUtils.GetAmountOfFiles(path, false);
            }
            else
            {
                frameCount = await FfmpegCommands.GetFrameCountAsync(path);
            }

            if (frameCount > 0)
            {
                Logger.Log($"Adding hash with value {frameCount} to cache.", true);
                cache.Add(hash, frameCount);
            }
            else
            {
                if (retryCount > 0)
                {
                    Logger.Log($"Got {frameCount} frames, retrying ({retryCount} left)", true);
                    Clear();
                    frameCount = await GetFrameCountAsync(path, retryCount - 1);
                }
                else
                {
                    Logger.Log($"Failed to get frames and out of retries ({frameCount} frames for {path})", true);
                }
            }

            return(frameCount);
        }
예제 #3
0
        static async Task <string> GetOutputCached(string path, Process process)
        {
            long      filesize = IoUtils.GetFilesize(path);
            QueryInfo hash     = new QueryInfo(path, filesize, process.StartInfo.Arguments);

            if (filesize > 0 && CacheContains(hash, ref cmdCache))
            {
                Logger.Log($"GetVideoInfo: '{process.StartInfo.FileName} {process.StartInfo.Arguments}' cached, won't re-run.", true, false, "ffmpeg");
                return(GetFromCache(hash, ref cmdCache));
            }

            Logger.Log($"GetVideoInfo: '{process.StartInfo.FileName} {process.StartInfo.Arguments}' not cached, running.", true, false, "ffmpeg");
            string output = await OsUtils.GetOutputAsync(process);

            cmdCache.Add(hash, output);
            return(output);
        }
예제 #4
0
        public static async Task UpdateModelList()
        {
            if (!Config.GetBool("fetchModelsFromRepo", false))
            {
                return;
            }

            foreach (AI ai in Implementations.networks)
            {
                try
                {
                    var    client   = new WebClient();
                    string aiName   = ai.pkgDir;
                    string url      = $"https://raw.githubusercontent.com/n00mkrad/flowframes/main/Pkgs/{aiName}/models.txt";
                    string movePath = Path.Combine(Paths.GetPkgPath(), aiName, "models.txt");
                    string savePath = movePath + ".tmp";

                    if (!Directory.Exists(savePath.GetParentDir()))
                    {
                        Logger.Log($"Skipping {ai.pkgDir} models file download as '{savePath.GetParentDir()}' does not exist!", true);
                        continue;
                    }

                    Logger.Log($"Saving models file from '{url}' to '{savePath}'", true);
                    client.DownloadFile(url, savePath);

                    if (IoUtils.GetFilesize(savePath) > 8)
                    {
                        File.Delete(movePath);
                        File.Move(savePath, movePath);
                    }
                    else
                    {
                        File.Delete(savePath);
                    }

                    Program.mainForm.UpdateAiModelCombox();
                }
                catch (Exception e)
                {
                    Logger.Log($"Failed to fetch models file for {ai.friendlyName}. Ignore this if you are not connected to the internet.");
                    Logger.Log($"{e.Message}\n{e.StackTrace}", true);
                }
            }
        }
예제 #5
0
        static async Task SaveFilenameMap()
        {
            string filePath = Path.Combine(I.current.tempFolder, Paths.resumeDir, filenameMapFilename);

            if (File.Exists(filePath) && IoUtils.GetFilesize(filePath) > 0)
            {
                return;
            }

            string fileContent = "";
            int    counter     = 0;

            foreach (string file in FrameRename.importFilenames)
            {
                if (counter % 1000 == 0)
                {
                    await Task.Delay(1);
                }
                fileContent += $"{file}\n";
                counter++;
            }

            File.WriteAllText(filePath, fileContent);
        }
예제 #6
0
        public static async Task MergeStreamsFromInput(string inputVideo, string interpVideo, string tempFolder, bool shortest)
        {
            if (!File.Exists(inputVideo) && !I.current.inputIsFrames)
            {
                Logger.Log("Warning: Input video file not found, can't copy audio/subtitle streams to output video!");
                return;
            }

            string containerExt = Path.GetExtension(interpVideo);
            string tempPath     = Path.Combine(tempFolder, $"vid{containerExt}");
            string outPath      = Path.Combine(tempFolder, $"muxed{containerExt}");

            IoUtils.TryDeleteIfExists(tempPath);
            File.Move(interpVideo, tempPath);
            string inName  = Path.GetFileName(tempPath);
            string outName = Path.GetFileName(outPath);

            string subArgs = "-c:s " + Utils.GetSubCodecForContainer(containerExt);

            bool   audioCompat = Utils.ContainerSupportsAllAudioFormats(I.current.outMode, GetAudioCodecs(inputVideo));
            bool   slowmo      = I.current.outItsScale != 0 && I.current.outItsScale != 1;
            string audioArgs   = audioCompat && !slowmo ? "" : await Utils.GetAudioFallbackArgs(inputVideo, I.current.outMode, I.current.outItsScale);

            if (!audioCompat && !slowmo)
            {
                Logger.Log("Warning: Input audio format(s) not fully supported in output container - Will re-encode.", true, false, "ffmpeg");
            }

            bool audio = Config.GetBool(Config.Key.keepAudio);
            bool subs  = Config.GetBool(Config.Key.keepSubs);
            bool meta  = Config.GetBool(Config.Key.keepMeta);

            if (!audio)
            {
                audioArgs = "-an";
            }

            if (!subs || (subs && !Utils.ContainerSupportsSubs(containerExt)))
            {
                subArgs = "-sn";
            }

            bool   isMkv       = I.current.outMode == I.OutMode.VidMkv;
            string mkvFix      = isMkv ? "-max_interleave_delta 0" : ""; // https://reddit.com/r/ffmpeg/comments/efddfs/starting_new_cluster_due_to_timestamp/
            string metaArg     = (isMkv && meta) ? "-map 1:t?" : "";     // https://reddit.com/r/ffmpeg/comments/fw4jnh/how_to_make_ffmpeg_keep_attached_images_in_mkv_as/
            string shortestArg = shortest ? "-shortest" : "";

            if (QuickSettingsTab.trimEnabled)
            {
                string otherStreamsName = $"otherStreams{containerExt}";

                string[] trim  = FfmpegExtract.GetTrimArgs();
                string   args1 = $"{trim[0]} -i {inputVideo.Wrap()} {trim[1]} -map 0 -map -0:v -map -0:d -c copy {audioArgs} {subArgs} {otherStreamsName}"; // Extract trimmed
                await RunFfmpeg(args1, tempFolder, LogMode.Hidden);

                string args2 = $"-i {inName} -i {otherStreamsName} -map 0:v:0 -map 1:a:? -map 1:s:? {metaArg} -c copy {audioArgs} {subArgs} {mkvFix} {shortestArg} {outName}"; // Merge interp + trimmed original
                await RunFfmpeg(args2, tempFolder, LogMode.Hidden);

                IoUtils.TryDeleteIfExists(Path.Combine(tempFolder, otherStreamsName));
            }
            else   // If trimming is disabled we can pull the streams directly from the input file
            {
                string args = $"-i {inName} -i {inputVideo.Wrap()} -map 0:v:0 -map 1:a:? -map 1:s:? {metaArg} -c copy {audioArgs} {subArgs} {mkvFix} {shortestArg} {outName}";
                await RunFfmpeg(args, tempFolder, LogMode.Hidden);
            }

            if (File.Exists(outPath) && IoUtils.GetFilesize(outPath) > 512)
            {
                File.Delete(tempPath);
                File.Move(outPath, interpVideo);
            }
            else
            {
                File.Move(tempPath, interpVideo);   // Muxing failed, move unmuxed video file back
            }
        }