Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Album gain #4741

Merged
merged 15 commits into from
Oct 18, 2023
6 changes: 6 additions & 0 deletions src/components/playback/playbackmanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions src/components/playbackSettings/playbackSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
13 changes: 7 additions & 6 deletions src/components/playbackSettings/playbackSettings.template.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,13 @@ <h2 class="sectionTitle">
${TabAdvanced}
</h2>

<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input type="checkbox" is="emby-checkbox" class="chkEnableAudioNormalization" />
<span>${EnableAudioNormalization}</span>
</label>
<div class="fieldDescription checkboxFieldDescription">${EnableAudioNormalizationHelp}</div>
<div class="selectContainer">
<select is="emby-select" id="selectAudioNormalization" label="${LabelSelectAudioNormalization}">
<option value="Off">${Off}</option>
<option value="TrackGain">${LabelTrackGain}</option>
<option value="AlbumGain">${LabelAlbumGain}</option>
</select>
<div class="fieldDescription">${SelectAudioNormalizationHelp}</div>
</div>

<div class="checkboxContainer checkboxContainer-withDescription">
Expand Down
7 changes: 6 additions & 1 deletion src/plugins/htmlAudioPlayer/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
12 changes: 6 additions & 6 deletions src/scripts/settings/userSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
}

/**
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 4 additions & 2 deletions src/strings/en-us.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand All @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
Loading