Jelajahi Sumber

Improve audio normalization

* Move calculation of LUFS to a scheduled task as it's pretty slow
* Correctly calculate album LUFS
* Don't try to convert replaygain tags to LUFS values
Bond_009 1 tahun lalu
induk
melakukan
88a38a61b5

+ 10 - 2
Emby.Server.Implementations/Data/SqliteItemRepository.cs

@@ -49,8 +49,8 @@ namespace Emby.Server.Implementations.Data
 
         private const string SaveItemCommandText =
             @"replace into TypedBaseItems
-            (guid,type,data,Path,StartDate,EndDate,ChannelId,IsMovie,IsSeries,EpisodeTitle,IsRepeat,CommunityRating,CustomRating,IndexNumber,IsLocked,Name,OfficialRating,MediaType,Overview,ParentIndexNumber,PremiereDate,ProductionYear,ParentId,Genres,InheritedParentalRatingValue,SortName,ForcedSortName,RunTimeTicks,Size,DateCreated,DateModified,PreferredMetadataLanguage,PreferredMetadataCountryCode,Width,Height,DateLastRefreshed,DateLastSaved,IsInMixedFolder,LockedFields,Studios,Audio,ExternalServiceId,Tags,IsFolder,UnratedType,TopParentId,TrailerTypes,CriticRating,CleanName,PresentationUniqueKey,OriginalTitle,PrimaryVersionId,DateLastMediaAdded,Album,LUFS,IsVirtualItem,SeriesName,UserDataKey,SeasonName,SeasonId,SeriesId,ExternalSeriesId,Tagline,ProviderIds,Images,ProductionLocations,ExtraIds,TotalBitrate,ExtraType,Artists,AlbumArtists,ExternalId,SeriesPresentationUniqueKey,ShowId,OwnerId)
-            values (@guid,@type,@data,@Path,@StartDate,@EndDate,@ChannelId,@IsMovie,@IsSeries,@EpisodeTitle,@IsRepeat,@CommunityRating,@CustomRating,@IndexNumber,@IsLocked,@Name,@OfficialRating,@MediaType,@Overview,@ParentIndexNumber,@PremiereDate,@ProductionYear,@ParentId,@Genres,@InheritedParentalRatingValue,@SortName,@ForcedSortName,@RunTimeTicks,@Size,@DateCreated,@DateModified,@PreferredMetadataLanguage,@PreferredMetadataCountryCode,@Width,@Height,@DateLastRefreshed,@DateLastSaved,@IsInMixedFolder,@LockedFields,@Studios,@Audio,@ExternalServiceId,@Tags,@IsFolder,@UnratedType,@TopParentId,@TrailerTypes,@CriticRating,@CleanName,@PresentationUniqueKey,@OriginalTitle,@PrimaryVersionId,@DateLastMediaAdded,@Album,@LUFS,@IsVirtualItem,@SeriesName,@UserDataKey,@SeasonName,@SeasonId,@SeriesId,@ExternalSeriesId,@Tagline,@ProviderIds,@Images,@ProductionLocations,@ExtraIds,@TotalBitrate,@ExtraType,@Artists,@AlbumArtists,@ExternalId,@SeriesPresentationUniqueKey,@ShowId,@OwnerId)";
+            (guid,type,data,Path,StartDate,EndDate,ChannelId,IsMovie,IsSeries,EpisodeTitle,IsRepeat,CommunityRating,CustomRating,IndexNumber,IsLocked,Name,OfficialRating,MediaType,Overview,ParentIndexNumber,PremiereDate,ProductionYear,ParentId,Genres,InheritedParentalRatingValue,SortName,ForcedSortName,RunTimeTicks,Size,DateCreated,DateModified,PreferredMetadataLanguage,PreferredMetadataCountryCode,Width,Height,DateLastRefreshed,DateLastSaved,IsInMixedFolder,LockedFields,Studios,Audio,ExternalServiceId,Tags,IsFolder,UnratedType,TopParentId,TrailerTypes,CriticRating,CleanName,PresentationUniqueKey,OriginalTitle,PrimaryVersionId,DateLastMediaAdded,Album,LUFS,NormalizationGain,IsVirtualItem,SeriesName,UserDataKey,SeasonName,SeasonId,SeriesId,ExternalSeriesId,Tagline,ProviderIds,Images,ProductionLocations,ExtraIds,TotalBitrate,ExtraType,Artists,AlbumArtists,ExternalId,SeriesPresentationUniqueKey,ShowId,OwnerId)
+            values (@guid,@type,@data,@Path,@StartDate,@EndDate,@ChannelId,@IsMovie,@IsSeries,@EpisodeTitle,@IsRepeat,@CommunityRating,@CustomRating,@IndexNumber,@IsLocked,@Name,@OfficialRating,@MediaType,@Overview,@ParentIndexNumber,@PremiereDate,@ProductionYear,@ParentId,@Genres,@InheritedParentalRatingValue,@SortName,@ForcedSortName,@RunTimeTicks,@Size,@DateCreated,@DateModified,@PreferredMetadataLanguage,@PreferredMetadataCountryCode,@Width,@Height,@DateLastRefreshed,@DateLastSaved,@IsInMixedFolder,@LockedFields,@Studios,@Audio,@ExternalServiceId,@Tags,@IsFolder,@UnratedType,@TopParentId,@TrailerTypes,@CriticRating,@CleanName,@PresentationUniqueKey,@OriginalTitle,@PrimaryVersionId,@DateLastMediaAdded,@Album,@LUFS,@NormalizationGain,@IsVirtualItem,@SeriesName,@UserDataKey,@SeasonName,@SeasonId,@SeriesId,@ExternalSeriesId,@Tagline,@ProviderIds,@Images,@ProductionLocations,@ExtraIds,@TotalBitrate,@ExtraType,@Artists,@AlbumArtists,@ExternalId,@SeriesPresentationUniqueKey,@ShowId,@OwnerId)";
 
         private readonly IServerConfigurationManager _config;
         private readonly IServerApplicationHost _appHost;
