aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Jellyfin.Api/Controllers/DynamicHlsController.cs29
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs64
-rw-r--r--MediaBrowser.Model/Configuration/EncodingOptions.cs6
3 files changed, 91 insertions, 8 deletions
diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs
index 4d8b4de24..7b1830761 100644
--- a/Jellyfin.Api/Controllers/DynamicHlsController.cs
+++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs
@@ -1685,14 +1685,25 @@ public class DynamicHlsController : BaseJellyfinApiController
audioTranscodeParams += "-acodec " + audioCodec;
- if (state.OutputAudioBitrate.HasValue)
+ var audioBitrate = state.OutputAudioBitrate;
+ var audioChannels = state.OutputAudioChannels;
+
+ if (audioBitrate.HasValue)
{
- audioTranscodeParams += " -ab " + state.OutputAudioBitrate.Value.ToString(CultureInfo.InvariantCulture);
+ string vbrParam;
+ if (_encodingOptions.EnableAudioVbr && (vbrParam = _encodingHelper.GetAudioVbrModeParam(state.OutputAudioCodec, audioBitrate.Value / audioChannels ?? 2)) != null)
+ {
+ audioTranscodeParams += vbrParam;
+ }
+ else
+ {
+ audioTranscodeParams += " -ab " + audioBitrate.Value.ToString(CultureInfo.InvariantCulture);
+ }
}
- if (state.OutputAudioChannels.HasValue)
+ if (audioChannels.HasValue)
{
- audioTranscodeParams += " -ac " + state.OutputAudioChannels.Value.ToString(CultureInfo.InvariantCulture);
+ audioTranscodeParams += " -ac " + audioChannels.Value.ToString(CultureInfo.InvariantCulture);
}
if (state.OutputAudioSampleRate.HasValue)
@@ -1747,7 +1758,15 @@ public class DynamicHlsController : BaseJellyfinApiController
if (bitrate.HasValue)
{
- args += " -ab " + bitrate.Value.ToString(CultureInfo.InvariantCulture);
+ string vbrParam;
+ if (_encodingOptions.EnableAudioVbr && (vbrParam = _encodingHelper.GetAudioVbrModeParam(state.OutputAudioCodec, bitrate.Value / channels ?? 2)) != null)
+ {
+ args += vbrParam;
+ }
+ else
+ {
+ args += " -ab " + bitrate.Value.ToString(CultureInfo.InvariantCulture);
+ }
}
if (state.OutputAudioSampleRate.HasValue)
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
index 648358b59..551160934 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
@@ -2160,6 +2160,47 @@ namespace MediaBrowser.Controller.MediaEncoding
return 128000;
}
+ public string GetAudioVbrModeParam(string encoder, int bitratePerChannel)
+ {
+ if (encoder == "libfdk_aac")
+ {
+ return " -vbr:a " + bitratePerChannel switch
+ {
+ < 32000 => "1",
+ < 48000 => "2",
+ < 64000 => "3",
+ < 96000 => "4",
+ _ => "5"
+ };
+ }
+
+ if (encoder == "libmp3lame")
+ {
+ return " -qscale:a " + bitratePerChannel switch
+ {
+ < 48000 => "8",
+ < 64000 => "6",
+ < 88000 => "4",
+ < 112000 => "2",
+ _ => "0"
+ };
+ }
+
+ if (encoder == "libvorbis")
+ {
+ return " -qscale:a " + bitratePerChannel switch
+ {
+ < 40000 => "0",
+ < 56000 => "2",
+ < 80000 => "4",
+ < 112000 => "6",
+ _ => "8"
+ };
+ }
+
+ return null;
+ }
+
public string GetAudioFilterParam(EncodingJobInfo state, EncodingOptions encodingOptions)
{
var channels = state.OutputAudioChannels;
@@ -5801,7 +5842,15 @@ namespace MediaBrowser.Controller.MediaEncoding
if (bitrate.HasValue)
{
- args += " -ab " + bitrate.Value.ToString(CultureInfo.InvariantCulture);
+ string vbrParam;
+ if (encodingOptions.EnableAudioVbr && (vbrParam = GetAudioVbrModeParam(codec, bitrate.Value / channels ?? 2)) != null)
+ {
+ args += vbrParam;
+ }
+ else
+ {
+ args += " -ab " + bitrate.Value.ToString(CultureInfo.InvariantCulture);
+ }
}
if (state.OutputAudioSampleRate.HasValue)
@@ -5819,13 +5868,22 @@ namespace MediaBrowser.Controller.MediaEncoding
var audioTranscodeParams = new List<string>();
var bitrate = state.OutputAudioBitrate;
+ var channels = state.OutputAudioChannels;
if (bitrate.HasValue)
{
- audioTranscodeParams.Add("-ab " + bitrate.Value.ToString(CultureInfo.InvariantCulture));
+ string vbrParam;
+ if (encodingOptions.EnableAudioVbr && (vbrParam = GetAudioVbrModeParam(state.OutputAudioCodec, bitrate.Value / channels ?? 2)) != null)
+ {
+ audioTranscodeParams.Add(vbrParam);
+ }
+ else
+ {
+ audioTranscodeParams.Add("-ab " + bitrate.Value.ToString(CultureInfo.InvariantCulture));
+ }
}
- if (state.OutputAudioChannels.HasValue)
+ if (channels.HasValue)
{
audioTranscodeParams.Add("-ac " + state.OutputAudioChannels.Value.ToString(CultureInfo.InvariantCulture));
}
diff --git a/MediaBrowser.Model/Configuration/EncodingOptions.cs b/MediaBrowser.Model/Configuration/EncodingOptions.cs
index 0ff95a2e1..b43e0f024 100644
--- a/MediaBrowser.Model/Configuration/EncodingOptions.cs
+++ b/MediaBrowser.Model/Configuration/EncodingOptions.cs
@@ -14,6 +14,7 @@ public class EncodingOptions
public EncodingOptions()
{
EnableFallbackFont = false;
+ EnableAudioVbr = false;
DownMixAudioBoost = 2;
DownMixStereoAlgorithm = DownMixStereoAlgorithms.None;
MaxMuxingQueueSize = 2048;
@@ -71,6 +72,11 @@ public class EncodingOptions
public bool EnableFallbackFont { get; set; }
/// <summary>
+ /// Gets or sets a value indicating whether audio VBR is enabled.
+ /// </summary>
+ public bool EnableAudioVbr { get; set; }
+
+ /// <summary>
/// Gets or sets the audio boost applied when downmixing audio.
/// </summary>
public double DownMixAudioBoost { get; set; }