music: re-add song deduplication
This commit is contained in:
parent
3bf80073f4
commit
9d9f810356
4 changed files with 42 additions and 20 deletions
|
@ -26,6 +26,7 @@ import kotlinx.coroutines.flow.flowOn
|
|||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import org.oxycblt.auxio.music.Music
|
||||
import org.oxycblt.auxio.music.stack.Indexer
|
||||
import org.oxycblt.auxio.music.stack.explore.AudioFile
|
||||
import org.oxycblt.auxio.music.stack.explore.PlaylistFile
|
||||
|
@ -42,6 +43,7 @@ import org.oxycblt.auxio.music.stack.interpret.model.MutableLibrary
|
|||
import org.oxycblt.auxio.music.stack.interpret.model.SongImpl
|
||||
import org.oxycblt.auxio.music.stack.interpret.prepare.PreSong
|
||||
import org.oxycblt.auxio.music.stack.interpret.prepare.Preparer
|
||||
import timber.log.Timber as L
|
||||
|
||||
interface Interpreter {
|
||||
suspend fun interpret(
|
||||
|
@ -88,8 +90,22 @@ class InterpreterImpl @Inject constructor(private val preparer: Preparer) : Inte
|
|||
.toList()
|
||||
val albums = albumLinker.resolve()
|
||||
|
||||
val songs = albumLinkedSongs.map { SongImpl(it) }
|
||||
return LibraryImpl(songs, albums, artists, genres)
|
||||
val uidMap = mutableMapOf<Music.UID, SongImpl>()
|
||||
val songs = albumLinkedSongs.mapNotNull {
|
||||
val uid = it.preSong.computeUid()
|
||||
val other = uidMap[uid]
|
||||
if (other == null) {
|
||||
SongImpl(it)
|
||||
} else {
|
||||
L.d("Song @ $uid already exists at ${other.path}, ignoring")
|
||||
null
|
||||
}
|
||||
}
|
||||
return LibraryImpl(
|
||||
songs,
|
||||
albums.onEach { it.finalize() },
|
||||
artists.onEach { it.finalize() },
|
||||
genres.onEach { it.finalize() })
|
||||
}
|
||||
|
||||
private data class LinkedSongImpl(private val albumLinkedSong: AlbumLinker.LinkedSong) :
|
||||
|
|
|
@ -43,23 +43,7 @@ import org.oxycblt.auxio.util.update
|
|||
class SongImpl(linkedSong: LinkedSong) : Song {
|
||||
private val preSong = linkedSong.preSong
|
||||
|
||||
override val uid =
|
||||
// Attempt to use a MusicBrainz ID first before falling back to a hashed UID.
|
||||
preSong.musicBrainzId?.let { Music.UID.musicBrainz(MusicType.SONGS, it) }
|
||||
?: Music.UID.auxio(MusicType.SONGS) {
|
||||
// Song UIDs are based on the raw data without parsing so that they remain
|
||||
// consistent across music setting changes. Parents are not held up to the
|
||||
// same standard since grouping is already inherently linked to settings.
|
||||
update(preSong.rawName)
|
||||
update(preSong.preAlbum.rawName)
|
||||
update(preSong.date)
|
||||
|
||||
update(preSong.track)
|
||||
update(preSong.disc?.number)
|
||||
|
||||
update(preSong.preArtists.map { it.rawName })
|
||||
update(preSong.preAlbum.preArtists.map { it.rawName })
|
||||
}
|
||||
override val uid = preSong.computeUid()
|
||||
override val name = preSong.name
|
||||
override val track = preSong.track
|
||||
override val disc = preSong.disc
|
||||
|
|
|
@ -47,6 +47,8 @@ class LibraryImpl(
|
|||
) : MutableLibrary {
|
||||
override val playlists = emptySet<Playlist>()
|
||||
|
||||
private val songUidMap = songs.associ { it.uid }
|
||||
|
||||
override fun findSong(uid: Music.UID): Song? {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@ package org.oxycblt.auxio.music.stack.interpret.prepare
|
|||
import android.net.Uri
|
||||
import java.util.UUID
|
||||
import org.oxycblt.auxio.image.extractor.Cover
|
||||
import org.oxycblt.auxio.music.Music
|
||||
import org.oxycblt.auxio.music.MusicType
|
||||
import org.oxycblt.auxio.music.info.Date
|
||||
import org.oxycblt.auxio.music.info.Disc
|
||||
import org.oxycblt.auxio.music.info.Name
|
||||
|
@ -29,6 +31,7 @@ import org.oxycblt.auxio.music.stack.explore.PlaylistHandle
|
|||
import org.oxycblt.auxio.music.stack.explore.fs.MimeType
|
||||
import org.oxycblt.auxio.music.stack.explore.fs.Path
|
||||
import org.oxycblt.auxio.playback.replaygain.ReplayGainAdjustment
|
||||
import org.oxycblt.auxio.util.update
|
||||
|
||||
data class PreSong(
|
||||
val musicBrainzId: UUID?,
|
||||
|
@ -48,7 +51,24 @@ data class PreSong(
|
|||
val preAlbum: PreAlbum,
|
||||
val preArtists: List<PreArtist>,
|
||||
val preGenres: List<PreGenre>
|
||||
)
|
||||
) {
|
||||
fun computeUid() =
|
||||
musicBrainzId?.let { Music.UID.musicBrainz(MusicType.SONGS, it) }
|
||||
?: Music.UID.auxio(MusicType.SONGS) {
|
||||
// Song UIDs are based on the raw data without parsing so that they remain
|
||||
// consistent across music setting changes. Parents are not held up to the
|
||||
// same standard since grouping is already inherently linked to settings.
|
||||
update(rawName)
|
||||
update(preAlbum.rawName)
|
||||
update(date)
|
||||
|
||||
update(track)
|
||||
update(disc?.number)
|
||||
|
||||
update(preArtists.map { artist -> artist.rawName })
|
||||
update(preAlbum.preArtists.map { artist -> artist.rawName })
|
||||
}
|
||||
}
|
||||
|
||||
data class PreAlbum(
|
||||
val musicBrainzId: UUID?,
|
||||
|
|
Loading…
Reference in a new issue