@@ -111,6 +111,7 @@ namespace Emby.Server.Implementations.Data
             "DateLastMediaAdded",
             "Album",
             "LUFS",
+            "NormalizationGain",
             "CriticRating",
             "IsVirtualItem",
             "SeriesName",
@@ -478,6 +479,7 @@ namespace Emby.Server.Implementations.Data
                 AddColumn(connection, "TypedBaseItems", "DateLastMediaAdded", "DATETIME", existingColumnNames);
                 AddColumn(connection, "TypedBaseItems", "Album", "Text", existingColumnNames);
                 AddColumn(connection, "TypedBaseItems", "LUFS", "Float", existingColumnNames);
+                AddColumn(connection, "TypedBaseItems", "NormalizationGain", "Float", existingColumnNames);
                 AddColumn(connection, "TypedBaseItems", "IsVirtualItem", "BIT", existingColumnNames);
                 AddColumn(connection, "TypedBaseItems", "SeriesName", "Text", existingColumnNames);
                 AddColumn(connection, "TypedBaseItems", "UserDataKey", "Text", existingColumnNames);
@@ -886,6 +888,7 @@ namespace Emby.Server.Implementations.Data
 
             saveItemStatement.TryBind("@Album", item.Album);
             saveItemStatement.TryBind("@LUFS", item.LUFS);
+            saveItemStatement.TryBind("@NormalizationGain", item.NormalizationGain);
             saveItemStatement.TryBind("@IsVirtualItem", item.IsVirtualItem);
 
             if (item is IHasSeries hasSeriesName)
@@ -1672,6 +1675,11 @@ namespace Emby.Server.Implementations.Data
                 item.LUFS = lUFS;
             }
 
+            if (reader.TryGetSingle(index++, out var normalizationGain))
+            {
+                item.NormalizationGain = normalizationGain;
+            }
+
             if (reader.TryGetSingle(index++, out var criticRating))
             {
                 item.CriticRating = criticRating;

+ 8 - 1
Emby.Server.Implementations/Dto/DtoService.cs

@@ -898,7 +898,14 @@ namespace Emby.Server.Implementations.Dto
                 dto.IsPlaceHolder = supportsPlaceHolders.IsPlaceHolder;
             }
 
