diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js
index 25499101f54..2e2aef986d7 100644
--- a/src/components/playback/playbackmanager.js
+++ b/src/components/playback/playbackmanager.js
@@ -2774,6 +2774,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 @@
-
-
${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 2c40109fe08..f9fa978b7d2 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';
}
/**
@@ -651,7 +651,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",