FF-1439 - added more options to convert audio

This commit is contained in:
John Andrews
2024-04-16 14:22:23 +12:00
parent c89b8b972a
commit 186c27dc35
7 changed files with 155 additions and 47 deletions

View File

@@ -2,7 +2,7 @@ namespace FileFlows.AudioNodes;
public class ConvertAudio : ConvertNode
{
protected override string Extension => Codec;
protected override string DefaultExtension => Codec;
public override string HelpUrl => "https://fileflows.com/docs/plugins/audio-nodes/convert-audio";
public static List<ListOption> BitrateOptions => ConvertNode.BitrateOptions;

View File

@@ -1,4 +1,5 @@
using FileFlows.AudioNodes.Helpers;
using System.ComponentModel;
using FileFlows.AudioNodes.Helpers;
namespace FileFlows.AudioNodes
{
@@ -6,7 +7,10 @@ namespace FileFlows.AudioNodes
public abstract class ConvertNode:AudioNode
{
protected abstract string Extension { get; }
/// <summary>
/// Gets the default extension to use if none set
/// </summary>
protected abstract string DefaultExtension { get; }
/// <summary>
/// Gets or sets if using high efficiency
/// </summary>
@@ -18,14 +22,12 @@ namespace FileFlows.AudioNodes
return info.Bitrate;
}
protected virtual bool SetId3Tags => false;
public override int Inputs => 1;
public override int Outputs => 2;
protected virtual List<string> GetArguments(NodeParameters args, out string? extension)
{
string Codec = Extension;
string Codec = DefaultExtension;
extension = null;
string codecKey = Codec + "_codec";
string codec = args.GetToolPathActual(codecKey)?.EmptyAsNull() ?? Codec;
@@ -55,6 +57,12 @@ namespace FileFlows.AudioNodes
}
int bitrate = Bitrate;
List<string> ffArgs = new()
{
"-c:a",
codec,
};
if (Codec.ToLowerInvariant() == "mp3" || ogg || Codec.ToLowerInvariant() == "aac")
{
if (bitrate is >= 10 and <= 20)
@@ -69,60 +77,56 @@ namespace FileFlows.AudioNodes
args.Logger?.ILog($"Using variable bitrate setting '{bitrate}' for codec '{Codec}'");
List<string> results;
if (codec == "libfdk_aac")
{
results = new()
ffArgs.AddRange(new[]
{
"-c:a",
codec,
"-vbr",
Math.Min(Math.Max(1, bitrate / 2), 5).ToString()
};
});
}
else
{
results = new()
ffArgs.AddRange(new[]
{
"-c:a",
codec,
"-qscale:a",
bitrate.ToString()
};
});
}
if (Codec == "aac" && HighEfficiency)
{
extension = "m4a";
results.AddRange(new[] { "-profile:a", "aac_he_v2" });
ffArgs.AddRange(new[] { "-profile:a", "aac_he_v2" });
}
return results;
}
}
else if(bitrate is > 10 and <= 20)
{
throw new Exception("Variable bitrate not supported in codec: " + Codec);
}
if (bitrate == 0)
else if (bitrate != 0)
{
// automatic
return new List<string>
ffArgs.AddRange(new []
{
"-c:a",
codec
};
"-ab",
(bitrate == -1 ? GetSourceBitrate(args).ToString() : bitrate + "k")
});
}
return new List<string>
if (SampleRate > 0)
{
"-c:a",
codec,
"-ab",
(bitrate == -1 ? GetSourceBitrate(args).ToString() : bitrate + "k")
};
ffArgs.Add("-ar");
ffArgs.Add(SampleRate.ToString());
}
if (Channels > 0)
{
ffArgs.Add("-ac");
ffArgs.Add(Channels.ToString());
}
return ffArgs;
}
/// <summary>
@@ -136,16 +140,85 @@ namespace FileFlows.AudioNodes
[Select(nameof(BitrateOptions), 1)]
public int Bitrate { get; set; }
/// <summary>
/// Gets or sets the sample rate
/// </summary>
[DefaultValue(0)]
[Select(nameof(SampleRateOptions), 2)]
public int SampleRate { get; set; }
private static List<ListOption> _SampleRateOptions;
/// <summary>
/// Gets the sample rate options
/// </summary>
public static List<ListOption> SampleRateOptions
{
get
{
if (_SampleRateOptions == null)
{
_SampleRateOptions = new List<ListOption>
{
new () { Label = "Automatic", Value = 0},
new () { Label = "Same as source", Value = 1},
new () { Label = "44100", Value = 44100 },
new () { Label = "48000", Value = 48000 },
new () { Label = "88200", Value = 88200 },
new () { Label = "96000", Value = 96000 },
new () { Label = "176400", Value = 176400 },
new () { Label = "192000", Value = 192000 }
};
}
return _SampleRateOptions;
}
}
/// <summary>
/// Gets or sets the number of channels rate
/// </summary>
[DefaultValue(0)]
[Select(nameof(ChannelsOptions), 3)]
public int Channels { get; set; }
private static List<ListOption> _ChannelsOptions;
/// <summary>
/// Gets the channel options
/// </summary>
public static List<ListOption> ChannelsOptions
{
get
{
if (_ChannelsOptions == null)
{
_ChannelsOptions = new List<ListOption>
{
new () { Label = "Same as source", Value = 0},
new () { Label = "Mono", Value = 1f},
new () { Label = "Stereo", Value = 2f},
new () { Label = "5.1", Value = 6},
new () { Label = "7.1", Value = 8}
};
}
return _ChannelsOptions;
}
}
/// <summary>
/// Gets or sets a custom extension to override the ont to use
/// </summary>
[TextVariable(4)]
public string CustomExtension { get; set; }
/// <summary>
/// Gets or sets if the audio should be normalized
/// </summary>
[Boolean(3)]
[Boolean(5)]
public bool Normalize { get; set; }
/// <summary>
/// Gets or sets if it should be skipped if the codec is the same
/// </summary>
[Boolean(4)]
[Boolean(6)]
[ConditionEquals(nameof(Normalize), true, inverse: true)]
public bool SkipIfCodecMatches { get; set; }
@@ -224,26 +297,27 @@ namespace FileFlows.AudioNodes
}
string ffprobe = ffprobeResult.Value;
if(Normalize == false && AudioInfo.Codec?.ToLower() == Extension?.ToLower())
if(Normalize == false && AudioInfo.Codec?.ToLower() == DefaultExtension?.ToLower())
{
if (SkipIfCodecMatches)
{
args.Logger?.ILog($"Audio file already '{Extension}' at bitrate '{AudioInfo.Bitrate} bps', and set to skip if codec matches");
args.Logger?.ILog($"Audio file already '{DefaultExtension}' at bitrate '{AudioInfo.Bitrate} bps', and set to skip if codec matches");
return 2;
}
args.Logger?.ILog($"Comparing bitrate {AudioInfo.Bitrate} is less than or equal to {(Bitrate * 1000)}");
if(AudioInfo.Bitrate <= Bitrate * 1000) // this bitrate is in Kbps, whereas AudioInfo.Bitrate is bytes per second
{
args.Logger?.ILog($"Audio file already '{Extension}' at bitrate '{AudioInfo.Bitrate} bps ({(AudioInfo.Bitrate / 1000)} KBps)'");
args.Logger?.ILog($"Audio file already '{DefaultExtension}' at bitrate '{AudioInfo.Bitrate} bps ({(AudioInfo.Bitrate / 1000)} KBps)'");
return 2;
}
}
var ffArgs = GetArguments(args, out string extension);
string outputFile = FileHelper.Combine(args.TempPath,
Guid.NewGuid() + "." + (extension?.EmptyAsNull() ?? Extension));
string actualExt = args.ReplaceVariables(CustomExtension, stripMissing: true)?.EmptyAsNull() ??
extension?.EmptyAsNull() ?? DefaultExtension;
string outputFile = FileHelper.Combine(args.TempPath, Guid.NewGuid() + "." + actualExt.TrimStart('.'));
ffArgs.Insert(0, "-hide_banner");
ffArgs.Insert(1, "-y"); // tells ffmpeg to replace the file if already exists, which it shouldnt but just incase

