music: group artists case-insensitively [#66]
Group up album artists case-insensitively. Music files from the same artist may format the artist differently, such as being in uppercase/lowercase forms. If we have already built an artist that has a functionally identical name to another artist, then simply merge the artists instead of keeping them separate.
This commit is contained in:
parent
50a2305f63
commit
9514f17bc7
1 changed files with 24 additions and 11 deletions
|
@ -145,6 +145,7 @@ class MusicLoader {
|
||||||
val artist = cursor.getString(artistIndex).let {
|
val artist = cursor.getString(artistIndex).let {
|
||||||
if (it != MediaStore.UNKNOWN_STRING) it else null
|
if (it != MediaStore.UNKNOWN_STRING) it else null
|
||||||
}
|
}
|
||||||
|
|
||||||
val albumArtist = cursor.getStringOrNull(albumArtistIndex)
|
val albumArtist = cursor.getStringOrNull(albumArtistIndex)
|
||||||
|
|
||||||
val year = cursor.getInt(yearIndex)
|
val year = cursor.getInt(yearIndex)
|
||||||
|
@ -198,21 +199,33 @@ class MusicLoader {
|
||||||
val artists = mutableListOf<Artist>()
|
val artists = mutableListOf<Artist>()
|
||||||
val albumsByArtist = albums.groupBy { it.artistName }
|
val albumsByArtist = albums.groupBy { it.artistName }
|
||||||
|
|
||||||
albumsByArtist.forEach { entry ->
|
for (entry in albumsByArtist) {
|
||||||
val resolvedName = if (entry.key == MediaStore.UNKNOWN_STRING) {
|
val name = entry.key
|
||||||
context.getString(R.string.def_artist)
|
val resolvedName = when (name) {
|
||||||
} else {
|
MediaStore.UNKNOWN_STRING -> context.getString(R.string.def_artist)
|
||||||
entry.key
|
else -> name
|
||||||
|
}
|
||||||
|
val artistAlbums = entry.value.toMutableList()
|
||||||
|
|
||||||
|
// Music files from the same artist may format the artist differently, such as being
|
||||||
|
// in uppercase/lowercase forms. If we have already built an artist that has a
|
||||||
|
// functionally identical name to this one, then simply merge the artists instead
|
||||||
|
// of removing them.
|
||||||
|
val previousArtistIndex = artists.indexOfFirst { artist ->
|
||||||
|
artist.name.lowercase() == name.lowercase()
|
||||||
}
|
}
|
||||||
|
|
||||||
// In most cases, MediaStore artist IDs are unreliable or omitted for speed.
|
// In most cases, MediaStore artist IDs are unreliable or omitted for speed.
|
||||||
// Use the hashCode of the artist name as our ID and move on.
|
// Use the hashCode of the artist name as our ID and move on.
|
||||||
artists.add(
|
if (previousArtistIndex > -1) {
|
||||||
Artist(
|
val previousArtist = artists[previousArtistIndex]
|
||||||
entry.key.hashCode().toLong(), entry.key,
|
artists[previousArtistIndex] = Artist(
|
||||||
resolvedName, entry.value
|
previousArtist.name.hashCode().toLong(), previousArtist.name,
|
||||||
|
previousArtist.resolvedName, previousArtist.albums + artistAlbums
|
||||||
)
|
)
|
||||||
)
|
} else {
|
||||||
|
artists.add(Artist(name.hashCode().toLong(), name, resolvedName, artistAlbums))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return artists
|
return artists
|
||||||
|
@ -237,8 +250,8 @@ class MusicLoader {
|
||||||
val nameIndex = cursor.getColumnIndexOrThrow(MediaStore.Audio.Genres.NAME)
|
val nameIndex = cursor.getColumnIndexOrThrow(MediaStore.Audio.Genres.NAME)
|
||||||
|
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
// No non-broken genre would be missing a name.
|
|
||||||
val id = cursor.getLong(idIndex)
|
val id = cursor.getLong(idIndex)
|
||||||
|
// No non-broken genre would be missing a name.
|
||||||
val name = cursor.getStringOrNull(nameIndex) ?: continue
|
val name = cursor.getStringOrNull(nameIndex) ?: continue
|
||||||
val resolvedName = when (name) {
|
val resolvedName = when (name) {
|
||||||
MediaStore.UNKNOWN_STRING -> context.getString(R.string.def_genre)
|
MediaStore.UNKNOWN_STRING -> context.getString(R.string.def_genre)
|
||||||
|
|
Loading…
Reference in a new issue