diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 05117fd08d9..d7eac0a2de8 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -2723,6 +2723,12 @@ class PlaybackManager { }); }); } else { + if (item.AlbumId != null) { + return apiClient.getItem(apiClient.getCurrentUserId(), item.AlbumId).then(function(result) { + mediaSource.albumLUFS = result.LUFS; + return mediaSource; + }); + } return mediaSource; } } else { diff --git a/src/components/playbackSettings/playbackSettings.js b/src/components/playbackSettings/playbackSettings.js index 0e3a798b653..aa02c1ed228 100644 --- a/src/components/playbackSettings/playbackSettings.js +++ b/src/components/playbackSettings/playbackSettings.js @@ -173,7 +173,7 @@ function loadForm(context, user, userSettings, apiClient) { context.querySelector('.chkPlayDefaultAudioTrack').checked = user.Configuration.PlayDefaultAudioTrack || false; context.querySelector('.chkPreferFmp4HlsContainer').checked = userSettings.preferFmp4HlsContainer(); context.querySelector('.chkEnableCinemaMode').checked = userSettings.enableCinemaMode(); - context.querySelector('.chkEnableAudioNormalization').checked = userSettings.enableAudioNormalization(); + context.querySelector('#selectAudioNormalization').value = userSettings.selectAudioNormalization(); context.querySelector('.chkEnableNextVideoOverlay').checked = userSettings.enableNextVideoInfoOverlay(); context.querySelector('.chkRememberAudioSelections').checked = user.Configuration.RememberAudioSelections || false; context.querySelector('.chkRememberSubtitleSelections').checked = user.Configuration.RememberSubtitleSelections || false; @@ -218,7 +218,7 @@ function saveUser(context, user, userSettingsInstance, apiClient) { user.Configuration.EnableNextEpisodeAutoPlay = context.querySelector('.chkEpisodeAutoPlay').checked; userSettingsInstance.preferFmp4HlsContainer(context.querySelector('.chkPreferFmp4HlsContainer').checked); userSettingsInstance.enableCinemaMode(context.querySelector('.chkEnableCinemaMode').checked); - userSettingsInstance.enableAudioNormalization(context.querySelector('.chkEnableAudioNormalization').checked); + userSettingsInstance.selectAudioNormalization(context.querySelector('#selectAudioNormalization').value); userSettingsInstance.enableNextVideoInfoOverlay(context.querySelector('.chkEnableNextVideoOverlay').checked); user.Configuration.RememberAudioSelections = context.querySelector('.chkRememberAudioSelections').checked; user.Configuration.RememberSubtitleSelections = context.querySelector('.chkRememberSubtitleSelections').checked; diff --git a/src/components/playbackSettings/playbackSettings.template.html b/src/components/playbackSettings/playbackSettings.template.html index 44dfe85e0b5..0926737af7c 100644 --- a/src/components/playbackSettings/playbackSettings.template.html +++ b/src/components/playbackSettings/playbackSettings.template.html @@ -72,12 +72,13 @@

${TabAdvanced}

-
- -
${EnableAudioNormalizationHelp}
+
+ +
${SelectAudioNormalizationHelp}
diff --git a/src/plugins/htmlAudioPlayer/plugin.js b/src/plugins/htmlAudioPlayer/plugin.js index 2742e8d8cce..d9104638c8a 100644 --- a/src/plugins/htmlAudioPlayer/plugin.js +++ b/src/plugins/htmlAudioPlayer/plugin.js @@ -112,9 +112,14 @@ class HtmlAudioPlayer { let val = options.url; console.debug('playing url: ' + val); import('../../scripts/settings/userSettings').then((userSettings) => { - if (userSettings.enableAudioNormalization() && options.item.LUFS != null) { + if (userSettings.selectAudioNormalization() == 'TrackGain' && options.item.LUFS != null) { const dbGain = -18 - options.item.LUFS; self.gainNode.gain.value = Math.pow(10, (dbGain / 20)); + console.debug('[HtmlAudioPlayer] Using track gain'); + } else if (userSettings.selectAudioNormalization() == 'AlbumGain' && options.mediaSource.albumLUFS != null) { + const dbGain = -18 - options.mediaSource.albumLUFS; + self.gainNode.gain.value = Math.pow(10, (dbGain / 20)); + console.debug('[HtmlAudioPlayer] Using album gain'); } else { self.gainNode.gain.value = 1; } diff --git a/src/scripts/settings/userSettings.js b/src/scripts/settings/userSettings.js index 9dc0656219f..d305c5469be 100644 --- a/src/scripts/settings/userSettings.js +++ b/src/scripts/settings/userSettings.js @@ -158,15 +158,15 @@ export class UserSettings { /** * Get or set 'Enable Audio Normalization' state. - * @param {boolean|undefined} val - Flag to enable 'Enable Audio Normalization' or undefined. - * @return {boolean} 'Enable Audio Normalization' state. + * @param {string|undefined} val - Flag to enable 'Enable Audio Normalization' or undefined. + * @return {string} 'Enable Audio Normalization' state. */ - enableAudioNormalization(val) { + selectAudioNormalization(val) { if (val !== undefined) { - return this.set('enableAudioNormalization', val.toString(), false); + return this.set('selectAudioNormalization', val, false); } - return toBoolean(this.get('enableAudioNormalization', false), true); + return this.get('selectAudioNormalization', false) || 'TrackGain'; } /** @@ -636,7 +636,7 @@ export const serverConfig = currentSettings.serverConfig.bind(currentSettings); export const allowedAudioChannels = currentSettings.allowedAudioChannels.bind(currentSettings); export const preferFmp4HlsContainer = currentSettings.preferFmp4HlsContainer.bind(currentSettings); export const enableCinemaMode = currentSettings.enableCinemaMode.bind(currentSettings); -export const enableAudioNormalization = currentSettings.enableAudioNormalization.bind(currentSettings); +export const selectAudioNormalization = currentSettings.selectAudioNormalization.bind(currentSettings); export const enableNextVideoInfoOverlay = currentSettings.enableNextVideoInfoOverlay.bind(currentSettings); export const enableVideoRemainingTime = currentSettings.enableVideoRemainingTime.bind(currentSettings); export const enableThemeSongs = currentSettings.enableThemeSongs.bind(currentSettings); diff --git a/src/strings/en-us.json b/src/strings/en-us.json index 46ac5869511..f7243d87ba1 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -138,7 +138,7 @@ "ChannelNumber": "Channel number", "Channels": "Channels", "CinemaModeConfigurationHelp": "Cinema mode brings the theater experience straight to your living room with the ability to play trailers and custom intros before the main feature.", - "EnableAudioNormalizationHelp": "Audio normalization will add a constant gain to keep the average at a desired level (-18dB).", + "SelectAudioNormalizationHelp": "Track gain - adjusts the volume of each track so they playback with the same loudness. Album gain - adjusts the volume of all the tracks in an album only, keeping the album's dynamic range.", "ClearQueue": "Clear queue", "ClientSettings": "Client Settings", "Collections": "Collections", @@ -226,7 +226,6 @@ "EnableBlurHash": "Enable blurred placeholders for images", "EnableBlurHashHelp": "Images that are still being loaded will be displayed with a unique placeholder.", "EnableCinemaMode": "Cinema mode", - "EnableAudioNormalization": "Audio Normalization", "EnableColorCodedBackgrounds": "Color coded backgrounds", "EnableDecodingColorDepth10Hevc": "Enable 10-bit hardware decoding for HEVC", "EnableDecodingColorDepth10Vp9": "Enable 10-bit hardware decoding for VP9", @@ -549,6 +548,7 @@ "LabelAlbumArtMaxResHelp": "Maximum resolution of album art exposed via the 'upnp:albumArtURI' property.", "LabelAlbumArtMaxWidth": "Album art max width", "LabelAlbumArtPN": "Album art PN", + "LabelAlbumGain": "Album Gain", "LabelAllowedRemoteAddresses": "Remote IP address filter", "LabelAllowedRemoteAddressesMode": "Remote IP address filter mode", "LabelAllowHWTranscoding": "Allow hardware transcoding", @@ -561,6 +561,7 @@ "LabelAudioChannels": "Audio channels", "LabelAudioCodec": "Audio codec", "LabelAudioLanguagePreference": "Preferred audio language", + "LabelSelectAudioNormalization": "Audio Normalization", "LabelAudioSampleRate": "Audio sample rate", "LabelAuthProvider": "Authentication Provider", "LabelAutomaticallyAddToCollection": "Automatically add to collection", @@ -1635,6 +1636,7 @@ "LabelPlaybackInfo": "Playback Info", "LabelAudioInfo": "Audio Info", "LabelVideoInfo": "Video Info", + "LabelTrackGain": "Track Gain", "LabelTranscodingInfo": "Transcoding Info", "LabelDirectStreamingInfo": "Direct Streaming Info", "LabelRemuxingInfo": "Remuxing Info",