/// <summary> /// Create the EcmTools object /// </summary> /// <param name="exePath">Where ecm.exe and unecm.exe are</param> public EcmTools(string exePath = "") { string binPath = exePath; exe_ecm = Path.Combine(binPath, EXECUTABLE_ECM); exe_unecm = Path.Combine(binPath, EXECUTABLE_UNECM); app = new CliApp(""); // Set executable later app.onComplete = (code) => { if (code == 0) { onComplete?.Invoke(true); } else { ERROR = "EcmTools error."; onComplete?.Invoke(false); } }; app.onStdErr = (s) => { // Read the progress percent and push it var m = Regex.Match(s, @"\s*" + regexString + @" \((\d{1,3})%"); if (m.Success) { progress = int.Parse(m.Groups[1].Value); // Debug.WriteLine("CAPTURED PERCENT - " + m.Groups[1].Value); onProgress?.Invoke(progress); } }; } // -----------------------------------------
}// ----------- /// <summary> /// FFMPEG wrapper /// </summary> /// <param name="executablePath">Set the path of ffmpeg if not on path already</param> public FFmpeg(string executablePath = "") { proc = new CliApp(Path.Combine(executablePath,EXECUTABLE_NAME)); proc.onComplete = (code) => { if (code == 0) { onComplete?.Invoke(true); } else { ERROR = "Something went wrong with FFMPEG"; onComplete?.Invoke(false); } }; // -- FFMPEG writes Status to StdErr // Gets current operation progress ( proc.onStdErr = (s) => { if (targetSeconds == 0) return; secondsConverted = readSecondsFromOutput(s, @"time=(\d{2}):(\d{2}):(\d{2})"); if (secondsConverted == -1) return; progress = (int)Math.Ceiling(((double)secondsConverted / (double)targetSeconds) * 100f); // LOG.log("[FFMPEG] : {0} / {1} = {2}", secondsConverted, targetSeconds, progress); if (progress > 100) progress = 100; onProgress?.Invoke(progress); }; }// -----------------------------------------
// -- public FreeArc(string exePath = "") { SOLID = false; proc = new CliApp(Path.Combine(exePath, EXECUTABLE_NAME)); proc.flag_stdout_word_mode = true; proc.onStdOutWord = onStdOutWordGetProgress; proc.onComplete = (code) => { COMPRESSED_SIZE = 0; if (code > 0) { ERROR = proc.stdErrLog; onComplete?.Invoke(false); return; } if (operation == "compress") { // Try to read the stdout string and get final size // 'Compressed 2 files, 127,707 => 120,363 bytes. Ratio 94.2%' var m = Regex.Match(proc.stdOutLog, @"=> (.*) bytes"); if (m.Success) { var ss = m.Groups[1].Value.Replace(",", string.Empty); COMPRESSED_SIZE = long.Parse(ss); } } onComplete?.Invoke(true); }; }// -----------------------------------------
public SevenZip(string exePath = "") { SOLID = false; proc = new CliApp(Path.Combine(exePath, EXECUTABLE_NAME)); proc.onStdOut = capture_stdout_percent; proc.onComplete = (code) => { COMPRESSED_SIZE = 0; proc.onStdOut = null; if (code > 0) { ERROR = proc.stdErrLog; onComplete?.Invoke(false); return; } if (operation == "compress") { // Get archive size // Archive size: (\d+) // STDOUT Example : `..Add new data to archive: 1 file, 544971 bytes (533 KiB)Files read from disk: 1Archive size: 544561 bytes (532 KiB)Everything is Ok` var m = Regex.Match(proc.stdOutLog, @"Archive size: (\d+)", RegexOptions.IgnoreCase); if (m.Success) { COMPRESSED_SIZE = long.Parse(m.Groups[1].Value); } } onComplete?.Invoke(true); }; }// ---
}// ----------------------------------------- /// <summary> /// Quickly create a CLI APP and return it /// </summary> static public CliApp quickStart(string filename, string args = null,Action<int> OnComplete = null) { var c = new CliApp(filename); c.onComplete = OnComplete; c.start(args); return c; }// -----------------------------------------
/// <summary> /// Read a file's duration, used for when converting to PCM /// </summary> /// <param name="file"></param> private int getSecondsFromFile(string input) { int i = 0; var s = CliApp.quickStartSync(proc.executable,$"-i \"{input}\" -f null -"); if(s[2]=="0") // ffmpeg success { i = readSecondsFromOutput(s[1], @"\s*Duration:\s*(\d{2}):(\d{2}):(\d{2})"); } return i; }// -----------------------------------------
/// <summary> /// Read a file's duration, used for when converting to PCM /// </summary> /// <param name="file"></param> private int getSecondsFromFile(string input) { int i = 0; var s = CliApp.quickStartSync(proc.executable, string.Format("-i \"{0}\" -f null -", input)); if (s[2] == "0") // ffmpeg success { i = readSecondsFromOutput(s[1], @"\s*Duration:\s*(\d{2}):(\d{2}):(\d{2})"); LOG.log("[FFMPEG] : {0} duration in seconds = {1}", input, i); } return(i); }// -----------------------------------------
}// ----------------------------------------- /// <summary> /// Check to see if an executable exists / can be run /// </summary> /// <param name="exePath"></param> /// <returns></returns> static public bool exists(string exePath) { var app = new CliApp(exePath); try{ app.proc.Start(); app.proc.WaitForExit(); }catch (System.ComponentModel.Win32Exception) { return(false); } return(true); } // -----------------------------------------
}// ----------------------------------------- /** * Quickly create a CLI APP in SYNC and return its stdOut and stdErr * Returns [ stdOut, stdErr, ExitCode ] */ static public string[] quickStartSync(string exePath,string args = null) { var app = new CliApp(exePath); app.proc.StartInfo.Arguments = args; app.proc.Start(); app.proc.WaitForExit(); var s = new string[] { app.proc.StandardOutput.ReadToEnd(), app.proc.StandardError.ReadToEnd(), app.proc.ExitCode.ToString() }; // app.proc.Close(); // DO NOT CLOSE!! ~CliApp() will handle the process ending return s; }// -----------------------------------------
// -- public Tak(string exePath = "") { proc = new CliApp(Path.Combine(exePath,EXECUTABLE_NAME)); proc.onComplete = (code) => { if (code == 0) { onComplete?.Invoke(true); } else { ERROR = proc.stdErrLog; onComplete?.Invoke(false); } }; }// -----------------------------------------
// -- public FreeArc(string exePath = "") { proc = new CliApp(Path.Combine(exePath, EXECUTABLE_NAME), true); proc.onComplete = (code) => { if (code == 0) { onComplete?.Invoke(true); } else { ERROR = proc.stdErrLog; onComplete(false); } }; proc.onStdOutWord = onStdOutWordGetProgress; }// -----------------------------------------
// ----------------------------------------- /// <summary> /// FFMPEG wrapper /// </summary> /// <param name="executablePath">Set the path of ffmpeg if not on path already</param> public FFmpeg(string executablePath = "") { proc = new CliApp(Path.Combine(executablePath, EXECUTABLE_NAME)); proc.onComplete = (code) => { if (code == 0) { onComplete?.Invoke(true); } else { ERROR = "Something went wrong with FFMPEG"; onComplete(false); } }; // Get and calculate progress, "targetSeconds" needs to be set for this to work proc.onStdErr = (s) => { if (targetSeconds == 0) { return; } secondsConverted = readSecondsFromOutput(s, @"time=(\d{2}):(\d{2}):(\d{2})"); if (secondsConverted == -1) { return; } progress = (int)Math.Ceiling(((double)secondsConverted / (double)targetSeconds) * 100f); // LOG.log("[FFMPEG] : {0} / {1} = {2}", secondsConverted, targetSeconds, progress); if (progress > 100) { progress = 100; } onProgress?.Invoke(progress); }; }// -----------------------------------------
// -- public FreeArc(string exePath = "") { proc = new CliApp(Path.Combine(exePath, EXECUTABLE_NAME)); proc.onComplete = (code) => { if (code == 0) { onComplete?.Invoke(true); } else { ERROR = proc.stdErrLog; onComplete(false); } }; // FREEARC writes to stdout //proc.onStdOut = (s) => //{ // Tried to read the progress, but can't //}; }// -----------------------------------------