Просмотр исходного кода

Use source audio bitrate if requested codec is lossless

Shadowghost 2 лет назад
Родитель
Сommit
1f15724398

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

@@ -12,6 +12,7 @@ using Jellyfin.Api.Attributes;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Api.Models.PlaybackDtos;
 using Jellyfin.Api.Models.StreamingDtos;
+using Jellyfin.Extensions;
 using Jellyfin.MediaEncoding.Hls.Playlist;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Controller.Configuration;
@@ -1688,7 +1689,7 @@ public class DynamicHlsController : BaseJellyfinApiController
             var audioBitrate = state.OutputAudioBitrate;
             var audioChannels = state.OutputAudioChannels;
 
-            if (audioBitrate.HasValue)
+            if (audioBitrate.HasValue && !EncodingHelper.LosslessAudioCodecs.Contains(state.ActualOutputAudioCodec, StringComparison.OrdinalIgnoreCase))
             {
                 var vbrParam = _encodingHelper.GetAudioVbrModeParam(state.OutputAudioCodec, audioBitrate.Value / (audioChannels ?? 2));
                 if (_encodingOptions.EnableAudioVbr && vbrParam is not null)
@@ -1717,11 +1718,11 @@ public class DynamicHlsController : BaseJellyfinApiController
 
         // dts, flac, opus and truehd are experimental in mp4 muxer
         var strictArgs = string.Empty;
-
-        if (string.Equals(state.ActualOutputAudioCodec, "flac", StringComparison.OrdinalIgnoreCase)
-            || string.Equals(state.ActualOutputAudioCodec, "opus", StringComparison.OrdinalIgnoreCase)
-            || string.Equals(state.ActualOutputAudioCodec, "dts", StringComparison.OrdinalIgnoreCase)
-            || string.Equals(state.ActualOutputAudioCodec, "truehd", StringComparison.OrdinalIgnoreCase))
+        var actualOutputAudioCodec = state.ActualOutputAudioCodec;
+        if (string.Equals(actualOutputAudioCodec, "flac", StringComparison.OrdinalIgnoreCase)
+            || string.Equals(actualOutputAudioCodec, "opus", StringComparison.OrdinalIgnoreCase)
+            || string.Equals(actualOutputAudioCodec, "dts", StringComparison.OrdinalIgnoreCase)
+            || string.Equals(actualOutputAudioCodec, "truehd", StringComparison.OrdinalIgnoreCase))
         {
             strictArgs = " -strict -2";
         }
@@ -1755,10 +1756,9 @@ public class DynamicHlsController : BaseJellyfinApiController
         }
 
         var bitrate = state.OutputAudioBitrate;
-
-        if (bitrate.HasValue)
+        if (bitrate.HasValue && !EncodingHelper.LosslessAudioCodecs.Contains(actualOutputAudioCodec, StringComparison.OrdinalIgnoreCase))
         {
-            var vbrParam = _encodingHelper.GetAudioVbrModeParam(state.OutputAudioCodec, bitrate.Value / (channels ?? 2));
+            var vbrParam = _encodingHelper.GetAudioVbrModeParam(actualOutputAudioCodec, bitrate.Value / (channels ?? 2));
             if (_encodingOptions.EnableAudioVbr && vbrParam is not null)
             {
                 args += vbrParam;

+ 11 - 2
Jellyfin.Api/Helpers/DynamicHlsHelper.cs

@@ -9,6 +9,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using Jellyfin.Api.Extensions;
 using Jellyfin.Api.Models.StreamingDtos;
+using Jellyfin.Extensions;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Net;
@@ -223,9 +224,17 @@ public class DynamicHlsHelper
                     sdrVideoUrl += "&AllowVideoStreamCopy=false";
 
                     var sdrOutputVideoBitrate = _encodingHelper.GetVideoBitrateParamValue(state.VideoRequest, state.VideoStream, state.OutputVideoCodec);
-                    var sdrOutputAudioBitrate = _encodingHelper.GetAudioBitrateParam(state.VideoRequest, state.AudioStream, state.OutputAudioChannels) ?? 0;
-                    var sdrTotalBitrate = sdrOutputAudioBitrate + sdrOutputVideoBitrate;
+                    var sdrOutputAudioBitrate = 0;
+                    if (EncodingHelper.LosslessAudioCodecs.Contains(state.VideoRequest.AudioCodec, StringComparison.OrdinalIgnoreCase))
+                    {
+                        sdrOutputAudioBitrate = state.AudioStream.BitRate ?? 0;
+                    }
+                    else
+                    {
+                        sdrOutputAudioBitrate = _encodingHelper.GetAudioBitrateParam(state.VideoRequest, state.AudioStream, state.OutputAudioChannels) ?? 0;
+                    }
 
+                    var sdrTotalBitrate = sdrOutputAudioBitrate + sdrOutputVideoBitrate;
                     var sdrPlaylist = AppendPlaylist(builder, state, sdrVideoUrl, sdrTotalBitrate, subtitleGroup);
 
                     // Provide a workaround for the case issue between flac and fLaC.

+ 11 - 5
Jellyfin.Api/Helpers/StreamingHelpers.cs

@@ -181,12 +181,18 @@ public static class StreamingHelpers
                 : GetOutputFileExtension(state, mediaSource);
         }
 
-        state.OutputContainer = (containerInternal ?? string.Empty).TrimStart('.');
-
-        state.OutputAudioBitrate = encodingHelper.GetAudioBitrateParam(streamingRequest.AudioBitRate, streamingRequest.AudioCodec, state.AudioStream, state.OutputAudioChannels);
-
-        state.OutputAudioCodec = streamingRequest.AudioCodec;
+        var outputAudioCodec = streamingRequest.AudioCodec;
+        if (EncodingHelper.LosslessAudioCodecs.Contains(outputAudioCodec))
+        {
+            state.OutputAudioBitrate = state.AudioStream.BitRate ?? 0;
+        }
+        else
+        {
+            state.OutputAudioBitrate = encodingHelper.GetAudioBitrateParam(streamingRequest.AudioBitRate, streamingRequest.AudioCodec, state.AudioStream, state.OutputAudioChannels) ?? 0;
+        }
 
+        state.OutputAudioCodec = outputAudioCodec;
+        state.OutputContainer = (containerInternal ?? string.Empty).TrimStart('.');
         state.OutputAudioChannels = encodingHelper.GetNumAudioChannelsParam(state, state.AudioStream, state.OutputAudioCodec);
 
         if (state.VideoRequest is not null)

+ 17 - 28
MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs

@@ -86,6 +86,16 @@ namespace MediaBrowser.Controller.MediaEncoding
             { "truehd", 6 },
         };
 