View File

@@ -5,15 +5,13 @@ public class ConvertToAAC : ConvertNode
/// <inheritdoc />
public override string HelpUrl => "https://fileflows.com/docs/plugins/audio-nodes/convert-to-aac";
/// <inheritdoc />
protected override string Extension => "aac";
protected override string DefaultExtension => "aac";
/// <inheritdoc />
public override string Icon => "svg:aac";
/// <summary>
/// Gets or sets if high efficiency should be used
/// </summary>
[Boolean(5)]
[Boolean(6)]
public bool HighEfficiency { get => base.HighEfficiency; set =>base.HighEfficiency = value; }
protected override bool SetId3Tags => true;
}

View File

@@ -5,7 +5,7 @@ public class ConvertToMP3 : ConvertNode
/// <inheritdoc />
public override string HelpUrl => "https://fileflows.com/docs/plugins/audio-nodes/convert-to-mp3";
/// <inheritdoc />
protected override string Extension => "mp3";
protected override string DefaultExtension => "mp3";
/// <inheritdoc />
public override string Icon => "svg:mp3";

View File

@@ -6,7 +6,7 @@ namespace FileFlows.AudioNodes;
public override string HelpUrl => "https://fileflows.com/docs/plugins/audio-nodes/convert-to-ogg";
/// <inheritdoc />
protected override string Extension => "ogg";
protected override string DefaultExtension => "ogg";
public static List<ListOption> BitrateOptions => ConvertNode.BitrateOptions;