-            dto.LUFS = item.LUFS;
+            if (item.LUFS.HasValue)
+            {
+                dto.NormalizationGain = -18f - item.LUFS;
+            }
+            else if (item.NormalizationGain.HasValue)
+            {
+                dto.NormalizationGain = item.NormalizationGain;
+            }
 
             // Add audio info
             if (item is Audio audio)

+ 0 - 1
Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs

@@ -13,7 +13,6 @@ using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Controller.Resolvers;
-using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.IO;
 using Microsoft.Extensions.Logging;
 

+ 2 - 0
Emby.Server.Implementations/Localization/Core/en-US.json

@@ -106,6 +106,8 @@
     "TaskCleanCacheDescription": "Deletes cache files no longer needed by the system.",
     "TaskRefreshChapterImages": "Extract Chapter Images",
     "TaskRefreshChapterImagesDescription": "Creates thumbnails for videos that have chapters.",
+    "TaskAudioNormalization": "Audio Normalization",
+    "TaskAudioNormalizationDescription": "Scans files for audio normalization data.",
     "TaskRefreshLibrary": "Scan Media Library",
     "TaskRefreshLibraryDescription": "Scans your media library for new files and refreshes metadata.",
     "TaskCleanLogs": "Clean Log Directory",

+ 196 - 0
Emby.Server.Implementations/ScheduledTasks/Tasks/AudioNormalizationPostScanTask.cs

