Browse Source

Backport pull request #11910 from jellyfin/release-10.9.z

Audio normalization: parse ffmpeg output line by line

Original-merge: d2be2ee480a44d3ed266d4632c3f38439b0dfaf5

Merged-by: joshuaboniface <joshua@boniface.me>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
Bond-009 1 năm trước cách đây
mục cha
commit
c7f87c0d69

+ 10 - 8
Emby.Server.Implementations/ScheduledTasks/Tasks/AudioNormalizationTask.cs

@@ -8,6 +8,7 @@ using System.Text.RegularExpressions;
 using System.Threading;
 using System.Threading.Tasks;
 using Jellyfin.Data.Enums;
+using Jellyfin.Extensions;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Audio;
@@ -69,7 +70,7 @@ public partial class AudioNormalizationTask : IScheduledTask
     /// <inheritdoc />
     public string Key => "AudioNormalization";
 
-    [GeneratedRegex(@"I:\s+(.*?)\s+LUFS")]
+    [GeneratedRegex(@"^\s+I:\s+(.*?)\s+LUFS")]
     private static partial Regex LUFSRegex();
 
     /// <inheritdoc />
@@ -179,16 +180,17 @@ public partial class AudioNormalizationTask : IScheduledTask
             }
 
             using var reader = process.StandardError;
-            var output = await reader.ReadToEndAsync(cancellationToken).ConfigureAwait(false);
-            cancellationToken.ThrowIfCancellationRequested();
-            MatchCollection split = LUFSRegex().Matches(output);
-
-            if (split.Count != 0)
+            await foreach (var line in reader.ReadAllLinesAsync(cancellationToken))
             {
-                return float.Parse(split[0].Groups[1].ValueSpan, CultureInfo.InvariantCulture.NumberFormat);
+                Match match = LUFSRegex().Match(line);
+
+                if (match.Success)
+                {
+                    return float.Parse(match.Groups[1].ValueSpan, CultureInfo.InvariantCulture.NumberFormat);
+                }
             }
 
-            _logger.LogError("Failed to find LUFS value in output:\n{Output}", output);
+            _logger.LogError("Failed to find LUFS value in output");
             return null;
         }
     }

+ 5 - 2
src/Jellyfin.Extensions/StreamExtensions.cs

@@ -1,7 +1,9 @@
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
+using System.Runtime.CompilerServices;
 using System.Text;
+using System.Threading;
 
 namespace Jellyfin.Extensions
 {
@@ -48,11 +50,12 @@ namespace Jellyfin.Extensions
         /// Reads all lines in the <see cref="TextReader" />.
         /// </summary>
         /// <param name="reader">The <see cref="TextReader" /> to read from.</param>
+        /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
         /// <returns>All lines in the stream.</returns>
-        public static async IAsyncEnumerable<string> ReadAllLinesAsync(this TextReader reader)
+        public static async IAsyncEnumerable<string> ReadAllLinesAsync(this TextReader reader, [EnumeratorCancellation] CancellationToken cancellationToken = default)
         {
             string? line;
-            while ((line = await reader.ReadLineAsync().ConfigureAwait(false)) is not null)
+            while ((line = await reader.ReadLineAsync(cancellationToken).ConfigureAwait(false)) is not null)
             {
                 yield return line;
             }