View File

@@ -5,7 +5,7 @@ public class ConvertToWAV : ConvertNode
/// <inheritdoc />
public override string HelpUrl => "https://fileflows.com/docs/plugins/audio-nodes/convert-to-wav";
/// <inheritdoc />
protected override string Extension => "wav";
protected override string DefaultExtension => "wav";
/// <inheritdoc />
public override string Icon => "svg:wav";

View File

@@ -38,6 +38,12 @@
"Bitrate-Help": "The bitrate for the new file, the higher the bitrate the better the quality but larger the file.",
"Codec": "Codec",
"Codec-Help": "The audio codec to convert the file into.",
"SampleRate": "Sample Rate",
"SampleRate-Help": "The sample rate to use",
"Channels": "Channels",
"Channels-Help": "The number of channels the converted file will have.\nIf you specify more channels than the source, FFmpeg will automatically up-mix it.\nIf you specify fewer channels than the source, FFmpeg will automatically down-mix it.",
"CustomExtension": "Extension",
"CustomExtension-Help": "Allows you to set a custom file extension to use instead of the automatic one determined by the codec.",
"Normalize": "Normalize",
"Normalize-Help": "If the audio should be normalized with two pass audio normalization",
"SkipIfCodecMatches": "Skip If Codec Matches",
@@ -57,6 +63,12 @@
"Bitrate-Help": "The bitrate for the new AAC file, the higher the bitrate the better the quality but larger the file. 192 Kbps is the recommended rate.",
"Normalize": "Normalize",
"Normalize-Help": "If the audio should be normalized with two pass audio normalization",
"SampleRate": "Sample Rate",
"SampleRate-Help": "The sample rate to use",
"Channels": "Channels",
"Channels-Help": "The number of channels the converted file will have.\nIf you specify more channels than the source, FFmpeg will automatically up-mix it.\nIf you specify fewer channels than the source, FFmpeg will automatically down-mix it.",
"CustomExtension": "Extension",
"CustomExtension-Help": "Allows you to set a custom file extension to use instead of the automatic one determined by the codec.",
"SkipIfCodecMatches": "Skip If Codec Matches",
"SkipIfCodecMatches-Help": "If the existing audio codec matches, this file will not be processed regardless of the bitrate. Otherwise if off, the bitrate must be less than or equal to for it to skip.",
"HighEfficiency": "High Efficiency",
@@ -72,6 +84,12 @@
"Fields": {
"Bitrate": "Bitrate",
"Bitrate-Help": "The bitrate for the new FLAC file, the higher the bitrate the better the quality but larger the file. 128 Kbps is the recommended rate.",
"SampleRate": "Sample Rate",
"SampleRate-Help": "The sample rate to use",
"Channels": "Channels",
"Channels-Help": "The number of channels the converted file will have.\nIf you specify more channels than the source, FFmpeg will automatically up-mix it.\nIf you specify fewer channels than the source, FFmpeg will automatically down-mix it.",
"CustomExtension": "Extension",
"CustomExtension-Help": "Allows you to set a custom file extension to use instead of the automatic one determined by the codec.",
"Normalize": "Normalize",
"Normalize-Help": "If the audio should be normalized with two pass audio normalization",
"SkipIfCodecMatches": "Skip If Codec Matches",
@@ -87,6 +105,12 @@
"Fields": {
"Bitrate": "Bitrate",
"Bitrate-Help": "The bitrate for the new MP3 file, the higher the bitrate the better the quality but larger the file. 192 Kbps is the recommended rate.",
"SampleRate": "Sample Rate",
"SampleRate-Help": "The sample rate to use",
"Channels": "Channels",
"Channels-Help": "The number of channels the converted file will have.\nIf you specify more channels than the source, FFmpeg will automatically up-mix it.\nIf you specify fewer channels than the source, FFmpeg will automatically down-mix it.",
"CustomExtension": "Extension",
"CustomExtension-Help": "Allows you to set a custom file extension to use instead of the automatic one determined by the codec.",
"Normalize": "Normalize",
"Normalize-Help": "If the audio should be normalized with two pass audio normalization",
"SkipIfCodecMatches": "Skip If Codec Matches",
@@ -102,6 +126,12 @@
"Fields": {
"Bitrate": "Bitrate",
"Bitrate-Help": "The bitrate for the new OGG file, the higher the bitrate the better the quality but larger the file. 128 Kbps is the recommended rate.",
"SampleRate": "Sample Rate",
"SampleRate-Help": "The sample rate to use",
"Channels": "Channels",
"Channels-Help": "The number of channels the converted file will have.\nIf you specify more channels than the source, FFmpeg will automatically up-mix it.\nIf you specify fewer channels than the source, FFmpeg will automatically down-mix it.",
"CustomExtension": "Extension",
"CustomExtension-Help": "Allows you to set a custom file extension to use instead of the automatic one determined by the codec.",
"Normalize": "Normalize",
"Normalize-Help": "If the audio should be normalized with two pass audio normalization",
"SkipIfCodecMatches": "Skip If Codec Matches",
@@ -117,6 +147,12 @@
"Fields": {
"Bitrate": "Bitrate",
"Bitrate-Help": "The bitrate for the new WAV file, the higher the bitrate the better the quality but larger the file. 128 Kbps is the recommended rate.",
"SampleRate": "Sample Rate",
"SampleRate-Help": "The sample rate to use",
"Channels": "Channels",
"Channels-Help": "The number of channels the converted file will have.\nIf you specify more channels than the source, FFmpeg will automatically up-mix it.\nIf you specify fewer channels than the source, FFmpeg will automatically down-mix it.",
"CustomExtension": "Extension",
"CustomExtension-Help": "Allows you to set a custom file extension to use instead of the automatic one determined by the codec.",
"Normalize": "Normalize",
"Normalize-Help": "If the audio should be normalized with two pass audio normalization",
"SkipIfCodecMatches": "Skip If Codec Matches",