@@ -0,0 +1,196 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
+using Jellyfin.Data.Enums;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.MediaEncoding;
+using MediaBrowser.Controller.Persistence;
+using MediaBrowser.Model.Globalization;
+using MediaBrowser.Model.Tasks;
+using Microsoft.Extensions.Logging;
+
+namespace Emby.Server.Implementations.ScheduledTasks.Tasks;
+
+/// <summary>
+/// The splashscreen post scan task.
+/// </summary>
+public partial class AudioNormalizationTask : IScheduledTask
+{
+    private readonly IItemRepository _itemRepository;
+    private readonly ILibraryManager _libraryManager;
+    private readonly IMediaEncoder _mediaEncoder;
+    private readonly IConfigurationManager _configurationManager;
+    private readonly ILocalizationManager _localization;
+    private readonly ILogger<AudioNormalizationTask> _logger;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="AudioNormalizationTask"/> class.
+    /// </summary>
+    /// <param name="itemRepository">Instance of the <see cref="IItemRepository"/> interface.</param>
+    /// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
+    /// <param name="mediaEncoder">Instance of the <see cref="IMediaEncoder"/> interface.</param>
+    /// <param name="configurationManager">Instance of the <see cref="IConfigurationManager"/> interface.</param>
+    /// <param name="localizationManager">Instance of the <see cref="ILocalizationManager"/> interface.</param>
+    /// <param name="logger">Instance of the <see cref="ILogger{AudioNormalizationTask}"/> interface.</param>
+    public AudioNormalizationTask(
+        IItemRepository itemRepository,
+        ILibraryManager libraryManager,
+        IMediaEncoder mediaEncoder,
+        IConfigurationManager configurationManager,
+        ILocalizationManager localizationManager,
+        ILogger<AudioNormalizationTask> logger)
+    {
+        _itemRepository = itemRepository;
+        _libraryManager = libraryManager;
+        _mediaEncoder = mediaEncoder;
+        _configurationManager = configurationManager;
+        _localization = localizationManager;
+        _logger = logger;
+    }
+
+    /// <inheritdoc />
+    public string Name => _localization.GetLocalizedString("TaskAudioNormalization");
+
+    /// <inheritdoc />
+    public string Description => _localization.GetLocalizedString("TaskAudioNormalizationDescription");
+
+    /// <inheritdoc />
+    public string Category => _localization.GetLocalizedString("TasksLibraryCategory");
+
+    /// <inheritdoc />
+    public string Key => "AudioNormalization";
+
+    [GeneratedRegex(@"I:\s+(.*?)\s+LUFS")]
+    private static partial Regex LUFSRegex();
+
+    /// <inheritdoc />
+    public async Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellationToken)
+    {
+        foreach (var library in _libraryManager.RootFolder.Children)
+        {
+            var libraryOptions = _libraryManager.GetLibraryOptions(library);
+            if (!libraryOptions.EnableLUFSScan)
+            {
+                continue;
+            }
+
+            // Album gain
+            var albums = _libraryManager.GetItemList(new InternalItemsQuery
+            {
+                IncludeItemTypes = [BaseItemKind.MusicAlbum],
+                Parent = library,
+                Recursive = true
+            });
+
+            foreach (var a in albums)
+            {
+                if (a.NormalizationGain.HasValue || a.LUFS.HasValue)
+                {
+                    continue;
+                }
+
+                var albumTracks = ((MusicAlbum)a).Tracks.Where(x => x.IsFileProtocol).ToList();
+                if (albumTracks.Count == 0)
+                {
+                    continue;
+                }
+
+                var tempFile = Path.Join(_configurationManager.GetTranscodePath(), Guid.NewGuid() + ".concat");
+                var inputLines = albumTracks.Select(x => string.Format(CultureInfo.InvariantCulture, "file '{0}'", x.Path.Replace("'", @"'\''", StringComparison.Ordinal)));
+                await File.WriteAllLinesAsync(tempFile, inputLines, cancellationToken).ConfigureAwait(false);
+                a.LUFS = await CalculateLUFSAsync(
+                    string.Format(CultureInfo.InvariantCulture, "-f concat -safe 0 -i \"{0}\"", tempFile),
+                    cancellationToken).ConfigureAwait(false);
+                File.Delete(tempFile);
+            }
+
+            _itemRepository.SaveItems(albums, cancellationToken);
+
+            var tracks = _libraryManager.GetItemList(new InternalItemsQuery
+            {
+                MediaTypes = [MediaType.Audio],
+                IncludeItemTypes = [BaseItemKind.Audio],
+                Parent = library,
+                Recursive = true
+            });
+
+            foreach (var t in tracks)
+            {
+                if (t.NormalizationGain.HasValue || t.LUFS.HasValue || !t.IsFileProtocol)
+                {
+                    continue;
+                }
+
+                t.LUFS = await CalculateLUFSAsync(string.Format(CultureInfo.InvariantCulture, "-i \"{0}\"", t.Path.Replace("\"", "\\\"", StringComparison.Ordinal)), cancellationToken);
+            }
+
+            _itemRepository.SaveItems(tracks, cancellationToken);
+        }
+    }
+
+    /// <inheritdoc />
+    public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
+    {
+        return
+        [
+            new TaskTriggerInfo
+            {
+                Type = TaskTriggerInfo.TriggerInterval,
+                IntervalTicks = TimeSpan.FromHours(24).Ticks
+            }
+        ];
+    }
+
+    private string EscapeFilename(string filename)
+        => filename;
+
+    private async Task<float?> CalculateLUFSAsync(string inputArgs, CancellationToken cancellationToken)
+    {
+        var args = $"-hide_banner {inputArgs} -af ebur128=framelog=verbose -f null -";
+
+        using (var process = new Process()
+        {
+            StartInfo = new ProcessStartInfo
+            {
+                FileName = _mediaEncoder.EncoderPath,
+                Arguments = args,
+                RedirectStandardOutput = false,
+                RedirectStandardError = true
+            },
+        })
+        {
+            try
+            {
+                _logger.LogDebug("Starting ffmpeg with arguments: {Arguments}", args);
+                process.Start();
+            }
+            catch (Exception ex)
+            {
+                _logger.LogError(ex, "Error starting ffmpeg with arguments: {Arguments}", args);
+                return null;
+            }
+
+            using var reader = process.StandardError;
+            var output = await reader.ReadToEndAsync(cancellationToken).ConfigureAwait(false);
+            cancellationToken.ThrowIfCancellationRequested();
+            MatchCollection split = LUFSRegex().Matches(output);
+
+            if (split.Count != 0)
+            {
+                return float.Parse(split[0].Groups[1].ValueSpan, CultureInfo.InvariantCulture.NumberFormat);
+            }
+
+            _logger.LogError("Failed to find LUFS value in output:\n{Output}", output);
+            return null;
+        }
+    }
+}

