aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBond_009 <bond.009@outlook.com>2024-04-28 15:18:53 +0200
committerBond_009 <bond.009@outlook.com>2024-04-28 15:18:53 +0200
commit88a38a61b59c20b64b5d993364dea2e1d7160d9f (patch)
treea49fd877fa56f7502dcaecf4d3b56866bbaf5de7
parent5612cb81780aaaae581b87062445d1829e71a4a9 (diff)
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
-rw-r--r--Emby.Server.Implementations/Data/SqliteItemRepository.cs12
-rw-r--r--Emby.Server.Implementations/Dto/DtoService.cs9
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs1
-rw-r--r--Emby.Server.Implementations/Localization/Core/en-US.json2
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/Tasks/AudioNormalizationPostScanTask.cs196
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs1
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs9
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs7
-rw-r--r--MediaBrowser.Model/Dto/BaseItemDto.cs6
-rw-r--r--MediaBrowser.Providers/MediaInfo/AudioFileProber.cs57
-rw-r--r--MediaBrowser.Providers/MediaInfo/ProbeProvider.cs1
11 files changed, 232 insertions, 69 deletions
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index 59e4ff1a9..0a8a36ebc 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/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;
diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs
index 98eacb52b..a82258bae 100644
--- a/Emby.Server.Implementations/Dto/DtoService.cs
+++ b/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)
diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
index 0bfb7fbe6..9405f2102 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
+++ b/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;
diff --git a/Emby.Server.Implementations/Localization/Core/en-US.json b/Emby.Server.Implementations/Localization/Core/en-US.json
index 4ba31bee0..c229f3538 100644
--- a/Emby.Server.Implementations/Localization/Core/en-US.json
+++ b/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",
diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/AudioNormalizationPostScanTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/AudioNormalizationPostScanTask.cs
new file mode 100644
index 000000000..f6739de79
--- /dev/null
+++ b/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;
+ }
+ }
+}
diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs
index d03d40863..36456504b 100644
--- a/Emby.Server.Implementations/ScheduledTasks/Tasks/ChapterImagesTask.cs
+++ b/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;
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
index 237345206..5b3349108 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
+++ b/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
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 474b093d5..3dd4d1e39 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -138,6 +138,13 @@ namespace MediaBrowser.Controller.Entities
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>
/// <value>The channel identifier.</value>
diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs
index 6d5c84e1d..623e58807 100644
--- a/MediaBrowser.Model/Dto/BaseItemDto.cs
+++ b/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.
diff --git a/MediaBrowser.Providers/MediaInfo/AudioFileProber.cs b/MediaBrowser.Providers/MediaInfo/AudioFileProber.cs
index 17d2ab71d..9b2610ee7 100644
--- a/MediaBrowser.Providers/MediaInfo/AudioFileProber.cs
+++ b/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 _))
diff --git a/MediaBrowser.Providers/MediaInfo/ProbeProvider.cs b/MediaBrowser.Providers/MediaInfo/ProbeProvider.cs
index 8bb8d5bb4..b330b419b 100644
--- a/MediaBrowser.Providers/MediaInfo/ProbeProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/ProbeProvider.cs
@@ -103,7 +103,6 @@ namespace MediaBrowser.Providers.MediaInfo
_subtitleResolver);
_audioProber = new AudioFileProber(
- loggerFactory.CreateLogger<AudioFileProber>(),
mediaSourceManager,
mediaEncoder,
itemRepo,