1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

Merge pull request #5869 from gnattu/custom-audio-tag

Add non-standard multi-value audio tag support
This commit is contained in:
Bill Thornton 2024-09-23 12:31:01 -04:00 committed by GitHub
commit a2676c25ce
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 46 additions and 0 deletions

View file

@ -12,6 +12,7 @@ import dom from '../../scripts/dom';
import '../../elements/emby-checkbox/emby-checkbox'; import '../../elements/emby-checkbox/emby-checkbox';
import '../../elements/emby-select/emby-select'; import '../../elements/emby-select/emby-select';
import '../../elements/emby-input/emby-input'; import '../../elements/emby-input/emby-input';
import '../../elements/emby-textarea/emby-textarea';
import './style.scss'; import './style.scss';
import template from './libraryoptionseditor.template.html'; import template from './libraryoptionseditor.template.html';
@ -473,8 +474,10 @@ export function setContentType(parent, contentType) {
if (contentType === 'music') { if (contentType === 'music') {
parent.querySelector('.lyricSettingsSection').classList.remove('hide'); parent.querySelector('.lyricSettingsSection').classList.remove('hide');
parent.querySelector('.audioTagSettingsSection').classList.remove('hide');
} else { } else {
parent.querySelector('.lyricSettingsSection').classList.add('hide'); parent.querySelector('.lyricSettingsSection').classList.add('hide');
parent.querySelector('.audioTagSettingsSection').classList.add('hide');
} }
parent.querySelector('.chkAutomaticallyAddToCollectionContainer').classList.toggle('hide', contentType !== 'movies' && contentType !== 'mixed'); parent.querySelector('.chkAutomaticallyAddToCollectionContainer').classList.toggle('hide', contentType !== 'movies' && contentType !== 'mixed');
@ -597,6 +600,8 @@ export function getLibraryOptions(parent) {
SaveLyricsWithMedia: parent.querySelector('#chkSaveLyricsLocally').checked, SaveLyricsWithMedia: parent.querySelector('#chkSaveLyricsLocally').checked,
RequirePerfectSubtitleMatch: parent.querySelector('#chkRequirePerfectMatch').checked, RequirePerfectSubtitleMatch: parent.querySelector('#chkRequirePerfectMatch').checked,
AutomaticallyAddToCollection: parent.querySelector('#chkAutomaticallyAddToCollection').checked, AutomaticallyAddToCollection: parent.querySelector('#chkAutomaticallyAddToCollection').checked,
PreferNonstandardArtistsTag: parent.querySelector('#chkPreferNonstandardArtistsTag').checked,
UseCustomTagDelimiters: parent.querySelector('#chkUseCustomTagDelimiters').checked,
MetadataSavers: Array.prototype.map.call(Array.prototype.filter.call(parent.querySelectorAll('.chkMetadataSaver'), elem => { MetadataSavers: Array.prototype.map.call(Array.prototype.filter.call(parent.querySelectorAll('.chkMetadataSaver'), elem => {
return elem.checked; return elem.checked;
}), elem => { }), elem => {
@ -613,6 +618,8 @@ export function getLibraryOptions(parent) {
}), elem => { }), elem => {
return elem.getAttribute('data-lang'); return elem.getAttribute('data-lang');
}); });
options.CustomTagDelimiters = parent.querySelector('#customTagDelimitersInput').value.split('');
options.DelimiterWhitelist = parent.querySelector('#tagDelimiterWhitelist').value.split('\n').filter(item => item.trim());
setSubtitleFetchersIntoOptions(parent, options); setSubtitleFetchersIntoOptions(parent, options);
setLyricFetchersIntoOptions(parent, options); setLyricFetchersIntoOptions(parent, options);
setMetadataFetchersIntoOptions(parent, options); setMetadataFetchersIntoOptions(parent, options);
@ -661,12 +668,16 @@ export function setLibraryOptions(parent, options) {
parent.querySelector('#chkSkipIfAudioTrackPresent').checked = options.SkipSubtitlesIfAudioTrackMatches; parent.querySelector('#chkSkipIfAudioTrackPresent').checked = options.SkipSubtitlesIfAudioTrackMatches;
parent.querySelector('#chkRequirePerfectMatch').checked = options.RequirePerfectSubtitleMatch; parent.querySelector('#chkRequirePerfectMatch').checked = options.RequirePerfectSubtitleMatch;
parent.querySelector('#chkAutomaticallyAddToCollection').checked = options.AutomaticallyAddToCollection; parent.querySelector('#chkAutomaticallyAddToCollection').checked = options.AutomaticallyAddToCollection;
parent.querySelector('#chkPreferNonstandardArtistsTag').checked = options.PreferNonstandardArtistsTag;
parent.querySelector('#chkUseCustomTagDelimiters').checked = options.UseCustomTagDelimiters;
Array.prototype.forEach.call(parent.querySelectorAll('.chkMetadataSaver'), elem => { Array.prototype.forEach.call(parent.querySelectorAll('.chkMetadataSaver'), elem => {
elem.checked = options.MetadataSavers ? options.MetadataSavers.includes(elem.getAttribute('data-pluginname')) : elem.getAttribute('data-defaultenabled') === 'true'; elem.checked = options.MetadataSavers ? options.MetadataSavers.includes(elem.getAttribute('data-pluginname')) : elem.getAttribute('data-defaultenabled') === 'true';
}); });
Array.prototype.forEach.call(parent.querySelectorAll('.chkSubtitleLanguage'), elem => { Array.prototype.forEach.call(parent.querySelectorAll('.chkSubtitleLanguage'), elem => {
elem.checked = !!options.SubtitleDownloadLanguages && options.SubtitleDownloadLanguages.includes(elem.getAttribute('data-lang')); elem.checked = !!options.SubtitleDownloadLanguages && options.SubtitleDownloadLanguages.includes(elem.getAttribute('data-lang'));
}); });
parent.querySelector('#customTagDelimitersInput').value = options.CustomTagDelimiters.join('');
parent.querySelector('#tagDelimiterWhitelist').value = options.DelimiterWhitelist.filter(item => item.trim()).join('\n');
renderMetadataReaders(parent, getOrderedPlugins(parent.availableOptions.MetadataReaders, options.LocalMetadataReaderOrder || [])); renderMetadataReaders(parent, getOrderedPlugins(parent.availableOptions.MetadataReaders, options.LocalMetadataReaderOrder || []));
renderMetadataFetchers(parent, parent.availableOptions, options); renderMetadataFetchers(parent, parent.availableOptions, options);
renderImageFetchers(parent, parent.availableOptions, options); renderImageFetchers(parent, parent.availableOptions, options);

View file

@ -216,3 +216,29 @@
<div class="fieldDescription checkboxFieldDescription">${SaveLyricsIntoMediaFoldersHelp}</div> <div class="fieldDescription checkboxFieldDescription">${SaveLyricsIntoMediaFoldersHelp}</div>
</div> </div>
</div> </div>
<div class="audioTagSettingsSection hide">
<h2>${LabelAudioTagSettings}</h2>
<div class="checkboxContainer checkboxContainer-withDescription advanced">
<label>
<input type="checkbox" is="emby-checkbox" id="chkPreferNonstandardArtistsTag" />
<span>${PreferNonStandardArtistsTag}</span>
</label>
<div class="fieldDescription checkboxFieldDescription">${PreferNonstandardArtistsTagHelp}</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription advanced">
<label>
<input type="checkbox" is="emby-checkbox" id="chkUseCustomTagDelimiters" />
<span>${UseCustomTagDelimiters}</span>
</label>
<div class="fieldDescription checkboxFieldDescription">${UseCustomTagDelimitersHelp}</div>
</div>
<div class="inputContainer">
<input type="text" is="emby-input" id="customTagDelimitersInput" label="${LabelCustomTagDelimiters}" value="/|;\"/>
<div class="fieldDescription">${LabelCustomTagDelimitersHelp}</div>
</div>
<div class="inputContainer">
<textarea is="emby-textarea" id="tagDelimiterWhitelist" label="${LabelDelimiterWhitelist}" class="textarea-mono" style="resize: none;min-height:2.5em"></textarea>
<div class="fieldDescription">${LabelDelimiterWhitelistHelp}</div>
</div>
</div>

View file

@ -584,6 +584,7 @@
"LabelAudioChannels": "Audio channels", "LabelAudioChannels": "Audio channels",
"LabelAudioCodec": "Audio codec", "LabelAudioCodec": "Audio codec",
"LabelAudioLanguagePreference": "Preferred audio language", "LabelAudioLanguagePreference": "Preferred audio language",
"LabelAudioTagSettings": "Audio Tag settings",
"LabelSelectAudioNormalization": "Audio Normalization", "LabelSelectAudioNormalization": "Audio Normalization",
"LabelSelectPreferredTranscodeVideoAudioCodec": "Preferred transcode audio codec in video playback", "LabelSelectPreferredTranscodeVideoAudioCodec": "Preferred transcode audio codec in video playback",
"LabelAudioSampleRate": "Audio sample rate", "LabelAudioSampleRate": "Audio sample rate",
@ -634,6 +635,8 @@
"LabelCustomCssHelp": "Apply your custom CSS code for theming/branding on the web interface.", "LabelCustomCssHelp": "Apply your custom CSS code for theming/branding on the web interface.",
"LabelCustomDeviceDisplayNameHelp": "Supply a custom display name or leave empty to use the name reported by the device.", "LabelCustomDeviceDisplayNameHelp": "Supply a custom display name or leave empty to use the name reported by the device.",
"LabelCustomRating": "Custom rating", "LabelCustomRating": "Custom rating",
"LabelCustomTagDelimiters": "Custom Tag Delimiter",
"LabelCustomTagDelimitersHelp": "Characters to be treated as delimiters to separate tags.",
"LabelDashboardTheme": "Server Dashboard theme", "LabelDashboardTheme": "Server Dashboard theme",
"LabelDate": "Date", "LabelDate": "Date",
"LabelDateAdded": "Date added", "LabelDateAdded": "Date added",
@ -644,6 +647,8 @@
"LabelDeathDate": "Death date", "LabelDeathDate": "Death date",
"LabelDefaultScreen": "Default screen", "LabelDefaultScreen": "Default screen",
"LabelDeinterlaceMethod": "Deinterlacing method", "LabelDeinterlaceMethod": "Deinterlacing method",
"LabelDelimiterWhitelist": "Delimiter Whitelist",
"LabelDelimiterWhitelistHelp": "Items to be excluded from tag splitting. One item per line.",
"LabelDeveloper": "Developer", "LabelDeveloper": "Developer",
"LabelDisableCustomCss": "Disable custom CSS code for theming/branding provided from the server.", "LabelDisableCustomCss": "Disable custom CSS code for theming/branding provided from the server.",
"LabelDisableVbrAudioEncoding": "Disable VBR audio encoding", "LabelDisableVbrAudioEncoding": "Disable VBR audio encoding",
@ -1335,6 +1340,8 @@
"PreferEmbeddedExtrasTitlesOverFileNamesHelp": "Extras often have the same embedded name as the parent, check this to use embedded titles for them anyway.", "PreferEmbeddedExtrasTitlesOverFileNamesHelp": "Extras often have the same embedded name as the parent, check this to use embedded titles for them anyway.",
"PreferEmbeddedTitlesOverFileNames": "Prefer embedded titles over filenames", "PreferEmbeddedTitlesOverFileNames": "Prefer embedded titles over filenames",
"PreferEmbeddedTitlesOverFileNamesHelp": "Determine the display title to use when no internet metadata or local metadata is available.", "PreferEmbeddedTitlesOverFileNamesHelp": "Determine the display title to use when no internet metadata or local metadata is available.",
"PreferNonstandardArtistsTag": "Prefer ARTISTS tag if available",
"PreferNonstandardArtistsTagHelp": "Use the non-standard ARTISTS tag instead of ARTIST tag when available.",
"AllowEmbeddedSubtitles": "Disable different types of embedded subtitles", "AllowEmbeddedSubtitles": "Disable different types of embedded subtitles",
"AllowEmbeddedSubtitlesHelp": "Disable subtitles that are packaged within media containers. Requires a full library refresh.", "AllowEmbeddedSubtitlesHelp": "Disable subtitles that are packaged within media containers. Requires a full library refresh.",
"AllowEmbeddedSubtitlesAllowAllOption": "Allow All", "AllowEmbeddedSubtitlesAllowAllOption": "Allow All",
@ -1569,6 +1576,8 @@
"UnsupportedPlayback": "Jellyfin cannot decrypt content protected by DRM but all content will be tried regardless, including protected titles. Some files may appear completely black due to encryption or other unsupported features, such as interactive titles.", "UnsupportedPlayback": "Jellyfin cannot decrypt content protected by DRM but all content will be tried regardless, including protected titles. Some files may appear completely black due to encryption or other unsupported features, such as interactive titles.",
"Up": "Up", "Up": "Up",
"Upload": "Upload", "Upload": "Upload",
"UseCustomTagDelimiters": "Use custom tag delimiter",
"UseCustomTagDelimitersHelp": "Split artist/genre tags with custom characters.",
"UseDoubleRateDeinterlacing": "Double the frame rate when deinterlacing", "UseDoubleRateDeinterlacing": "Double the frame rate when deinterlacing",
"UseDoubleRateDeinterlacingHelp": "This setting uses the field rate when deinterlacing, often referred to as bob deinterlacing, which doubles the frame rate of the video to provide full motion like what you would see when viewing interlaced video on a TV.", "UseDoubleRateDeinterlacingHelp": "This setting uses the field rate when deinterlacing, often referred to as bob deinterlacing, which doubles the frame rate of the video to provide full motion like what you would see when viewing interlaced video on a TV.",
"UseEpisodeImagesInNextUp": "Use episode images in 'Next Up' and 'Continue Watching' sections", "UseEpisodeImagesInNextUp": "Use episode images in 'Next Up' and 'Continue Watching' sections",