+ 0 - 1
Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs

@@ -13,7 +13,6 @@ using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Globalization;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Tasks;

+ 4 - 5
MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs

@@ -183,14 +183,13 @@ namespace MediaBrowser.Controller.Entities.Audio
                 progress.Report(percent * 95);
             }
 
-            // get album LUFS
-            LUFS = items.OfType<Audio>().Max(item => item.LUFS);
-
             var parentRefreshOptions = refreshOptions;
             if (childUpdateType > ItemUpdateType.None)
             {
-                parentRefreshOptions = new MetadataRefreshOptions(refreshOptions);
-                parentRefreshOptions.MetadataRefreshMode = MetadataRefreshMode.FullRefresh;
+                parentRefreshOptions = new MetadataRefreshOptions(refreshOptions)
+                {
+                    MetadataRefreshMode = MetadataRefreshMode.FullRefresh
+                };
             }
 
             // Refresh current item

+ 7 - 0
MediaBrowser.Controller/Entities/BaseItem.cs

@@ -137,6 +137,13 @@ namespace MediaBrowser.Controller.Entities
         [JsonIgnore]
         public float? LUFS { get; set; }
 
+        /// <summary>
+        /// Gets or sets the gain required for audio normalization.
+        /// </summary>
+        /// <value>The gain required for audio normalization..</value>
+        [JsonIgnore]
+        public float? NormalizationGain { get; set; }
+
         /// <summary>
         /// Gets or sets the channel identifier.
         /// </summary>

+ 3 - 3
MediaBrowser.Model/Dto/BaseItemDto.cs

@@ -782,10 +782,10 @@ namespace MediaBrowser.Model.Dto
         public string TimerId { get; set; }
 
         /// <summary>
-        /// Gets or sets the LUFS value.
+        /// Gets or sets the gain required for audio normalization.
         /// </summary>
-        /// <value>The LUFS Value.</value>
-        public float? LUFS { get; set; }
+        /// <value>The gain required for audio normalization..</value>
+        public float? NormalizationGain { get; set; }
 
         /// <summary>
         /// Gets or sets the current program.

+ 2 - 55
MediaBrowser.Providers/MediaInfo/AudioFileProber.cs

@@ -1,9 +1,6 @@
 using System;
 using System.Collections.Generic;
-using System.Diagnostics;
-using System.Globalization;
 using System.Linq;
-using System.Text.RegularExpressions;
 using System.Threading;
 using System.Threading.Tasks;
 using Jellyfin.Data.Enums;
@@ -18,7 +15,6 @@ using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.MediaInfo;
-using Microsoft.Extensions.Logging;
 using TagLib;
 
 namespace MediaBrowser.Providers.MediaInfo
@@ -26,12 +22,8 @@ namespace MediaBrowser.Providers.MediaInfo
     /// <summary>
     /// Probes audio files for metadata.
     /// </summary>
