فهرست منبع

Use better audio VBR settings

LAME's VBR mode only has advantage over a certain bitrate range. For very low and very high bitrate, use the ABR mode instead.

aac_at's CVBR mode produces very good quality and is not worse than its TVBR mode in blind testing. Use this mode for convenience.

The ffmpeg native aac encoder will have quality regression with its VBR mode. Always use CBR mode for ffmpeg's native aac encoder.

Signed-off-by: gnattu <gnattuoc@me.com>
gnattu 1 سال پیش
والد
کامیت
78929418cc
2فایلهای تغییر یافته به همراه25 افزوده شده و 12 حذف شده
  1. 2 2
      Jellyfin.Api/Controllers/DynamicHlsController.cs
  2. 23 10
      MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs

+ 2 - 2
Jellyfin.Api/Controllers/DynamicHlsController.cs

@@ -1671,7 +1671,7 @@ public class DynamicHlsController : BaseJellyfinApiController
 
 
             if (audioBitrate.HasValue && !EncodingHelper.LosslessAudioCodecs.Contains(state.ActualOutputAudioCodec, StringComparison.OrdinalIgnoreCase))
             if (audioBitrate.HasValue && !EncodingHelper.LosslessAudioCodecs.Contains(state.ActualOutputAudioCodec, StringComparison.OrdinalIgnoreCase))
             {
             {
-                var vbrParam = _encodingHelper.GetAudioVbrModeParam(audioCodec, audioBitrate.Value / (audioChannels ?? 2));
+                var vbrParam = _encodingHelper.GetAudioVbrModeParam(audioCodec, audioBitrate.Value, audioChannels ?? 2);
                 if (_encodingOptions.EnableAudioVbr && vbrParam is not null)
                 if (_encodingOptions.EnableAudioVbr && vbrParam is not null)
                 {
                 {
                     audioTranscodeParams += vbrParam;
                     audioTranscodeParams += vbrParam;
@@ -1724,7 +1724,7 @@ public class DynamicHlsController : BaseJellyfinApiController
         var bitrate = state.OutputAudioBitrate;
         var bitrate = state.OutputAudioBitrate;
         if (bitrate.HasValue && !EncodingHelper.LosslessAudioCodecs.Contains(actualOutputAudioCodec, StringComparison.OrdinalIgnoreCase))
         if (bitrate.HasValue && !EncodingHelper.LosslessAudioCodecs.Contains(actualOutputAudioCodec, StringComparison.OrdinalIgnoreCase))
         {
         {
-            var vbrParam = _encodingHelper.GetAudioVbrModeParam(audioCodec, bitrate.Value / (channels ?? 2));
+            var vbrParam = _encodingHelper.GetAudioVbrModeParam(audioCodec, bitrate.Value, channels ?? 2);
             if (_encodingOptions.EnableAudioVbr && vbrParam is not null)
             if (_encodingOptions.EnableAudioVbr && vbrParam is not null)
             {
             {
                 args += vbrParam;
                 args += vbrParam;

+ 23 - 10
MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs

@@ -2586,8 +2586,9 @@ namespace MediaBrowser.Controller.MediaEncoding
             return 128000 * (outputAudioChannels ?? audioStream.Channels ?? 2);
             return 128000 * (outputAudioChannels ?? audioStream.Channels ?? 2);
         }
         }
 
 
-        public string GetAudioVbrModeParam(string encoder, int bitratePerChannel)
+        public string GetAudioVbrModeParam(string encoder, int bitrate, int channels)
         {
         {
+            var bitratePerChannel = bitrate / channels;
             if (string.Equals(encoder, "libfdk_aac", StringComparison.OrdinalIgnoreCase))
             if (string.Equals(encoder, "libfdk_aac", StringComparison.OrdinalIgnoreCase))
             {
             {
                 return " -vbr:a " + bitratePerChannel switch
                 return " -vbr:a " + bitratePerChannel switch
@@ -2602,14 +2603,26 @@ namespace MediaBrowser.Controller.MediaEncoding
 
 
             if (string.Equals(encoder, "libmp3lame", StringComparison.OrdinalIgnoreCase))
             if (string.Equals(encoder, "libmp3lame", StringComparison.OrdinalIgnoreCase))
             {
             {
-                return " -qscale:a " + bitratePerChannel switch
+                // lame's VBR is only good for a certain bitrate range
+                // For very low and very high bitrate, use abr mode
+                if (bitratePerChannel is < 122500 and > 48000)
                 {
                 {
-                    < 48000 => "8",
-                    < 64000 => "6",
-                    < 88000 => "4",
-                    < 112000 => "2",
-                    _ => "0"
-                };
+                    return " -qscale:a " + bitratePerChannel switch
+                    {
+                        < 64000 => "6",
+                        < 88000 => "4",
+                        < 112000 => "2",
+                        _ => "0"
+                    };
+                }
+
+                return " -abr:a 1" + " -b:a " + bitrate;
+            }
+
+            if (string.Equals(encoder, "aac_at", StringComparison.OrdinalIgnoreCase))
+            {
+                // aac_at's CVBR mode
+                return " -aac_at_mode:a 2" + " -b:a " + bitrate;
             }
             }
 
 
             if (string.Equals(encoder, "libvorbis", StringComparison.OrdinalIgnoreCase))
             if (string.Equals(encoder, "libvorbis", StringComparison.OrdinalIgnoreCase))
@@ -6962,7 +6975,7 @@ namespace MediaBrowser.Controller.MediaEncoding
             var bitrate = state.OutputAudioBitrate;
             var bitrate = state.OutputAudioBitrate;
             if (bitrate.HasValue && !LosslessAudioCodecs.Contains(codec, StringComparison.OrdinalIgnoreCase))
             if (bitrate.HasValue && !LosslessAudioCodecs.Contains(codec, StringComparison.OrdinalIgnoreCase))
             {
             {
-                var vbrParam = GetAudioVbrModeParam(codec, bitrate.Value / (channels ?? 2));
+                var vbrParam = GetAudioVbrModeParam(codec, bitrate.Value, channels ?? 2);
                 if (encodingOptions.EnableAudioVbr && vbrParam is not null)
                 if (encodingOptions.EnableAudioVbr && vbrParam is not null)
                 {
                 {
                     args += vbrParam;
                     args += vbrParam;
@@ -6993,7 +7006,7 @@ namespace MediaBrowser.Controller.MediaEncoding
 
 
             if (bitrate.HasValue && !LosslessAudioCodecs.Contains(outputCodec, StringComparison.OrdinalIgnoreCase))
             if (bitrate.HasValue && !LosslessAudioCodecs.Contains(outputCodec, StringComparison.OrdinalIgnoreCase))
             {
             {
-                var vbrParam = GetAudioVbrModeParam(GetAudioEncoder(state), bitrate.Value / (channels ?? 2));
+                var vbrParam = GetAudioVbrModeParam(GetAudioEncoder(state), bitrate.Value, channels ?? 2);
                 if (encodingOptions.EnableAudioVbr && vbrParam is not null)
                 if (encodingOptions.EnableAudioVbr && vbrParam is not null)
                 {
                 {
                     audioTranscodeParams.Add(vbrParam);
                     audioTranscodeParams.Add(vbrParam);