FF-1127 - added bitrate per channel and updated bitrate on added audio tracks

This commit is contained in:
John Andrews
2023-10-03 15:03:41 +13:00
parent 108624ccf2
commit a813bfbe74
5 changed files with 68 additions and 21 deletions

View File

@@ -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;
}
}

View File

@@ -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
/// </summary>
[Select(nameof(BitrateOptions), 3)]
public int Bitrate { get; set; }
/// <summary>
/// Gets or sets if the bitrate specified should be per channel
/// </summary>
[Boolean(4)]
public bool BitratePerChannel { get; set; }
private static List<ListOption> _BitrateOptions;
/// <summary>
@@ -115,7 +123,7 @@ public class FfmpegBuilderAudioAddTrack : FfmpegBuilderNode
/// Gets or sets the sample rate
/// </summary>
[DefaultValue(0)]
[Select(nameof(SampleRateOptions), 4)]
[Select(nameof(SampleRateOptions), 5)]
public int SampleRate { get; set; }
private static List<ListOption> _SampleRateOptions;
@@ -148,17 +156,17 @@ public class FfmpegBuilderAudioAddTrack : FfmpegBuilderNode
/// Gets or sets the language of the new track
/// </summary>
[DefaultValue("eng")]
[TextVariable(5)]
[TextVariable(6)]
public string Language { get; set; }
/// <summary>
/// Gets or sets if the title of the new track should be removed
/// </summary>
[Boolean(6)]
[Boolean(7)]
public bool RemoveTitle { get; set; }
/// <summary>
/// Gets or sets the title of the new track
/// </summary>
[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;
}
/// <summary>
/// Gets how many channels there are including sub channels, eg. 5.1 is 6 channels
/// </summary>
/// <param name="audio">the audio track</param>
/// <returns>the number of channels for the bitrate calculation</returns>
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;
}
/// <summary>
/// Gets the best audio track
/// </summary>
@@ -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();
}

View File

@@ -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;

View File

@@ -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": {

View File

@@ -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);
}