-    public partial class AudioFileProber
+    public class AudioFileProber
     {
-        // Default LUFS value for use with the web interface, at -18db gain will be 1(no db gain).
-        private const float DefaultLUFSValue = -18;
-
-        private readonly ILogger<AudioFileProber> _logger;
         private readonly IMediaEncoder _mediaEncoder;
         private readonly IItemRepository _itemRepo;
         private readonly ILibraryManager _libraryManager;
@@ -42,7 +34,6 @@ namespace MediaBrowser.Providers.MediaInfo
         /// <summary>
         /// Initializes a new instance of the <see cref="AudioFileProber"/> class.
         /// </summary>
-        /// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param>
         /// <param name="mediaSourceManager">Instance of the <see cref="IMediaSourceManager"/> interface.</param>
         /// <param name="mediaEncoder">Instance of the <see cref="IMediaEncoder"/> interface.</param>
         /// <param name="itemRepo">Instance of the <see cref="IItemRepository"/> interface.</param>
@@ -50,7 +41,6 @@ namespace MediaBrowser.Providers.MediaInfo
         /// <param name="lyricResolver">Instance of the <see cref="LyricResolver"/> interface.</param>
         /// <param name="lyricManager">Instance of the <see cref="ILyricManager"/> interface.</param>
         public AudioFileProber(
-            ILogger<AudioFileProber> logger,
             IMediaSourceManager mediaSourceManager,
             IMediaEncoder mediaEncoder,
             IItemRepository itemRepo,
@@ -58,7 +48,6 @@ namespace MediaBrowser.Providers.MediaInfo
             LyricResolver lyricResolver,
             ILyricManager lyricManager)
         {
-            _logger = logger;
             _mediaEncoder = mediaEncoder;
             _itemRepo = itemRepo;
             _libraryManager = libraryManager;
@@ -67,9 +56,6 @@ namespace MediaBrowser.Providers.MediaInfo
             _lyricManager = lyricManager;
         }
 
-        [GeneratedRegex(@"I:\s+(.*?)\s+LUFS")]
-        private static partial Regex LUFSRegex();
-
         /// <summary>
         /// Probes the specified item for metadata.
         /// </summary>
@@ -112,45 +98,6 @@ namespace MediaBrowser.Providers.MediaInfo
                 await FetchAsync(item, result, options, cancellationToken).ConfigureAwait(false);
             }
 
-            var libraryOptions = _libraryManager.GetLibraryOptions(item);
-            if (libraryOptions.EnableLUFSScan && item.LUFS is null)
-            {
-                using (var process = new Process()
-                {
-                    StartInfo = new ProcessStartInfo
-                    {
-                        FileName = _mediaEncoder.EncoderPath,
-                        Arguments = $"-hide_banner -i \"{path}\" -af ebur128=framelog=verbose -f null -",
-                        RedirectStandardOutput = false,
-                        RedirectStandardError = true
-                    },
-                })
-                {
-                    try
-                    {
-                        process.Start();
-                    }
-                    catch (Exception ex)
-                    {
-                        _logger.LogError(ex, "Error starting ffmpeg");
-
-                        throw;
-                    }
-
-                    using var reader = process.StandardError;
-                    var output = await reader.ReadToEndAsync(cancellationToken).ConfigureAwait(false);
-                    cancellationToken.ThrowIfCancellationRequested();
-                    MatchCollection split = LUFSRegex().Matches(output);
-
-                    if (split.Count != 0)
-                    {
-                        item.LUFS = float.Parse(split[0].Groups[1].ValueSpan, CultureInfo.InvariantCulture.NumberFormat);
-                    }
-                }
-            }
-
-            _logger.LogDebug("LUFS for {ItemName} is {LUFS}.", item.Name, item.LUFS);
-
             return ItemUpdateType.MetadataImport;
         }
 
@@ -339,7 +286,7 @@ namespace MediaBrowser.Providers.MediaInfo
 
                 if (!double.IsNaN(tags.ReplayGainTrackGain))
                 {
-                    audio.LUFS = DefaultLUFSValue - (float)tags.ReplayGainTrackGain;
+                    audio.NormalizationGain = (float)tags.ReplayGainTrackGain;
                 }
 
                 if (options.ReplaceAllMetadata || !audio.TryGetProviderId(MetadataProvider.MusicBrainzArtist, out _))

+ 0 - 1
MediaBrowser.Providers/MediaInfo/ProbeProvider.cs

@@ -103,7 +103,6 @@ namespace MediaBrowser.Providers.MediaInfo
                 _subtitleResolver);
 
             _audioProber = new AudioFileProber(
-                loggerFactory.CreateLogger<AudioFileProber>(),
                 mediaSourceManager,
                 mediaEncoder,
                 itemRepo,