+        public static readonly string[] LosslessAudioCodecs = new string[]
+        {
+            "alac",
+            "ape",
+            "flac",
+            "mlp",
+            "truehd",
+            "wavpack"
+        };
+
         public EncodingHelper(
             IApplicationPaths appPaths,
             IMediaEncoder mediaEncoder,
@@ -2149,17 +2159,6 @@ namespace MediaBrowser.Controller.MediaEncoding
                 };
             }
 
-            if (string.Equals(audioCodec, "flac", StringComparison.OrdinalIgnoreCase)
-                || string.Equals(audioCodec, "alac", StringComparison.OrdinalIgnoreCase))
-            {
-                if (inputChannels >= 6)
-                {
-                    return Math.Min(3584000, bitrate);
-                }
-
-                return Math.Min(1536000, bitrate);
-            }
-
             if (string.Equals(audioCodec, "dts", StringComparison.OrdinalIgnoreCase)
                 || string.Equals(audioCodec, "dca", StringComparison.OrdinalIgnoreCase))
             {
@@ -2172,20 +2171,10 @@ namespace MediaBrowser.Controller.MediaEncoding
                 };
             }
 
-            if (string.Equals(audioCodec, "truehd", StringComparison.OrdinalIgnoreCase))
-            {
-                return (inputChannels, outputChannels) switch
-                {
-                    (> 0, > 0) => Math.Min(outputChannels * 768000, bitrate),
-                    (> 0, _) => Math.Min(inputChannels * 768000, bitrate),
-                    (_, _) => Math.Min(768000, bitrate)
-                };
-            }
-
             // Empty bitrate area is not allow on iOS
             // Default audio bitrate to 128K per channel if we don't have codec specific defaults
             // https://ffmpeg.org/ffmpeg-codecs.html#toc-Codec-Options
-            return 128000 * (outputAudioChannels ?? audioStream.Channels ?? 1);
+            return 128000 * (outputAudioChannels ?? audioStream.Channels ?? 2);
         }
 
         public string GetAudioVbrModeParam(string encoder, int bitratePerChannel)
@@ -5867,8 +5856,7 @@ namespace MediaBrowser.Controller.MediaEncoding
             }
 
             var bitrate = state.OutputAudioBitrate;
-
-            if (bitrate.HasValue)
+            if (bitrate.HasValue && !LosslessAudioCodecs.Contains(codec, StringComparison.OrdinalIgnoreCase))
             {
                 var vbrParam = GetAudioVbrModeParam(codec, bitrate.Value / (channels ?? 2));
                 if (encodingOptions.EnableAudioVbr && vbrParam is not null)
@@ -5897,10 +5885,11 @@ namespace MediaBrowser.Controller.MediaEncoding
 
             var bitrate = state.OutputAudioBitrate;
             var channels = state.OutputAudioChannels;
+            var outputCodec = state.OutputAudioCodec;
 
-            if (bitrate.HasValue)
+            if (bitrate.HasValue && !LosslessAudioCodecs.Contains(outputCodec, StringComparison.OrdinalIgnoreCase))
             {
-                var vbrParam = GetAudioVbrModeParam(state.OutputAudioCodec, bitrate.Value / (channels ?? 2));
+                var vbrParam = GetAudioVbrModeParam(outputCodec, bitrate.Value / (channels ?? 2));
                 if (encodingOptions.EnableAudioVbr && vbrParam is not null)
                 {
                     audioTranscodeParams.Add(vbrParam);
@@ -5916,12 +5905,12 @@ namespace MediaBrowser.Controller.MediaEncoding
                 audioTranscodeParams.Add("-ac " + state.OutputAudioChannels.Value.ToString(CultureInfo.InvariantCulture));
             }
 
-            if (!string.IsNullOrEmpty(state.OutputAudioCodec))
+            if (!string.IsNullOrEmpty(outputCodec))
             {
                 audioTranscodeParams.Add("-acodec " + GetAudioEncoder(state));
             }
 
-            if (!string.Equals(state.OutputAudioCodec, "opus", StringComparison.OrdinalIgnoreCase))
+            if (!string.Equals(outputCodec, "opus", StringComparison.OrdinalIgnoreCase))
             {
                 // opus only supports specific sampling rates
                 var sampleRate = state.OutputAudioSampleRate;