예제 #1
0
        public static bool ContainerSupportsAudioFormat(Interpolate.OutMode outMode, string format)
        {
            bool   supported = false;
            string alias     = GetAudioExt(format);

            string[] formatsMp4    = new string[] { "m4a", "mp3", "ac3", "dts" };
            string[] formatsMkv    = new string[] { "m4a", "mp3", "ac3", "dts", "ogg", "mp2", "wav", "wma" };
            string[] formatsWebm   = new string[] { "ogg" };
            string[] formatsProres = new string[] { "m4a", "ac3", "dts", "wav" };
            string[] formatsAvi    = new string[] { "m4a", "ac3", "dts" };

            switch (outMode)
            {
            case Interpolate.OutMode.VidMp4: supported = formatsMp4.Contains(alias); break;

            case Interpolate.OutMode.VidMkv: supported = formatsMkv.Contains(alias); break;

            case Interpolate.OutMode.VidWebm: supported = formatsWebm.Contains(alias); break;

            case Interpolate.OutMode.VidProRes: supported = formatsProres.Contains(alias); break;

            case Interpolate.OutMode.VidAvi: supported = formatsAvi.Contains(alias); break;
            }

            Logger.Log($"Checking if {outMode} supports audio format '{format}' ({alias}): {supported}", true, false, "ffmpeg");
            return(supported);
        }
예제 #2
0
        public static bool ContainerSupportsAudioFormat(Interpolate.OutMode outMode, string format)
        {
            format = format.Remove(".");

            string[] formatsMp4    = new string[] { "m4a", "ac3", "dts" };
            string[] formatsMkv    = new string[] { "m4a", "ac3", "dts", "ogg", "mp2", "wav" };
            string[] formatsWebm   = new string[] { "ogg" };
            string[] formatsProres = new string[] { "m4a", "ac3", "dts", "wav" };
            string[] formatsAvi    = new string[] { "m4a", "ac3", "dts" };

            switch (outMode)
            {
            case Interpolate.OutMode.VidMp4: return(formatsMp4.Contains(format));

            case Interpolate.OutMode.VidMkv: return(formatsMkv.Contains(format));

            case Interpolate.OutMode.VidWebm: return(formatsWebm.Contains(format));

            case Interpolate.OutMode.VidProRes: return(formatsProres.Contains(format));

            case Interpolate.OutMode.VidAvi: return(formatsAvi.Contains(format));
            }

            return(false);
        }
예제 #3
0
 Interpolate.OutMode GetOutMode()
 {
     Interpolate.OutMode outMode = Interpolate.OutMode.VidMp4;
     if (outModeCombox.Text.ToLower().Contains("mkv"))
     {
         outMode = Interpolate.OutMode.VidMkv;
     }
     if (outModeCombox.Text.ToLower().Contains("webm"))
     {
         outMode = Interpolate.OutMode.VidWebm;
     }
     if (outModeCombox.Text.ToLower().Contains("prores"))
     {
         outMode = Interpolate.OutMode.VidProRes;
     }
     if (outModeCombox.Text.ToLower().Contains("avi"))
     {
         outMode = Interpolate.OutMode.VidAvi;
     }
     if (outModeCombox.Text.ToLower().Contains("gif"))
     {
         outMode = Interpolate.OutMode.VidGif;
     }
     if (outModeCombox.Text.ToLower().Contains("image"))
     {
         outMode = Interpolate.OutMode.ImgPng;
     }
     return(outMode);
 }
