public static string GetFilesizeStr(string path) { try { return(FormatUtils.Bytes(GetFilesize(path))); } catch { return("?"); } }
public static void DeleteAllModels() { foreach (string modelFolder in GetAllModelFolders()) { string size = FormatUtils.Bytes(IoUtils.GetDirSize(modelFolder, true)); if (IoUtils.TryDeleteIfExists(modelFolder)) { Logger.Log($"Deleted cached model '{Path.GetFileName(modelFolder.GetParentDir())}/{Path.GetFileName(modelFolder)}' ({size})"); } } }
public async Task CheckModelCacheSize() { long modelFoldersBytes = 0; foreach (string modelFolder in ModelDownloader.GetAllModelFolders()) { modelFoldersBytes += IOUtils.GetDirSize(modelFolder, true); } if (modelFoldersBytes > 1024 * 1024) { clearModelCacheBtn.Text = $"Clear Model Cache ({FormatUtils.Bytes(modelFoldersBytes)})"; } else { clearModelCacheBtn.Enabled = false; } }
public static async Task ExtractAudioTracks(string inputFile, string outFolder, bool showMsg = true) { string msg = "Extracting audio from video..."; if (showMsg) { Logger.Log(msg); } List <AudioTrack> audioTracks = await GetAudioTracks(inputFile); int counter = 1; foreach (AudioTrack track in audioTracks) { if (Interpolate.canceled) { break; } string audioExt = Utils.GetAudioExt(inputFile, track.streamIndex); string outPath = Path.Combine(outFolder, $"{track.streamIndex}_{track.metadata}_audio.{audioExt}"); string args = $" -loglevel panic -i {inputFile.Wrap()} -map 0:{track.streamIndex} -vn -c:a copy {outPath.Wrap()}"; await RunFfmpeg(args, LogMode.Hidden); if (File.Exists(outPath) && IOUtils.GetFilesize(outPath) < 512) { Logger.Log($"Failed to extract audio stream #{track.streamIndex} losslessly! Trying to re-encode."); File.Delete(outPath); outPath = Path.ChangeExtension(outPath, Utils.GetAudioExtForContainer(Path.GetExtension(inputFile))); args = $" -loglevel panic -i {inputFile.Wrap()} -vn {Utils.GetAudioFallbackArgs(Path.GetExtension(inputFile))} {outPath.Wrap()}"; await RunFfmpeg(args, LogMode.Hidden, TaskType.ExtractOther, true); if (File.Exists(outPath) && IOUtils.GetFilesize(outPath) < 512) { Logger.Log($"Failed to extract audio stream #{track.streamIndex}, even with re-encoding. Will be missing from output."); IOUtils.TryDeleteIfExists(outPath); return; } Logger.Log($"Audio stream #{track.streamIndex} has been re-encoded as it can't be extracted losslessly. This may decrease the quality slightly.", false, true); } if (audioTracks.Count > 1) { Program.mainForm.SetProgress(FormatUtils.RatioInt(counter, audioTracks.Count)); } Logger.Log($"[FFCmds] Extracted audio track {track.streamIndex} to {outPath} ({FormatUtils.Bytes(IOUtils.GetFilesize(outPath))})", true, false, "ffmpeg"); counter++; } }
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); }
public static async Task MainLoop(string interpFramesPath) { if (!AutoEncodeResume.resumeNextRun) { AutoEncodeResume.Reset(); } debug = Config.GetBool("autoEncDebug", false); try { UpdateChunkAndBufferSizes(); bool imgSeq = Interpolate.current.outMode.ToString().ToLower().StartsWith("img"); interpFramesFolder = interpFramesPath; videoChunksFolder = Path.Combine(interpFramesPath.GetParentDir(), Paths.chunksDir); if (Interpolate.currentlyUsingAutoEnc) { Directory.CreateDirectory(videoChunksFolder); } encodedFrameLines.Clear(); unencodedFrameLines.Clear(); Logger.Log($"[AE] Starting AutoEncode MainLoop - Chunk Size: {chunkSize} Frames - Safety Buffer: {safetyBufferFrames} Frames", true); int chunkNo = AutoEncodeResume.encodedChunks + 1; string encFile = Path.Combine(interpFramesPath.GetParentDir(), Paths.GetFrameOrderFilename(Interpolate.current.interpFactor)); interpFramesLines = IoUtils.ReadLines(encFile).Select(x => x.Split('/').Last().Remove("'").Split('#').First()).ToArray(); // Array with frame filenames while (!Interpolate.canceled && GetInterpFramesAmount() < 2) { await Task.Delay(1000); } int lastEncodedFrameNum = 0; while (HasWorkToDo()) // Loop while proc is running and not all frames have been encoded { if (Interpolate.canceled) { return; } if (paused) { await Task.Delay(200); continue; } unencodedFrameLines.Clear(); bool aiRunning = !AiProcess.lastAiProcess.HasExited; for (int frameLineNum = lastEncodedFrameNum; frameLineNum < interpFramesLines.Length; frameLineNum++) { if (aiRunning && interpFramesLines[frameLineNum].Contains(InterpolationProgress.lastFrame.ToString().PadLeft(Padding.interpFrames, '0'))) { break; } unencodedFrameLines.Add(frameLineNum); } if (Config.GetBool(Config.Key.alwaysWaitForAutoEnc)) { int maxFrames = chunkSize + (0.5f * chunkSize).RoundToInt() + safetyBufferFrames; bool overwhelmed = unencodedFrameLines.Count > maxFrames; if (overwhelmed && !AiProcessSuspend.aiProcFrozen && OsUtils.IsProcessHidden(AiProcess.lastAiProcess)) { string dirSize = FormatUtils.Bytes(IoUtils.GetDirSize(Interpolate.current.interpFolder, true)); Logger.Log($"AutoEnc is overwhelmed! ({unencodedFrameLines.Count} unencoded frames > {maxFrames}) - Pausing.", true); AiProcessSuspend.SuspendResumeAi(true); } else if (!overwhelmed && AiProcessSuspend.aiProcFrozen) { AiProcessSuspend.SuspendResumeAi(false); } } if (unencodedFrameLines.Count > 0 && (unencodedFrameLines.Count >= (chunkSize + safetyBufferFrames) || !aiRunning)) // Encode every n frames, or after process has exited { try { List <int> frameLinesToEncode = aiRunning ? unencodedFrameLines.Take(chunkSize).ToList() : unencodedFrameLines; // Take all remaining frames if process is done string lastOfChunk = Path.Combine(interpFramesPath, interpFramesLines[frameLinesToEncode.Last()]); if (!File.Exists(lastOfChunk)) { if (debug) { Logger.Log($"[AE] Last frame of chunk doesn't exist; skipping loop iteration ({lastOfChunk})", true); } await Task.Delay(500); continue; } busy = true; string outpath = Path.Combine(videoChunksFolder, "chunks", $"{chunkNo.ToString().PadLeft(4, '0')}{FfmpegUtils.GetExt(Interpolate.current.outMode)}"); string firstFile = Path.GetFileName(interpFramesLines[frameLinesToEncode.First()].Trim()); string lastFile = Path.GetFileName(interpFramesLines[frameLinesToEncode.Last()].Trim()); Logger.Log($"[AE] Encoding Chunk #{chunkNo} to using line {frameLinesToEncode.First()} ({firstFile}) through {frameLinesToEncode.Last()} ({lastFile}) - {unencodedFrameLines.Count} unencoded frames left in total", true, false, "ffmpeg"); await Export.EncodeChunk(outpath, Interpolate.current.interpFolder, chunkNo, Interpolate.current.outMode, frameLinesToEncode.First(), frameLinesToEncode.Count); if (Interpolate.canceled) { return; } if (aiRunning && Config.GetInt(Config.Key.autoEncMode) == 2) { Task.Run(() => DeleteOldFramesAsync(interpFramesPath, frameLinesToEncode)); } if (Interpolate.canceled) { return; } encodedFrameLines.AddRange(frameLinesToEncode); Logger.Log("[AE] Done Encoding Chunk #" + chunkNo, true, false, "ffmpeg"); lastEncodedFrameNum = (frameLinesToEncode.Last() + 1); chunkNo++; AutoEncodeResume.Save(); if (!imgSeq && Config.GetInt(Config.Key.autoEncBackupMode) > 0) { if (aiRunning && (currentMuxTask == null || (currentMuxTask != null && currentMuxTask.IsCompleted))) { currentMuxTask = Task.Run(() => Export.ChunksToVideo(Interpolate.current.tempFolder, videoChunksFolder, Interpolate.current.outPath, true)); } else { Logger.Log($"[AE] Skipping backup because {(!aiRunning ? "this is the final chunk" : "previous mux task has not finished yet")}!", true, false, "ffmpeg"); } } busy = false; } catch (Exception e) { Logger.Log($"AutoEnc Chunk Encoding Error: {e.Message}. Stack Trace:\n{e.StackTrace}"); Interpolate.Cancel("Auto-Encode encountered an error."); } } await Task.Delay(50); } if (Interpolate.canceled) { return; } while (currentMuxTask != null && !currentMuxTask.IsCompleted) { await Task.Delay(100); } if (imgSeq) { return; } await Export.ChunksToVideo(Interpolate.current.tempFolder, videoChunksFolder, Interpolate.current.outPath); } catch (Exception e) { Logger.Log($"AutoEnc Error: {e.Message}. Stack Trace:\n{e.StackTrace}"); Interpolate.Cancel("Auto-Encode encountered an error."); } }