diff --git a/AudioNodes/Nodes/ConvertNode.cs b/AudioNodes/Nodes/ConvertNode.cs
index 68b07a75..ec92497d 100644
--- a/AudioNodes/Nodes/ConvertNode.cs
+++ b/AudioNodes/Nodes/ConvertNode.cs
@@ -119,10 +119,10 @@ namespace FileFlows.AudioNodes
return 2;
}
- args.Logger?.ILog($"Comparing bitrate {AudioInfo.Bitrate} is less than or equal to {(Bitrate * 1024)}");
- if(AudioInfo.Bitrate <= Bitrate * 1024) // this bitrate is in Kbps, whereas AudioInfo.Bitrate is bytes per second
+ 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 '{Codec}' at bitrate '{AudioInfo.Bitrate} bps ({(AudioInfo.Bitrate / 1024)} KiBps)'");
+ args.Logger?.ILog($"Audio file already '{Codec}' at bitrate '{AudioInfo.Bitrate} bps ({(AudioInfo.Bitrate / 1000)} KBps)'");
return 2;
}
}
diff --git a/VideoNodes/FfmpegBuilderNodes/Audio/FfmpegBuilderAudioAddTrack.cs b/VideoNodes/FfmpegBuilderNodes/Audio/FfmpegBuilderAudioAddTrack.cs
index ba6f37fc..d13e23a7 100644
--- a/VideoNodes/FfmpegBuilderNodes/Audio/FfmpegBuilderAudioAddTrack.cs
+++ b/VideoNodes/FfmpegBuilderNodes/Audio/FfmpegBuilderAudioAddTrack.cs
@@ -1,4 +1,6 @@
-using FileFlows.VideoNodes.FfmpegBuilderNodes.Models;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using FileFlows.VideoNodes.FfmpegBuilderNodes.Models;
namespace FileFlows.VideoNodes.FfmpegBuilderNodes;
@@ -85,6 +87,12 @@ public class FfmpegBuilderAudioAddTrack : FfmpegBuilderNode
///
[Select(nameof(BitrateOptions), 3)]
public int Bitrate { get; set; }
+
+ ///
+ /// Gets or sets if the bitrate specified should be per channel
+ ///
+ [Boolean(4)]
+ public bool BitratePerChannel { get; set; }
private static List _BitrateOptions;
///
@@ -115,7 +123,7 @@ public class FfmpegBuilderAudioAddTrack : FfmpegBuilderNode
/// Gets or sets the sample rate
///
[DefaultValue(0)]
- [Select(nameof(SampleRateOptions), 4)]
+ [Select(nameof(SampleRateOptions), 5)]
public int SampleRate { get; set; }
private static List _SampleRateOptions;
@@ -148,17 +156,17 @@ public class FfmpegBuilderAudioAddTrack : FfmpegBuilderNode
/// Gets or sets the language of the new track
///
[DefaultValue("eng")]
- [TextVariable(5)]
+ [TextVariable(6)]
public string Language { get; set; }
///
/// Gets or sets if the title of the new track should be removed
///
- [Boolean(6)]
+ [Boolean(7)]
public bool RemoveTitle { get; set; }
///
/// Gets or sets the title of the new track
///
- [TextVariable(7)]
+ [TextVariable(8)]
[ConditionEquals(nameof(RemoveTitle), false)]
public string NewTitle { get; set; }
@@ -189,7 +197,7 @@ public class FfmpegBuilderAudioAddTrack : FfmpegBuilderNode
bool directCopy = false;
if(bestAudio.Codec.ToLower() == this.Codec.ToLower())
{
- if(this.Channels == 0 || this.Channels == bestAudio.Channels)
+ if((Channels == 0 || Channels == bestAudio.Channels) && Bitrate <= 2)
{
directCopy = true;
}
@@ -202,7 +210,19 @@ public class FfmpegBuilderAudioAddTrack : FfmpegBuilderNode
else
{
int sampleRate = SampleRate == 1 ? audio.Stream.SampleRate : SampleRate;
- audio.EncodingParameters.AddRange(GetNewAudioTrackParameters(args, audio, Codec, Channels, Bitrate, sampleRate));
+
+ int bitrate = Bitrate;
+ if (BitratePerChannel)
+ {
+ int totalChannels = GetAudioBitrateChannels(audio);
+ args.Logger?.ILog("Total channels: " + totalChannels);
+ args.Logger?.ILog("Bitrate Per Channel: " + bitrate);
+
+ bitrate = totalChannels * bitrate;
+ args.Logger?.ILog("Total Bitrate: " + bitrate);
+ }
+
+ audio.EncodingParameters.AddRange(GetNewAudioTrackParameters(args, audio, Codec, Channels, bitrate, sampleRate));
if (this.Channels > 0)
audio.Channels = this.Channels;
}
@@ -220,6 +240,27 @@ public class FfmpegBuilderAudioAddTrack : FfmpegBuilderNode
return 1;
}
+ ///
+ /// Gets how many channels there are including sub channels, eg. 5.1 is 6 channels
+ ///
+ /// the audio track
+ /// the number of channels for the bitrate calculation
+ private int GetAudioBitrateChannels(FfmpegAudioStream audio)
+ {
+ float channels = (Channels > 0 ? Channels : audio.Channels);
+
+ // Check if there are any decimal parts in the channels
+ float decimalPart = channels - (int)channels;
+
+ // Calculate the additional channels based on the decimal part
+ int additionalChannels = (int)(decimalPart * 10);
+
+ // Total channels including sub-channels
+ int totalChannels = (int)channels + additionalChannels;
+
+ return totalChannels;
+ }
+
///
/// Gets the best audio track
///
@@ -353,12 +394,16 @@ public class FfmpegBuilderAudioAddTrack : FfmpegBuilderNode
{
options.Add("-b:a:{index}");
options.Add((stream.Stream.Bitrate / 1000) + "k");
+ options.Add("-metadata:s:a:{index}");
+ options.Add($"BPS={stream.Stream.Bitrate}");
}
}
else if (bitrate > 0)
{
options.Add("-b:a:{index}");
options.Add(bitrate + "k");
+ options.Add("-metadata:s:a:{index}");
+ options.Add($"BPS={bitrate * 1000}");
}
// Handle sample rate
@@ -368,7 +413,7 @@ public class FfmpegBuilderAudioAddTrack : FfmpegBuilderNode
options.Add(sampleRate.ToString());
}
- args.Logger.ILog("New Audo Arguments: " + string.Join(" ", options));
+ args.Logger.ILog("New Audio Arguments: " + string.Join(" ", options));
return options.ToArray();
}
diff --git a/VideoNodes/FfmpegBuilderNodes/Video/FfmpegBuilderVideoBitrate.cs b/VideoNodes/FfmpegBuilderNodes/Video/FfmpegBuilderVideoBitrate.cs
index f6999b58..3ee39155 100644
--- a/VideoNodes/FfmpegBuilderNodes/Video/FfmpegBuilderVideoBitrate.cs
+++ b/VideoNodes/FfmpegBuilderNodes/Video/FfmpegBuilderVideoBitrate.cs
@@ -28,14 +28,14 @@ public class FfmpegBuilderVideoBitrate : FfmpegBuilderNode
args.Logger?.ELog("Minimum birate not set");
return -1;
}
- float currentBitrate = (int)(video.Stream.Bitrate / 1024f);
+ float currentBitrate = (int)(video.Stream.Bitrate / 1000f);
if (currentBitrate <= 0 && Model.VideoInfo.Bitrate > 0)
- currentBitrate = (int)(Model.VideoInfo.Bitrate/ 1024f);
+ currentBitrate = (int)(Model.VideoInfo.Bitrate/ 1000f);
if (currentBitrate <= 0)
{
// need to work it out
currentBitrate = args.WorkingFileSize;
- //currentBitrate /= 1024f;
+ //currentBitrate /= 1000f;
currentBitrate = (float)(currentBitrate / video.Stream.Duration.TotalSeconds);
// rough estimate of 75% of the file is video
currentBitrate *= 0.75f;
diff --git a/VideoNodes/VideoNodes.en.json b/VideoNodes/VideoNodes.en.json
index 994b1210..130db0d8 100644
--- a/VideoNodes/VideoNodes.en.json
+++ b/VideoNodes/VideoNodes.en.json
@@ -130,7 +130,9 @@
"NewTitle": "New Title",
"NewTitle-Help": "Optional title for the newly created audio track. If left blank the source title will be used",
"RemoveTitle": "Remove Title",
- "RemoveTitle-Help": "If the source title should be removed and the track should have no title"
+ "RemoveTitle-Help": "If the source title should be removed and the track should have no title",
+ "BitratePerChannel": "Bitrate Per Channel",
+ "BitratePerChannel-Help": "If the bitrate specified should be per channel"
}
},
"FfmpegBuilderAudioAdjustVolume": {
diff --git a/VideoNodes/VideoNodes/VideoNode.cs b/VideoNodes/VideoNodes/VideoNode.cs
index 83d04479..0f1f5b5f 100644
--- a/VideoNodes/VideoNodes/VideoNode.cs
+++ b/VideoNodes/VideoNodes/VideoNode.cs
@@ -142,14 +142,14 @@ namespace FileFlows.VideoNodes
if (stream.Bitrate > 0)
metadata.Add(prefix + "Bitrate", stream.Bitrate);
}
- foreach (var (strream, i) in videoInfo.SubtitleStreams.Select((value, i) => (value, i)))
+ foreach (var (stream, i) in videoInfo.SubtitleStreams.Select((value, i) => (value, i)))
{
string prefix = "Subtitle" + (i == 0 ? "" : " " + (i + 1)) + " ";
- metadata.Add(prefix + "Codec", strream.Codec);
- if (string.IsNullOrEmpty(strream.Title) == false)
- metadata.Add(prefix + "Title", strream.Title);
- if (string.IsNullOrEmpty(strream.Language) == false)
- metadata.Add(prefix + "Language", strream.Language);
+ metadata.Add(prefix + "Codec", stream.Codec);
+ if (string.IsNullOrEmpty(stream.Title) == false)
+ metadata.Add(prefix + "Title", stream.Title);
+ if (string.IsNullOrEmpty(stream.Language) == false)
+ metadata.Add(prefix + "Language", stream.Language);
}
args.SetMetadata(metadata);
}