예제 #4
0
        public InterpSettings(string inPathArg, string outPathArg, AI aiArg, float inFpsArg, int interpFactorArg, Interpolate.OutMode outModeArg, string modelArg)
        {
            inPath       = inPathArg;
            outPath      = outPathArg;
            ai           = aiArg;
            inFps        = inFpsArg;
            interpFactor = interpFactorArg;
            outFps       = inFpsArg * interpFactorArg;
            outMode      = outModeArg;
            model        = modelArg;

            alpha      = false;
            stepByStep = false;

            try
            {
                tempFolder    = InterpolateUtils.GetTempFolderLoc(inPath, outPath);
                framesFolder  = Path.Combine(tempFolder, Paths.framesDir);
                interpFolder  = Path.Combine(tempFolder, Paths.interpDir);
                inputIsFrames = IOUtils.IsPathDirectory(inPath);
            }
            catch
            {
                Logger.Log("Tried to create InterpSettings struct without an inpath. Can't set tempFolder, framesFolder and interpFolder.", true);
                tempFolder    = "";
                framesFolder  = "";
                interpFolder  = "";
                inputIsFrames = false;
            }

            inputResolution  = new Size(0, 0);
            scaledResolution = new Size(0, 0);
        }
예제 #5
0
        public void SetOutMode(Interpolate.OutMode mode)
        {
            int theIndex = 0;

            for (int i = 0; i < outModeCombox.Items.Count; i++)
            {
                string currentItem = outModeCombox.Items[i].ToString().ToLower();
                if (mode == Interpolate.OutMode.VidMkv && currentItem.Contains("mkv"))
                {
                    theIndex = i;
                }
                if (mode == Interpolate.OutMode.VidWebm && currentItem.Contains("webm"))
                {
                    theIndex = i;
                }
                if (mode == Interpolate.OutMode.VidProRes && currentItem.Contains("prores"))
                {
                    theIndex = i;
                }
                if (mode == Interpolate.OutMode.VidAvi && currentItem.Contains("avi"))
                {
                    theIndex = i;
                }
                if (mode == Interpolate.OutMode.VidGif && currentItem.Contains("gif"))
                {
                    theIndex = i;
                }
                if (mode == Interpolate.OutMode.ImgPng && currentItem.Contains("image"))
                {
                    theIndex = i;
                }
            }
            outModeCombox.SelectedIndex = theIndex;
        }
예제 #6
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);
        }
