2020-12-23 16:13:04 +01:00
|
|
|
|
using Flowframes.IO;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Flowframes.AudioVideo
|
|
|
|
|
|
{
|
|
|
|
|
|
class FFmpegUtils
|
|
|
|
|
|
{
|
2021-01-14 17:46:03 +01:00
|
|
|
|
public enum Codec { H264, H265, NVENC264, NVENC265, VP9, ProRes, AviRaw }
|
2020-12-23 16:13:04 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static Codec GetCodec(Interpolate.OutMode mode)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (mode == Interpolate.OutMode.VidMp4)
|
|
|
|
|
|
{
|
2021-01-14 17:46:03 +01:00
|
|
|
|
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;
|
2020-12-23 16:13:04 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (mode == Interpolate.OutMode.VidWebm)
|
|
|
|
|
|
return Codec.VP9;
|
|
|
|
|
|
|
|
|
|
|
|
if (mode == Interpolate.OutMode.VidProRes)
|
|
|
|
|
|
return Codec.ProRes;
|
|
|
|
|
|
|
|
|
|
|
|
if (mode == Interpolate.OutMode.VidAviRaw)
|
|
|
|
|
|
return Codec.AviRaw;
|
|
|
|
|
|
|
|
|
|
|
|
return Codec.H264;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static string GetEnc(Codec codec)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (codec)
|
|
|
|
|
|
{
|
|
|
|
|
|
case Codec.H264: return "libx264";
|
|
|
|
|
|
case Codec.H265: return "libx265";
|
2021-01-14 17:46:03 +01:00
|
|
|
|
case Codec.NVENC264: return "h264_nvenc";
|
|
|
|
|
|
case Codec.NVENC265: return "hevc_nvenc";
|
2020-12-23 16:13:04 +01:00
|
|
|
|
case Codec.VP9: return "libvpx-vp9";
|
|
|
|
|
|
case Codec.ProRes: return "prores_ks";
|
2021-01-06 17:41:18 +01:00
|
|
|
|
case Codec.AviRaw: return Config.Get("aviCodec");
|
2020-12-23 16:13:04 +01:00
|
|
|
|
}
|
|
|
|
|
|
return "libx264";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static string GetEncArgs (Codec codec)
|
|
|
|
|
|
{
|
|
|
|
|
|
string args = $"-c:v { GetEnc(codec)} ";
|
|
|
|
|
|
|
2020-12-23 18:39:27 +01:00
|
|
|
|
if(codec == Codec.H264)
|
|
|
|
|
|
{
|
2021-01-06 17:41:18 +01:00
|
|
|
|
args += $"-crf {Config.GetInt("h264Crf")} -preset {Config.Get("ffEncPreset")} -pix_fmt yuv420p";
|
2020-12-23 18:39:27 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (codec == Codec.H265)
|
|
|
|
|
|
{
|
2021-01-06 17:41:18 +01:00
|
|
|
|
args += $"-crf {Config.GetInt("h265Crf")} -preset {Config.Get("ffEncPreset")} -pix_fmt yuv420p";
|
2020-12-23 18:39:27 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-01-14 17:46:03 +01:00
|
|
|
|
if (codec == Codec.NVENC264)
|
|
|
|
|
|
{
|
|
|
|
|
|
args += $"-crf {Config.GetInt("h264Crf")} -preset default -pix_fmt yuv420p";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (codec == Codec.NVENC265)
|
|
|
|
|
|
{
|
|
|
|
|
|
args += $"-crf {Config.GetInt("h265Crf")} -preset default -pix_fmt yuv420p";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-12-23 18:39:27 +01:00
|
|
|
|
if (codec == Codec.VP9)
|
|
|
|
|
|
{
|
|
|
|
|
|
int crf = Config.GetInt("vp9Crf");
|
|
|
|
|
|
string qualityStr = (crf > 0) ? $"-crf {crf}" : "-lossless 1";
|
2020-12-24 13:50:21 +01:00
|
|
|
|
string cpuUsed = Config.GetInt("vp9Speed", 3).ToString();
|
2021-01-06 17:41:18 +01:00
|
|
|
|
args += $"{qualityStr} -cpu-used {cpuUsed} -tile-columns 2 -tile-rows 2 -row-mt 1 -pix_fmt yuv420p";
|
2020-12-23 18:39:27 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(codec == Codec.ProRes)
|
2020-12-23 16:13:04 +01:00
|
|
|
|
{
|
2021-01-06 17:41:18 +01:00
|
|
|
|
args += $"-profile:v {Config.GetInt("proResProfile")} -pix_fmt yuv420p";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (codec == Codec.AviRaw)
|
|
|
|
|
|
{
|
|
|
|
|
|
args += $"-pix_fmt {Config.Get("aviColors")}";
|
2020-12-23 16:13:04 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return args;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-12-23 18:21:31 +01:00
|
|
|
|
public static string GetAudioEnc(Codec codec)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (codec)
|
|
|
|
|
|
{
|
|
|
|
|
|
case Codec.VP9: return "libopus";
|
|
|
|
|
|
}
|
|
|
|
|
|
return "aac";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-12-24 12:31:16 +01:00
|
|
|
|
public static int GetAudioKbits (string codec)
|
2020-12-23 18:21:31 +01:00
|
|
|
|
{
|
|
|
|
|
|
if (codec.Trim().ToLower() == "aac")
|
2020-12-24 12:31:16 +01:00
|
|
|
|
return Config.GetInt("aacBitrate", 160);
|
2020-12-23 18:21:31 +01:00
|
|
|
|
if (codec.Trim().ToLower().Contains("opus"))
|
2020-12-24 12:31:16 +01:00
|
|
|
|
return Config.GetInt("opusBitrate", 128);
|
2020-12-23 18:21:31 +01:00
|
|
|
|
|
2020-12-24 12:31:16 +01:00
|
|
|
|
return 192;
|
2020-12-23 18:21:31 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-12-23 16:13:04 +01:00
|
|
|
|
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.VidWebm: ext += "webm"; break;
|
|
|
|
|
|
case Interpolate.OutMode.VidProRes: ext += "mov"; break;
|
|
|
|
|
|
case Interpolate.OutMode.VidAviRaw: ext += "avi"; break;
|
|
|
|
|
|
case Interpolate.OutMode.VidGif: ext += "gif"; break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return ext;
|
|
|
|
|
|
}
|
2020-12-25 00:39:14 +01:00
|
|
|
|
|
|
|
|
|
|
static string GetAudioExt(string videoFile)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (FFmpegCommands.GetAudioCodec(videoFile))
|
|
|
|
|
|
{
|
|
|
|
|
|
case "vorbis": return "ogg";
|
|
|
|
|
|
case "opus": return "ogg";
|
|
|
|
|
|
case "mp2": return "mp2";
|
|
|
|
|
|
case "aac": return "m4a";
|
|
|
|
|
|
default: return "wav";
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-12-23 16:13:04 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|