Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Changelog9.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ <h2><a name="v9.0.4" id="v9.0.4"></a>Version 9.0.4</h2>
<ul>
<li>New Features:</li>
<ul>
<li></li>
<li><a href="https://github.com/LMS-Community/slimserver/issues/1578">#1578</a> - Add opt-in "Merge contributors by name" preference to prevent duplicate album-artist browse entries when MusicBrainz IDs differ across the same display name.</li>
</ul>
<br />

Expand Down
5 changes: 5 additions & 0 deletions HTML/EN/settings/server/behavior.html
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@
<label for="pref_useTPE2AsAlbumArtist1" class="stdlabel">[% 'SETUP_USETPE2ASALBUMARTIST_1' | getstring %]</label><br/>
[% END %]

[% WRAPPER settingGroup title="SETUP_MERGECONTRIBUTORSBYNAME" desc="SETUP_MERGECONTRIBUTORSBYNAME_DESC" %]
<input type="checkbox" name="pref_mergeContributorsByName" id="pref_mergeContributorsByName" value="1" [% IF prefs.pref_mergeContributorsByName %]checked="checked"[% END %] />
<label for="pref_mergeContributorsByName" class="stdlabel">[% 'SETUP_MERGECONTRIBUTORSBYNAME_LABEL' | getstring %]</label>
[% END %]

[% WRAPPER settingGroup title="SETUP_MYCLASSICALGENRES" desc="SETUP_MYCLASSICALGENRES_DESC" %]
<input type="text" class="stdedit" name="pref_myClassicalGenres" id="myClassicalGenres" value="[% prefs.pref_myClassicalGenres | html %]" size="40" placeholder="[% "GENRES" | string | html %]"><br/>
[% END %]
Expand Down
33 changes: 31 additions & 2 deletions Slim/Schema/Contributor.pm
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,19 @@ sub add {
my $mbid = $brainzIDList[$i];
my ($id, $oldExtId, $oldMbid, $sth);

# check Musicbrainz ID first
if ($mbid) {
my $preferNameMatch = $prefs->get('mergeContributorsByName');

# Default behaviour: check Musicbrainz ID first, name fallback
# only against rows whose musicbrainz_id is NULL.
#
# When mergeContributorsByName is enabled: look up by name first
# regardless of MBID, tie-breaking by preferring rows with a
# non-null musicbrainz_id (richer data) then by id ascending
# (oldest first) for determinism. MBID lookup is the fallback.
# This is opt-in because some libraries legitimately rely on
# MBIDs to distinguish two artists who share a display name
# (e.g. John Williams the composer vs. the guitarist).
if ($mbid && !$preferNameMatch) {
$sth = $dbh->prepare_cached( 'SELECT id, extid, musicbrainz_id FROM contributors WHERE musicbrainz_id = ?' );
$sth->execute($mbid);
($id, $oldExtId, $oldMbid) = $sth->fetchrow_array;
Expand All @@ -273,6 +284,24 @@ sub add {
$sth->finish;
}
}
elsif ($preferNameMatch && $name) {
$sth = $dbh->prepare_cached(
'SELECT id, extid, musicbrainz_id FROM contributors WHERE name = ? '
. 'ORDER BY (musicbrainz_id IS NULL), id LIMIT 1'
);
$sth->execute($name);
($id, $oldExtId, $oldMbid) = $sth->fetchrow_array;
$sth->finish;

# If no name match, fall back to MBID lookup so a brand-new
# contributor doesn't get split off from an existing MBID-only row.
if ( !$id && $mbid ) {
$sth = $dbh->prepare_cached( 'SELECT id, extid, musicbrainz_id FROM contributors WHERE musicbrainz_id = ?' );
$sth->execute($mbid);
($id, $oldExtId, $oldMbid) = $sth->fetchrow_array;
$sth->finish;
}
}
else {
$sth = $dbh->prepare_cached( 'SELECT id, extid, musicbrainz_id FROM contributors WHERE name = ? LIMIT 1' );
$sth->execute($name);
Expand Down
3 changes: 2 additions & 1 deletion Slim/Utils/Prefs.pm
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ sub init {
'variousArtistAutoIdentification' => 1,
'useUnifiedArtistsList' => 0,
'useTPE2AsAlbumArtist' => 1,
'mergeContributorsByName' => 0,
'variousArtistsString' => undef,
'releaseTypesToIgnore' => [],
'ignoreReleaseTypes' => 0,
Expand Down Expand Up @@ -403,7 +404,7 @@ sub init {

$prefs->setChange(
sub { Slim::Control::Request::executeRequest(undef, ['wipecache', $prefs->get('dontTriggerScanOnPrefChange') ? 'queue' : undef]) },
qw(splitList groupdiscs useTPE2AsAlbumArtist cleanupReleaseTypes worksScan)
qw(splitList groupdiscs useTPE2AsAlbumArtist mergeContributorsByName cleanupReleaseTypes worksScan)
);

$prefs->setChange( sub {
Expand Down
2 changes: 1 addition & 1 deletion Slim/Web/Settings/Server/Behavior.pm
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ sub prefs {
ignoreReleaseTypes cleanupReleaseTypes groupArtistAlbumsByReleaseType
useTPE2AsAlbumArtist variousArtistsString ratingImplementation useUnifiedArtistsList
skipsentinel showComposerReleasesbyAlbum myClassicalGenres onlyAlbumYears
worksScan)
worksScan mergeContributorsByName)
);
}

Expand Down
9 changes: 9 additions & 0 deletions strings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20219,6 +20219,15 @@ SETUP_USETPE2ASALBUMARTIST_0
RU Поле TPE2 тега MP3 содержит группу
SV Behandla mp3-taggen TPE2 som band

SETUP_MERGECONTRIBUTORSBYNAME
EN Merge contributors by name

SETUP_MERGECONTRIBUTORSBYNAME_DESC
EN When two tracks share the same album artist display name but carry different MusicBrainz Album Artist IDs (e.g. a band credit on MusicBrainz that uses the solo artist's name string), LMS normally creates separate contributor rows — causing duplicate browse entries for the same apparent artist. Enable this option to match contributors by display name first, ignoring MBID differences, so those tracks are grouped under a single entry. Leave disabled if your library contains genuinely distinct artists who share a name and you rely on MusicBrainz IDs to keep them apart. Changing this setting will trigger a rescan.

SETUP_MERGECONTRIBUTORSBYNAME_LABEL
EN Merge album artist contributors with the same name, even when MusicBrainz IDs differ

LYRICS
CS Texty písní
DA Tekster
Expand Down