예제 #7
0
        public static async Task <string> GetAudioFallbackArgs(string videoPath, Interpolate.OutMode outMode, float itsScale)
        {
            bool   opusMp4 = Config.GetBool(Config.Key.allowOpusInMp4);
            int    opusBr  = Config.GetInt(Config.Key.opusBitrate, 128);
            int    aacBr   = Config.GetInt(Config.Key.aacBitrate, 160);
            int    ac      = (await GetVideoInfo.GetFfprobeInfoAsync(videoPath, GetVideoInfo.FfprobeMode.ShowStreams, "channels", 0)).GetInt();
            string af      = GetAudioFilters(itsScale);

            if (outMode == Interpolate.OutMode.VidMkv || outMode == Interpolate.OutMode.VidWebm || (outMode == Interpolate.OutMode.VidMp4 && opusMp4))
            {
                return($"-c:a libopus -b:a {(ac > 4 ? $"{opusBr * 2}" : $"{opusBr}")}k -ac {(ac > 0 ? $"{ac}" : "2")} {af}"); // Double bitrate if 5ch or more, ignore ac if <= 0
            }
예제 #8
0
        public static bool ContainerSupportsAllAudioFormats(Interpolate.OutMode outMode, List <string> codecs)
        {
            foreach (string format in codecs)
            {
                if (!ContainerSupportsAudioFormat(outMode, format))
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #9
0
        public static string GetAudioFallbackArgs(Interpolate.OutMode outMode)
        {
            string codec   = "aac";
            string bitrate = $"{Config.GetInt("aacBitrate", 160)}";

            if (outMode == Interpolate.OutMode.VidMkv || outMode == Interpolate.OutMode.VidWebm)
            {
                codec   = "libopus";
                bitrate = $"{Config.GetInt("opusBitrate", 128)}";
            }

            return($"-c:a {codec} -b:a {bitrate}k -ac 2");
        }
예제 #10
0
        public static bool ContainerSupportsAllAudioFormats(Interpolate.OutMode outMode, List <string> codecs)
        {
            if (codecs.Count < 1)
            {
                Logger.Log($"Warning: ContainerSupportsAllAudioFormats() was called, but codec list has {codecs.Count} entries.", true, false, "ffmpeg");
            }

            foreach (string format in codecs)
            {
                if (!ContainerSupportsAudioFormat(outMode, format))
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #11
0
        public static Codec GetCodec(Interpolate.OutMode mode)
        {
            if (mode == Interpolate.OutMode.VidMp4 || mode == Interpolate.OutMode.VidMkv)
            {
                int mp4MkvEnc = Config.GetInt(Config.Key.mp4Enc);
                if (mp4MkvEnc == 0)
                {
                    return(Codec.H264);
                }
                if (mp4MkvEnc == 1)
                {
                    return(Codec.H265);
                }
                if (mp4MkvEnc == 2)
                {
                    return(Codec.H264Nvenc);
                }
                if (mp4MkvEnc == 3)
                {
                    return(Codec.H265Nvenc);
                }
                if (mp4MkvEnc == 4)
                {
                    return(Codec.Av1);
                }
            }

            if (mode == Interpolate.OutMode.VidWebm)
            {
                return(Codec.Vp9);
            }

            if (mode == Interpolate.OutMode.VidProRes)
            {
                return(Codec.ProRes);
            }

            if (mode == Interpolate.OutMode.VidAvi)
            {
                return(Codec.AviRaw);
            }

            return(Codec.H264);
        }
예제 #12
0
        public static string GetExt(Interpolate.OutMode outMode, bool dot = true)
        {
            string ext = dot ? "." : "";

            switch (outMode)
            {
            case Interpolate.OutMode.VidMp4: ext += "mp4"; break;

            case Interpolate.OutMode.VidMkv: ext += "mkv"; break;

            case Interpolate.OutMode.VidWebm: ext += "webm"; break;

            case Interpolate.OutMode.VidProRes: ext += "mov"; break;

            case Interpolate.OutMode.VidAvi: ext += "avi"; break;

            case Interpolate.OutMode.VidGif: ext += "gif"; break;
            }

            return(ext);
        }
예제 #13
0
        public static Codec GetCodec(Interpolate.OutMode mode)
        {
            if (mode == Interpolate.OutMode.VidMp4 || mode == Interpolate.OutMode.VidMkv)
            {
                int mp4Enc = Config.GetInt("mp4Enc");
                if (mp4Enc == 0)
                {
                    return(Codec.H264);
                }
                if (mp4Enc == 1)
                {
                    return(Codec.H265);
                }
                if (mp4Enc == 2)
                {
                    return(Codec.NVENC264);
                }
                if (mp4Enc == 3)
                {
                    return(Codec.NVENC265);
                }
            }

            if (mode == Interpolate.OutMode.VidWebm)
            {
                return(Codec.VP9);
            }

            if (mode == Interpolate.OutMode.VidProRes)
            {
                return(Codec.ProRes);
            }

            if (mode == Interpolate.OutMode.VidAvi)
            {
                return(Codec.AviRaw);
            }

            return(Codec.H264);
        }
예제 #14
0
        public InterpSettings(string inPathArg, string outPathArg, AI aiArg, Fraction inFpsDetectedArg, Fraction inFpsArg, float interpFactorArg, float itsScale, Interpolate.OutMode outModeArg, ModelCollection.ModelInfo modelArg)
        {
            inPath        = inPathArg;
            outPath       = outPathArg;
            ai            = aiArg;
            inFpsDetected = inFpsDetectedArg;
            inFps         = inFpsArg;
            interpFactor  = interpFactorArg;
            outFps        = inFpsArg * (double)interpFactorArg;
            outItsScale   = itsScale;
            outMode       = outModeArg;
            model         = modelArg;

            alpha      = false;
            stepByStep = false;

            framesExt = "";
            interpExt = "";

            try
            {
                tempFolder    = InterpolateUtils.GetTempFolderLoc(inPath, outPath);
                framesFolder  = Path.Combine(tempFolder, Paths.framesDir);
                interpFolder  = Path.Combine(tempFolder, Paths.interpDir);
                inputIsFrames = IoUtils.IsPathDirectory(inPath);
            }
            catch
            {
                Logger.Log("Tried to create InterpSettings struct without an inpath. Can't set tempFolder, framesFolder and interpFolder.", true);
                tempFolder    = "";
                framesFolder  = "";
                interpFolder  = "";
                inputIsFrames = false;
            }

            _inputResolution  = new Size(0, 0);
            _scaledResolution = new Size(0, 0);

            RefreshExtensions();
        }
예제 #15
0
        public InterpSettings(string serializedData)
        {
            inPath           = "";
            outPath          = "";
            ai               = Networks.networks[0];
            inFps            = 0;
            interpFactor     = 0;
            outFps           = 0;
            outMode          = Interpolate.OutMode.VidMp4;
            model            = "";
            alpha            = false;
            stepByStep       = false;
            inputResolution  = new Size(0, 0);
            scaledResolution = new Size(0, 0);

            Dictionary <string, string> entries = new Dictionary <string, string>();

            foreach (string line in serializedData.SplitIntoLines())
            {
                if (line.Length < 3)
                {
                    continue;
                }
                string[] keyValuePair = line.Split('|');
                entries.Add(keyValuePair[0], keyValuePair[1]);
            }

            foreach (KeyValuePair <string, string> entry in entries)
            {
                switch (entry.Key)
                {
                case "INPATH": inPath = entry.Value; break;

                case "OUTPATH": outPath = entry.Value; break;

                case "AI": ai = Networks.GetAi(entry.Value); break;

                case "INFPS": inFps = float.Parse(entry.Value); break;

                case "OUTFPS": outFps = float.Parse(entry.Value); break;

                case "INTERPFACTOR": interpFactor = float.Parse(entry.Value); break;

                case "OUTMODE": outMode = (Interpolate.OutMode)Enum.Parse(typeof(Interpolate.OutMode), entry.Value); break;

                case "MODEL": model = entry.Value; break;

                case "INPUTRES": inputResolution = FormatUtils.ParseSize(entry.Value); break;

                case "OUTPUTRES": scaledResolution = FormatUtils.ParseSize(entry.Value); break;

                case "ALPHA": alpha = bool.Parse(entry.Value); break;

                case "STEPBYSTEP": stepByStep = bool.Parse(entry.Value); break;
                }
            }

            try
            {
                tempFolder    = InterpolateUtils.GetTempFolderLoc(inPath, outPath);
                framesFolder  = Path.Combine(tempFolder, Paths.framesDir);
                interpFolder  = Path.Combine(tempFolder, Paths.interpDir);
                inputIsFrames = IOUtils.IsPathDirectory(inPath);
            }
            catch
            {
                Logger.Log("Tried to create InterpSettings struct without an inpath. Can't set tempFolder, framesFolder and interpFolder.", true);
                tempFolder    = "";
                framesFolder  = "";
                interpFolder  = "";
                inputIsFrames = false;
            }
        }
예제 #16
0
        public static bool InputIsValid(string inDir, string outDir, float fpsOut, float factor, Interpolate.OutMode outMode)
        {
            bool passes = true;

            bool isFile = !IOUtils.IsPathDirectory(inDir);

            if ((passes && isFile && !IOUtils.IsFileValid(inDir)) || (!isFile && !IOUtils.IsDirValid(inDir)))
            {
                ShowMessage("Input path is not valid!");
                passes = false;
            }
            if (passes && !IOUtils.IsDirValid(outDir))
            {
                ShowMessage("Output path is not valid!");
                passes = false;
            }
            if (passes && /*factor != 2 && factor != 4 && factor != 8*/ factor > 16)
            {
                ShowMessage("Interpolation factor is not valid!");
                passes = false;
            }
            if (passes && outMode == I.OutMode.VidGif && fpsOut > 50 && !(Config.GetFloat("maxFps") != 0 && Config.GetFloat("maxFps") <= 50))
            {
                ShowMessage("Invalid output frame rate!\nGIF does not properly support frame rates above 50 FPS.\nPlease use MP4, WEBM or another video format.");
                passes = false;
            }
            if (passes && fpsOut < 1 || fpsOut > 1000)
            {
                ShowMessage("Invalid output frame rate - Must be 1-1000.");
                passes = false;
            }
            if (!passes)
            {
                I.Cancel("Invalid settings detected.", true);
            }
            return(passes);
        }
예제 #17
0
        public static async Task ExtractSubtitles(string inputFile, string outFolder, Interpolate.OutMode outMode, bool showMsg = true)
        {
            try
            {
                string msg = "Extracting subtitles from video...";
                if (showMsg)
                {
                    Logger.Log(msg);
                }

                List <SubtitleTrack> subtitleTracks = await GetSubtitleTracks(inputFile);

                int counter = 1;
                int extractedSuccessfully = 0;

                foreach (SubtitleTrack subTrack in subtitleTracks)
                {
                    if (Interpolate.canceled)
                    {
                        break;
                    }

                    string outPath = Path.Combine(outFolder, $"{subTrack.streamIndex}_{subTrack.lang}_{subTrack.encoding}.srt");
                    string args    = $" -loglevel error -sub_charenc {subTrack.encoding} -i {inputFile.Wrap()} -map 0:{subTrack.streamIndex} {outPath.Wrap()}";
                    await RunFfmpeg(args, LogMode.Hidden);

                    if (subtitleTracks.Count > 4)
                    {
                        Program.mainForm.SetProgress(FormatUtils.RatioInt(counter, subtitleTracks.Count));
                    }
                    counter++;

                    if (IOUtils.GetFilesize(outPath) >= 32)
                    {
                        Logger.Log($"[FFCmds] Extracted subtitle track {subTrack.streamIndex} to {outPath} ({FormatUtils.Bytes(IOUtils.GetFilesize(outPath))})", true, false, "ffmpeg");
                        extractedSuccessfully++;
                    }
                    else
                    {
                        IOUtils.TryDeleteIfExists(outPath);     // Delete if encode was not successful
                    }
                }

                if (extractedSuccessfully > 0)
                {
                    Logger.Log($"Extracted {extractedSuccessfully} subtitle tracks from the input video.", false, Logger.GetLastLine().Contains(msg));
                    Utils.ContainerSupportsSubs(Utils.GetExt(outMode), true);
                }
            }
            catch (Exception e)
            {
                Logger.Log("Error extracting subtitles: " + e.Message);
            }

            Program.mainForm.SetProgress(0);
        }
예제 #18
0
        public static async Task FramesToVideoConcat(string framesFile, string outPath, Interpolate.OutMode outMode, float fps, float resampleFps, LogMode logMode = LogMode.OnlyLastLine, bool isChunk = false)
        {
            if (logMode != LogMode.Hidden)
            {
                Logger.Log((resampleFps <= 0) ? $"Encoding video..." : $"Encoding video resampled to {resampleFps.ToString().Replace(",", ".")} FPS...");
            }
            Directory.CreateDirectory(outPath.GetParentDir());
            string encArgs = Utils.GetEncArgs(Utils.GetCodec(outMode));

            if (!isChunk)
            {
                encArgs += $" -movflags +faststart";
            }
            string vfrFilename = Path.GetFileName(framesFile);
            string rate        = fps.ToString().Replace(",", ".");
            string vf          = (resampleFps <= 0) ? "" : $"-vf fps=fps={resampleFps.ToStringDot()}";
            string extraArgs   = Config.Get("ffEncArgs");
            string args        = $"-vsync 0 -f concat -r {rate} -i {vfrFilename} {encArgs} {vf} {extraArgs} -threads {Config.GetInt("ffEncThreads")} {outPath.Wrap()}";

            await RunFfmpeg(args, framesFile.GetParentDir(), logMode, "error", TaskType.Encode, !isChunk);
        }
예제 #19
0
 public static async Task FramesToVideoConcat(string framesFile, string outPath, Interpolate.OutMode outMode, float fps, LogMode logMode = LogMode.OnlyLastLine, bool isChunk = false)
 {
     await FramesToVideoConcat(framesFile, outPath, outMode, fps, 0, logMode, isChunk);
 }