diff --git a/app/src/main/java/org/oxycblt/auxio/image/coil/Components.kt b/app/src/main/java/org/oxycblt/auxio/image/coil/Components.kt index 0eea209b8..12d69d87a 100644 --- a/app/src/main/java/org/oxycblt/auxio/image/coil/Components.kt +++ b/app/src/main/java/org/oxycblt/auxio/image/coil/Components.kt @@ -44,7 +44,6 @@ import okio.FileSystem import okio.buffer import okio.source import org.oxycblt.musikr.cover.Cover -import org.oxycblt.musikr.cover.StoredCovers class CoverKeyer @Inject constructor() : Keyer { override fun key(data: Cover, options: Options) = "${data.id}&${options.size}" diff --git a/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt b/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt index 65bd954a4..8f4f6f2f3 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt @@ -39,7 +39,6 @@ import org.oxycblt.musikr.Song import org.oxycblt.musikr.Storage import org.oxycblt.musikr.cache.Cache import org.oxycblt.musikr.cache.CacheDatabase -import org.oxycblt.musikr.cover.StoredCovers import org.oxycblt.musikr.playlist.db.PlaylistDatabase import org.oxycblt.musikr.playlist.db.StoredPlaylists import org.oxycblt.musikr.tag.interpret.Naming diff --git a/app/src/main/java/org/oxycblt/auxio/music/RevisionedLibrary.kt b/app/src/main/java/org/oxycblt/auxio/music/RevisionedLibrary.kt index a3e9f46eb..0c425959e 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/RevisionedLibrary.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/RevisionedLibrary.kt @@ -15,21 +15,19 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package org.oxycblt.auxio.music import android.content.Context import androidx.media3.common.util.Log -import org.oxycblt.auxio.util.unlikelyToBeNull import java.util.UUID +import org.oxycblt.auxio.util.unlikelyToBeNull import org.oxycblt.musikr.cover.Cover import org.oxycblt.musikr.cover.MutableStoredCovers import org.oxycblt.musikr.cover.StoredCovers -open class RevisionedStoredCovers( - private val context: Context, - private val revision: UUID? -) : StoredCovers { +open class RevisionedStoredCovers(private val context: Context, private val revision: UUID?) : + StoredCovers { protected val inner = revision?.let { StoredCovers.at(context, "covers_$it") } override suspend fun obtain(id: String): RevisionedCover? { @@ -51,10 +49,8 @@ open class RevisionedStoredCovers( } } -class MutableRevisionedStoredCovers( - context: Context, - private val revision: UUID -) : RevisionedStoredCovers(context, revision), MutableStoredCovers { +class MutableRevisionedStoredCovers(context: Context, private val revision: UUID) : + RevisionedStoredCovers(context, revision), MutableStoredCovers { override suspend fun write(data: ByteArray): RevisionedCover? { return unlikelyToBeNull(inner).write(data)?.let { RevisionedCover(revision, it) } } diff --git a/musikr/src/main/java/org/oxycblt/musikr/Config.kt b/musikr/src/main/java/org/oxycblt/musikr/Config.kt index a428157e1..22ec833dd 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/Config.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/Config.kt @@ -20,7 +20,6 @@ package org.oxycblt.musikr import org.oxycblt.musikr.cache.Cache import org.oxycblt.musikr.cover.MutableStoredCovers -import org.oxycblt.musikr.cover.StoredCovers import org.oxycblt.musikr.playlist.db.StoredPlaylists import org.oxycblt.musikr.tag.interpret.Naming import org.oxycblt.musikr.tag.interpret.Separators diff --git a/musikr/src/main/java/org/oxycblt/musikr/cache/CacheDatabase.kt b/musikr/src/main/java/org/oxycblt/musikr/cache/CacheDatabase.kt index 76be6bd87..0fdba1c18 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/cache/CacheDatabase.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/cache/CacheDatabase.kt @@ -30,7 +30,6 @@ import androidx.room.Room import androidx.room.RoomDatabase import androidx.room.TypeConverter import androidx.room.TypeConverters -import org.oxycblt.musikr.cover.Cover import org.oxycblt.musikr.cover.StoredCovers import org.oxycblt.musikr.fs.DeviceFile import org.oxycblt.musikr.metadata.Properties diff --git a/musikr/src/main/java/org/oxycblt/musikr/cover/Cover.kt b/musikr/src/main/java/org/oxycblt/musikr/cover/Cover.kt index 5f7376ec2..4344f5787 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/cover/Cover.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/cover/Cover.kt @@ -18,8 +18,8 @@ package org.oxycblt.musikr.cover -import org.oxycblt.musikr.Song import java.io.InputStream +import org.oxycblt.musikr.Song sealed interface Cover { val id: String diff --git a/musikr/src/main/java/org/oxycblt/musikr/cover/CoverFiles.kt b/musikr/src/main/java/org/oxycblt/musikr/cover/CoverFiles.kt index 5a3f99569..73982e4ad 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/cover/CoverFiles.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/cover/CoverFiles.kt @@ -15,22 +15,21 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package org.oxycblt.musikr.cover import android.content.Context -import android.util.Log import java.io.File import java.io.IOException +import java.io.InputStream import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withContext -import java.io.InputStream -import java.io.OutputStream interface CoverFiles { suspend fun find(id: String): CoverFile? + suspend fun write(id: String, data: ByteArray): CoverFile? companion object { @@ -91,4 +90,4 @@ private class CoverFilesImpl(private val dir: File, private val coverFormat: Cov private class CoverFileImpl(private val file: File) : CoverFile { override suspend fun open() = withContext(Dispatchers.IO) { file.inputStream() } -} \ No newline at end of file +} diff --git a/musikr/src/main/java/org/oxycblt/musikr/cover/CoverFormat.kt b/musikr/src/main/java/org/oxycblt/musikr/cover/CoverFormat.kt index 3ff9dba06..c7b23967b 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/cover/CoverFormat.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/cover/CoverFormat.kt @@ -15,12 +15,11 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package org.oxycblt.musikr.cover import android.graphics.Bitmap import android.graphics.BitmapFactory -import android.os.Build import java.io.OutputStream internal interface CoverFormat { @@ -31,23 +30,18 @@ internal interface CoverFormat { companion object { // Enable if perhaps you want to try other formats. // Currently this is just far too slow. -// fun webp(): CoverFormat = CoverFormatImpl( -// "webp", -// 750, -// 80, -// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { -// Bitmap.CompressFormat.WEBP_LOSSY -// } else { -// Bitmap.CompressFormat.WEBP -// } -// ) + // fun webp(): CoverFormat = CoverFormatImpl( + // "webp", + // 750, + // 80, + // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + // Bitmap.CompressFormat.WEBP_LOSSY + // } else { + // Bitmap.CompressFormat.WEBP + // } + // ) - fun jpeg(): CoverFormat = CoverFormatImpl( - "jpg", - 1000, - 100, - Bitmap.CompressFormat.JPEG - ) + fun jpeg(): CoverFormat = CoverFormatImpl("jpg", 1000, 100, Bitmap.CompressFormat.JPEG) } } diff --git a/musikr/src/main/java/org/oxycblt/musikr/cover/StoredCovers.kt b/musikr/src/main/java/org/oxycblt/musikr/cover/StoredCovers.kt index f5fc31ab7..fb5140e2f 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/cover/StoredCovers.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/cover/StoredCovers.kt @@ -15,20 +15,17 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package org.oxycblt.musikr.cover import android.content.Context -import java.io.InputStream interface StoredCovers { suspend fun obtain(id: String): Cover.Single? companion object { fun at(context: Context, path: String): MutableStoredCovers = - FileStoredCovers( - CoverIdentifier.md5(), CoverFiles.at(context, path) - ) + FileStoredCovers(CoverIdentifier.md5(), CoverFiles.at(context, path)) } } @@ -48,9 +45,6 @@ private class FileStoredCovers( } } -private class FileCover( - override val id: String, - private val coverFile: CoverFile -) : Cover.Single { +private class FileCover(override val id: String, private val coverFile: CoverFile) : Cover.Single { override suspend fun open() = coverFile.open() -} \ No newline at end of file +} diff --git a/musikr/src/main/java/org/oxycblt/musikr/pipeline/EvaluateStep.kt b/musikr/src/main/java/org/oxycblt/musikr/pipeline/EvaluateStep.kt index ac4123031..785f10d9d 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/pipeline/EvaluateStep.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/pipeline/EvaluateStep.kt @@ -82,7 +82,7 @@ private class EvaluateStepImpl( preSongs.onEach { Log.d("EvaluateStep", it.toString()) wrap(it, graphBuilder::add) - }, + }, prePlaylists.onEach { wrap(it, graphBuilder::add) }) graphBuild.collect() val graph = graphBuilder.build() diff --git a/musikr/src/main/java/org/oxycblt/musikr/pipeline/ExtractStep.kt b/musikr/src/main/java/org/oxycblt/musikr/pipeline/ExtractStep.kt index f9921d7c2..2b1e85c2f 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/pipeline/ExtractStep.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/pipeline/ExtractStep.kt @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package org.oxycblt.musikr.pipeline import android.content.Context @@ -23,7 +23,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.buffer -import kotlinx.coroutines.flow.flatMapMerge import kotlinx.coroutines.flow.flattenMerge import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map @@ -35,7 +34,6 @@ import org.oxycblt.musikr.cache.Cache import org.oxycblt.musikr.cache.CacheResult import org.oxycblt.musikr.cover.Cover import org.oxycblt.musikr.cover.MutableStoredCovers -import org.oxycblt.musikr.cover.StoredCovers import org.oxycblt.musikr.fs.DeviceFile import org.oxycblt.musikr.metadata.MetadataExtractor import org.oxycblt.musikr.metadata.Properties @@ -53,8 +51,7 @@ internal interface ExtractStep { MetadataExtractor.from(context), TagParser.new(), storage.cache, - storage.storedCovers - ) + storage.storedCovers) } } @@ -80,9 +77,8 @@ private class ExtractStepImpl( val cacheResults = distributedAudioNodes.flows .map { flow -> - flow.map { - wrap(it) { file -> cache.read(file, storedCovers) } - } + flow + .map { wrap(it) { file -> cache.read(file, storedCovers) } } .flowOn(Dispatchers.IO) .buffer(Channel.UNLIMITED) } @@ -114,13 +110,13 @@ private class ExtractStepImpl( val metadata = fds.mapNotNull { fileWith -> - wrap(fileWith.file) { _ -> - metadataExtractor - .extract(fileWith.with) - ?.let { FileWith(fileWith.file, it) } - .also { withContext(Dispatchers.IO) { fileWith.with.close() } } + wrap(fileWith.file) { _ -> + metadataExtractor + .extract(fileWith.with) + ?.let { FileWith(fileWith.file, it) } + .also { withContext(Dispatchers.IO) { fileWith.with.close() } } + } } - } .flowOn(Dispatchers.IO) // Covers are pretty big, so cap the amount of parsed metadata in-memory to at most // 8 to minimize GCs. @@ -150,8 +146,7 @@ private class ExtractStepImpl( cacheFlow.manager, cachedSongs, writtenSongs, - playlistNodes - ) + playlistNodes) } private data class FileWith(val file: DeviceFile, val with: T) diff --git a/musikr/src/main/java/org/oxycblt/musikr/pipeline/FlowUtil.kt b/musikr/src/main/java/org/oxycblt/musikr/pipeline/FlowUtil.kt index c45b083f9..58f2c6eb0 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/pipeline/FlowUtil.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/pipeline/FlowUtil.kt @@ -21,11 +21,9 @@ package org.oxycblt.musikr.pipeline import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.asFlow -import kotlinx.coroutines.flow.emitAll import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.receiveAsFlow -import kotlinx.coroutines.flow.toList import kotlinx.coroutines.flow.withIndex internal sealed interface Divert {