2020-11-23 16:51:05 +01:00
|
|
|
|
using Flowframes.IO;
|
|
|
|
|
|
using Flowframes.OS;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Flowframes
|
|
|
|
|
|
{
|
|
|
|
|
|
class AvProcess
|
|
|
|
|
|
{
|
|
|
|
|
|
public static Process lastProcess;
|
2021-01-06 22:51:04 +01:00
|
|
|
|
public enum TaskType { ExtractFrames, Encode, GetInfo, Merge, Other };
|
|
|
|
|
|
public static TaskType lastTask = TaskType.Other;
|
2020-11-23 16:51:05 +01:00
|
|
|
|
|
|
|
|
|
|
public static string lastOutputFfmpeg;
|
|
|
|
|
|
public static string lastOutputGifski;
|
|
|
|
|
|
|
|
|
|
|
|
public enum LogMode { Visible, OnlyLastLine, Hidden }
|
|
|
|
|
|
static LogMode currentLogMode;
|
|
|
|
|
|
|
2021-01-06 22:51:04 +01:00
|
|
|
|
public static async Task RunFfmpeg(string args, LogMode logMode, TaskType taskType = TaskType.Other)
|
2020-11-30 20:32:33 +01:00
|
|
|
|
{
|
2021-01-07 12:15:13 +01:00
|
|
|
|
await RunFfmpeg(args, "", logMode, taskType);
|
2020-11-30 20:32:33 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-01-06 22:51:04 +01:00
|
|
|
|
public static async Task RunFfmpeg(string args, string workingDir, LogMode logMode, TaskType taskType = TaskType.Other)
|
2020-11-23 16:51:05 +01:00
|
|
|
|
{
|
|
|
|
|
|
lastOutputFfmpeg = "";
|
|
|
|
|
|
currentLogMode = logMode;
|
2021-01-04 14:27:34 +01:00
|
|
|
|
Process ffmpeg = OSUtils.NewProcess(true);
|
2020-11-23 16:51:05 +01:00
|
|
|
|
lastProcess = ffmpeg;
|
2021-01-06 22:51:04 +01:00
|
|
|
|
lastTask = taskType;
|
2020-11-30 20:32:33 +01:00
|
|
|
|
if(!string.IsNullOrWhiteSpace(workingDir))
|
2020-12-27 22:52:14 +01:00
|
|
|
|
ffmpeg.StartInfo.Arguments = $"{GetCmdArg()} cd /D {workingDir.Wrap()} & {Path.Combine(GetAvDir(), "ffmpeg.exe").Wrap()} -hide_banner -loglevel warning -y -stats {args}";
|
2020-11-30 20:32:33 +01:00
|
|
|
|
else
|
2020-12-27 22:52:14 +01:00
|
|
|
|
ffmpeg.StartInfo.Arguments = $"{GetCmdArg()} cd /D {GetAvDir().Wrap()} & ffmpeg.exe -hide_banner -loglevel warning -y -stats {args}";
|
2020-11-30 20:32:33 +01:00
|
|
|
|
if (logMode != LogMode.Hidden) Logger.Log("Running ffmpeg...", false);
|
2020-12-27 22:52:14 +01:00
|
|
|
|
Logger.Log("cmd.exe " + ffmpeg.StartInfo.Arguments, true, false, "ffmpeg");
|
2020-11-25 12:40:17 +01:00
|
|
|
|
ffmpeg.OutputDataReceived += new DataReceivedEventHandler(FfmpegOutputHandler);
|
|
|
|
|
|
ffmpeg.ErrorDataReceived += new DataReceivedEventHandler(FfmpegOutputHandler);
|
2020-11-23 16:51:05 +01:00
|
|
|
|
ffmpeg.Start();
|
|
|
|
|
|
ffmpeg.BeginOutputReadLine();
|
|
|
|
|
|
ffmpeg.BeginErrorReadLine();
|
|
|
|
|
|
while (!ffmpeg.HasExited)
|
2020-12-27 22:52:14 +01:00
|
|
|
|
await Task.Delay(1);
|
2020-11-23 16:51:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-11-25 12:40:17 +01:00
|
|
|
|
static void FfmpegOutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
|
2020-11-23 16:51:05 +01:00
|
|
|
|
{
|
2020-11-26 20:17:18 +01:00
|
|
|
|
if (outLine == null || outLine.Data == null)
|
|
|
|
|
|
return;
|
|
|
|
|
|
string line = outLine.Data;
|
2021-01-06 21:44:09 +01:00
|
|
|
|
lastOutputFfmpeg = lastOutputFfmpeg + "\n" + line;
|
2020-11-23 16:51:05 +01:00
|
|
|
|
bool hidden = currentLogMode == LogMode.Hidden;
|
|
|
|
|
|
bool replaceLastLine = currentLogMode == LogMode.OnlyLastLine;
|
2020-11-26 20:17:18 +01:00
|
|
|
|
string trimmedLine = line.Remove("q=-0.0").Remove("size=N/A").Remove("bitrate=N/A").TrimWhitespaces();
|
2020-12-27 22:52:14 +01:00
|
|
|
|
Logger.Log(trimmedLine, hidden, replaceLastLine, "ffmpeg");
|
2020-11-26 20:17:18 +01:00
|
|
|
|
|
|
|
|
|
|
if(line.Contains("Could not open file"))
|
2021-01-06 21:44:09 +01:00
|
|
|
|
Interpolate.Cancel($"FFmpeg Error: {line}");
|
2021-01-14 17:55:00 +01:00
|
|
|
|
|
|
|
|
|
|
if (line.Contains("No NVENC capable devices found"))
|
|
|
|
|
|
Interpolate.Cancel($"FFmpeg Error: {line}\nMake sure you have an NVENC-capable Nvidia GPU.");
|
2020-11-23 16:51:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-12-27 22:52:14 +01:00
|
|
|
|
static void FfmpegOutputHandlerSilent (object sendingProcess, DataReceivedEventArgs outLine)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (outLine == null || outLine.Data == null || outLine.Data.Trim().Length < 2)
|
|
|
|
|
|
return;
|
|
|
|
|
|
string line = outLine.Data;
|
|
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(lastOutputFfmpeg))
|
|
|
|
|
|
lastOutputFfmpeg += "\n";
|
|
|
|
|
|
lastOutputFfmpeg = lastOutputFfmpeg + line;
|
|
|
|
|
|
Logger.Log(line, true, false, "ffmpeg");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-11-23 16:51:05 +01:00
|
|
|
|
public static string GetFfmpegOutput (string args)
|
|
|
|
|
|
{
|
|
|
|
|
|
Process ffmpeg = OSUtils.NewProcess(true);
|
2020-12-27 22:52:14 +01:00
|
|
|
|
lastProcess = ffmpeg;
|
|
|
|
|
|
ffmpeg.StartInfo.Arguments = $"{GetCmdArg()} cd /D {GetAvDir().Wrap()} & ffmpeg.exe -hide_banner -y -stats {args}";
|
|
|
|
|
|
Logger.Log("cmd.exe " + ffmpeg.StartInfo.Arguments, true, false, "ffmpeg");
|
2020-11-23 16:51:05 +01:00
|
|
|
|
ffmpeg.Start();
|
|
|
|
|
|
ffmpeg.WaitForExit();
|
|
|
|
|
|
string output = ffmpeg.StandardOutput.ReadToEnd();
|
|
|
|
|
|
string err = ffmpeg.StandardError.ReadToEnd();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(err)) output += "\n" + err;
|
|
|
|
|
|
return output;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-12-27 22:52:14 +01:00
|
|
|
|
public static async Task<string> GetFfmpegOutputAsync(string args, bool setBusy = false)
|
|
|
|
|
|
{
|
2021-01-05 23:13:29 +01:00
|
|
|
|
if (Program.busy)
|
|
|
|
|
|
setBusy = false;
|
2020-12-27 22:52:14 +01:00
|
|
|
|
lastOutputFfmpeg = "";
|
|
|
|
|
|
Process ffmpeg = OSUtils.NewProcess(true);
|
|
|
|
|
|
lastProcess = ffmpeg;
|
|
|
|
|
|
ffmpeg.StartInfo.Arguments = $"{GetCmdArg()} cd /D {GetAvDir().Wrap()} & ffmpeg.exe -hide_banner -y -stats {args}";
|
|
|
|
|
|
Logger.Log("cmd.exe " + ffmpeg.StartInfo.Arguments, true, false, "ffmpeg");
|
|
|
|
|
|
if (setBusy)
|
|
|
|
|
|
Program.mainForm.SetWorking(true);
|
|
|
|
|
|
ffmpeg.Start();
|
|
|
|
|
|
ffmpeg.OutputDataReceived += new DataReceivedEventHandler(FfmpegOutputHandlerSilent);
|
|
|
|
|
|
ffmpeg.ErrorDataReceived += new DataReceivedEventHandler(FfmpegOutputHandlerSilent);
|
|
|
|
|
|
ffmpeg.Start();
|
|
|
|
|
|
ffmpeg.BeginOutputReadLine();
|
|
|
|
|
|
ffmpeg.BeginErrorReadLine();
|
|
|
|
|
|
while (!ffmpeg.HasExited)
|
2021-01-16 02:30:46 +01:00
|
|
|
|
await Task.Delay(10);
|
2020-12-27 22:52:14 +01:00
|
|
|
|
if (setBusy)
|
|
|
|
|
|
Program.mainForm.SetWorking(false);
|
2021-01-16 02:30:46 +01:00
|
|
|
|
await Task.Delay(100);
|
2020-12-27 22:52:14 +01:00
|
|
|
|
return lastOutputFfmpeg;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-11-23 16:51:05 +01:00
|
|
|
|
public static string GetFfprobeOutput (string args)
|
|
|
|
|
|
{
|
|
|
|
|
|
Process ffprobe = OSUtils.NewProcess(true);
|
2020-12-27 22:52:14 +01:00
|
|
|
|
ffprobe.StartInfo.Arguments = $"{GetCmdArg()} cd /D {GetAvDir().Wrap()} & ffprobe.exe {args}";
|
|
|
|
|
|
Logger.Log("cmd.exe " + ffprobe.StartInfo.Arguments, true, false, "ffmpeg");
|
2020-11-23 16:51:05 +01:00
|
|
|
|
ffprobe.Start();
|
|
|
|
|
|
ffprobe.WaitForExit();
|
|
|
|
|
|
string output = ffprobe.StandardOutput.ReadToEnd();
|
|
|
|
|
|
string err = ffprobe.StandardError.ReadToEnd();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(err)) output += "\n" + err;
|
|
|
|
|
|
return output;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-12-27 22:52:14 +01:00
|
|
|
|
public static async Task<string> GetFfprobeOutputAsync(string args)
|
|
|
|
|
|
{
|
|
|
|
|
|
Process ffprobe = OSUtils.NewProcess(true);
|
|
|
|
|
|
ffprobe.StartInfo.Arguments = $"{GetCmdArg()} cd /D {GetAvDir().Wrap()} & ffprobe.exe {args}";
|
|
|
|
|
|
Logger.Log("cmd.exe " + ffprobe.StartInfo.Arguments, true, false, "ffmpeg");
|
|
|
|
|
|
ffprobe.Start();
|
|
|
|
|
|
while (!ffprobe.HasExited)
|
|
|
|
|
|
await Task.Delay(1);
|
|
|
|
|
|
string output = ffprobe.StandardOutput.ReadToEnd();
|
|
|
|
|
|
string err = ffprobe.StandardError.ReadToEnd();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(err)) output += "\n" + err;
|
|
|
|
|
|
return output;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-11-23 16:51:05 +01:00
|
|
|
|
public static async Task RunGifski(string args, LogMode logMode)
|
|
|
|
|
|
{
|
|
|
|
|
|
lastOutputGifski = "";
|
|
|
|
|
|
currentLogMode = logMode;
|
|
|
|
|
|
Process gifski = OSUtils.NewProcess(true);
|
|
|
|
|
|
lastProcess = gifski;
|
2020-12-27 22:52:14 +01:00
|
|
|
|
gifski.StartInfo.Arguments = $"{GetCmdArg()} cd /D {GetAvDir().Wrap()} & gifski.exe {args}";
|
2020-11-23 16:51:05 +01:00
|
|
|
|
Logger.Log("Running gifski...");
|
2020-12-27 22:52:14 +01:00
|
|
|
|
Logger.Log("cmd.exe " + gifski.StartInfo.Arguments, true, false, "ffmpeg");
|
2020-11-23 16:51:05 +01:00
|
|
|
|
gifski.OutputDataReceived += new DataReceivedEventHandler(OutputHandlerGifski);
|
|
|
|
|
|
gifski.ErrorDataReceived += new DataReceivedEventHandler(OutputHandlerGifski);
|
|
|
|
|
|
gifski.Start();
|
|
|
|
|
|
gifski.BeginOutputReadLine();
|
|
|
|
|
|
gifski.BeginErrorReadLine();
|
|
|
|
|
|
while (!gifski.HasExited)
|
|
|
|
|
|
await Task.Delay(100);
|
|
|
|
|
|
Logger.Log("Done running gifski.", true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void OutputHandlerGifski(object sendingProcess, DataReceivedEventArgs outLine)
|
|
|
|
|
|
{
|
2020-11-26 20:17:18 +01:00
|
|
|
|
if (outLine == null || outLine.Data == null)
|
|
|
|
|
|
return;
|
2020-11-23 16:51:05 +01:00
|
|
|
|
lastOutputGifski = lastOutputGifski + outLine.Data + "\n";
|
|
|
|
|
|
bool hidden = currentLogMode == LogMode.Hidden;
|
|
|
|
|
|
bool replaceLastLine = currentLogMode == LogMode.OnlyLastLine;
|
|
|
|
|
|
Logger.Log(outLine.Data, hidden, replaceLastLine);
|
|
|
|
|
|
}
|
2020-12-10 16:10:52 +01:00
|
|
|
|
|
2020-11-23 16:51:05 +01:00
|
|
|
|
static string GetAvDir ()
|
|
|
|
|
|
{
|
|
|
|
|
|
return Path.Combine(Paths.GetPkgPath(), Path.GetFileNameWithoutExtension(Packages.audioVideo.fileName));
|
|
|
|
|
|
}
|
2020-12-27 22:52:14 +01:00
|
|
|
|
|
|
|
|
|
|
static string GetCmdArg ()
|
|
|
|
|
|
{
|
|
|
|
|
|
return "/C";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static async Task SetBusyWhileRunning ()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (Program.busy) return;
|
|
|
|
|
|
|
|
|
|
|
|
await Task.Delay(100);
|
|
|
|
|
|
while(!lastProcess.HasExited)
|
|
|
|
|
|
await Task.Delay(10);
|
|
|
|
|
|
}
|
2020-11-23 16:51:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|