From 0ddd49fd10d9252a33b5596273cf3949cd8a5750 Mon Sep 17 00:00:00 2001 From: vfsfitvnm Date: Tue, 12 Jul 2022 22:09:25 +0200 Subject: [PATCH] Improve cache settings --- .../it/vfsfitvnm/vimusic/MainApplication.kt | 2 +- .../vimusic/enums/CoilDiskCacheSize.kt | 19 +++ .../enums/ExoPlayerDiskCacheMaxSize.kt | 21 +++ .../vimusic/service/PlayerService.kt | 8 +- .../vimusic/ui/components/SeekBar.kt | 1 + .../screens/settings/CacheSettingsScreen.kt | 122 +++++------------- .../it/vfsfitvnm/vimusic/utils/Preferences.kt | 20 +-- 7 files changed, 92 insertions(+), 101 deletions(-) create mode 100644 app/src/main/kotlin/it/vfsfitvnm/vimusic/enums/CoilDiskCacheSize.kt create mode 100644 app/src/main/kotlin/it/vfsfitvnm/vimusic/enums/ExoPlayerDiskCacheMaxSize.kt diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/MainApplication.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/MainApplication.kt index 7488daf..17f3247 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/MainApplication.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/MainApplication.kt @@ -19,7 +19,7 @@ class MainApplication : Application(), ImageLoaderFactory { .diskCache( DiskCache.Builder() .directory(filesDir.resolve("coil")) - .maxSizeBytes(Preferences().coilDiskCacheMaxSizeBytes) + .maxSizeBytes(Preferences().coilDiskCacheMaxSize.bytes) .build() ) .build() diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/enums/CoilDiskCacheSize.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/enums/CoilDiskCacheSize.kt new file mode 100644 index 0000000..66c67f3 --- /dev/null +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/enums/CoilDiskCacheSize.kt @@ -0,0 +1,19 @@ +package it.vfsfitvnm.vimusic.enums + + +enum class CoilDiskCacheMaxSize { + `128MB`, + `256MB`, + `512MB`, + `1GB`, + `2GB`; + + val bytes: Long + get() = when (this) { + `128MB` -> 128 + `256MB` -> 256 + `512MB` -> 512 + `1GB` -> 1024 + `2GB` -> 2048 + } * 1000 * 1000L +} diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/enums/ExoPlayerDiskCacheMaxSize.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/enums/ExoPlayerDiskCacheMaxSize.kt new file mode 100644 index 0000000..2803f58 --- /dev/null +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/enums/ExoPlayerDiskCacheMaxSize.kt @@ -0,0 +1,21 @@ +package it.vfsfitvnm.vimusic.enums + + +enum class ExoPlayerDiskCacheMaxSize { + `512MB`, + `1GB`, + `2GB`, + `4GB`, + `8GB`, + Unlimited; + + val bytes: Long + get() = when (this) { + `512MB` -> 512 + `1GB` -> 1024 + `2GB` -> 2048 + `4GB` -> 4096 + `8GB` -> 8192 + Unlimited -> 0 + } * 1000 * 1000L +} diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/service/PlayerService.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/service/PlayerService.kt index 005da7f..1134a48 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/service/PlayerService.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/service/PlayerService.kt @@ -25,6 +25,7 @@ import androidx.media3.datasource.ResolvingDataSource import androidx.media3.datasource.cache.Cache import androidx.media3.datasource.cache.CacheDataSource import androidx.media3.datasource.cache.LeastRecentlyUsedCacheEvictor +import androidx.media3.datasource.cache.NoOpCacheEvictor import androidx.media3.datasource.cache.SimpleCache import androidx.media3.exoplayer.ExoPlayer import androidx.media3.exoplayer.RenderersFactory @@ -41,6 +42,7 @@ import androidx.media3.extractor.mkv.MatroskaExtractor import it.vfsfitvnm.vimusic.Database import it.vfsfitvnm.vimusic.MainActivity import it.vfsfitvnm.vimusic.R +import it.vfsfitvnm.vimusic.enums.ExoPlayerDiskCacheMaxSize import it.vfsfitvnm.vimusic.models.QueuedMediaItem import it.vfsfitvnm.vimusic.query import it.vfsfitvnm.vimusic.utils.* @@ -124,7 +126,11 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene isVolumeNormalizationEnabled = preferences.volumeNormalization isInvincibilityEnabled = preferences.isInvincibilityEnabled - val cacheEvictor = LeastRecentlyUsedCacheEvictor(preferences.exoPlayerDiskCacheMaxSizeBytes) + val cacheEvictor = when (val size = preferences.exoPlayerDiskCacheMaxSize) { + ExoPlayerDiskCacheMaxSize.Unlimited -> NoOpCacheEvictor() + else -> LeastRecentlyUsedCacheEvictor(size.bytes) + } + cache = SimpleCache(cacheDir, cacheEvictor, StandaloneDatabaseProvider(this)) player = ExoPlayer.Builder(this, createRendersFactory(), createMediaSourceFactory()) diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/SeekBar.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/SeekBar.kt index cfeec74..c78fd72 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/SeekBar.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/SeekBar.kt @@ -16,6 +16,7 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import kotlin.math.roundToLong + @Composable fun SeekBar( value: Long, diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/CacheSettingsScreen.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/CacheSettingsScreen.kt index 41a65cc..8525f51 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/CacheSettingsScreen.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/CacheSettingsScreen.kt @@ -4,7 +4,6 @@ import android.text.format.Formatter import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.foundation.* import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicText import androidx.compose.runtime.* import androidx.compose.ui.Modifier @@ -17,14 +16,13 @@ import coil.annotation.ExperimentalCoilApi import it.vfsfitvnm.route.RouteHandler import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder import it.vfsfitvnm.vimusic.R -import it.vfsfitvnm.vimusic.ui.components.SeekBar +import it.vfsfitvnm.vimusic.enums.ExoPlayerDiskCacheMaxSize import it.vfsfitvnm.vimusic.ui.components.TopAppBar import it.vfsfitvnm.vimusic.ui.components.themed.TextCard import it.vfsfitvnm.vimusic.ui.screens.* import it.vfsfitvnm.vimusic.ui.styling.LocalColorPalette import it.vfsfitvnm.vimusic.ui.styling.LocalTypography import it.vfsfitvnm.vimusic.utils.LocalPreferences -import it.vfsfitvnm.vimusic.utils.secondary import it.vfsfitvnm.vimusic.utils.semiBold import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -98,54 +96,28 @@ fun CacheSettingsScreen() { mutableStateOf(diskCache.size) } - var scrubbingDiskCacheMaxSize by remember { - mutableStateOf(null) - } - SettingsEntryGroupText(title = "IMAGE CACHE") - Column( - modifier = Modifier - .padding(start = 24.dp) - .padding(horizontal = 32.dp, vertical = 16.dp) - .fillMaxWidth() - ) { - BasicText( - text = "Max size", - style = typography.xs.semiBold, - ) - - BasicText( - text = Formatter.formatShortFileSize(context, scrubbingDiskCacheMaxSize ?: preferences.coilDiskCacheMaxSizeBytes), - style = typography.xs.semiBold.secondary - ) - - SeekBar( - value = (scrubbingDiskCacheMaxSize ?: preferences.coilDiskCacheMaxSizeBytes).coerceIn(250L * 1024 * 1024, 2048L * 1024 * 1024), - minimumValue = 250L * 1024 * 1024, - maximumValue = 2048L * 1024 * 1024, - onDragStart = { - scrubbingDiskCacheMaxSize = it - }, - onDrag = { delta -> - scrubbingDiskCacheMaxSize = scrubbingDiskCacheMaxSize?.plus(delta)?.coerceIn(250L * 1024 * 1024, 2048L * 1024 * 1024) - }, - onDragEnd = { - preferences.coilDiskCacheMaxSizeBytes = scrubbingDiskCacheMaxSize ?: preferences.coilDiskCacheMaxSizeBytes - scrubbingDiskCacheMaxSize = null - }, - color = colorPalette.text, - backgroundColor = colorPalette.textDisabled, - shape = RoundedCornerShape(8.dp), - modifier = Modifier - .padding(top = 8.dp) - .fillMaxWidth() - ) - } + EnumValueSelectorSettingsEntry( + title = "Max size", + selectedValue = preferences.coilDiskCacheMaxSize, + onValueSelected = { + preferences.coilDiskCacheMaxSize = it + } + ) DisabledSettingsEntry( title = "Space used", - text = "${Formatter.formatShortFileSize(context, diskCacheSize)} (${diskCacheSize * 100 / preferences.coilDiskCacheMaxSizeBytes.coerceAtLeast(1)}%)", + text = "${ + Formatter.formatShortFileSize( + context, + diskCacheSize + ) + } (${ + diskCacheSize * 100 / preferences.coilDiskCacheMaxSize.bytes.coerceAtLeast( + 1 + ) + }%)", ) SettingsEntry( @@ -167,54 +139,26 @@ fun CacheSettingsScreen() { } } - var scrubbingDiskCacheMaxSize by remember { - mutableStateOf(null) - } - SettingsEntryGroupText(title = "SONG CACHE") - Column( - modifier = Modifier - .padding(start = 24.dp) - .padding(horizontal = 32.dp, vertical = 16.dp) - .fillMaxWidth() - ) { - BasicText( - text = "Max size", - style = typography.xs.semiBold, - ) - - BasicText( - text = Formatter.formatShortFileSize(context, scrubbingDiskCacheMaxSize ?: preferences.exoPlayerDiskCacheMaxSizeBytes), - style = typography.xs.semiBold.secondary - ) - - SeekBar( - value = (scrubbingDiskCacheMaxSize ?: preferences.exoPlayerDiskCacheMaxSizeBytes).coerceIn(250L * 1024 * 1024, 4096L * 1024 * 1024), - minimumValue = 250L * 1024 * 1024, - maximumValue = 4096L * 1024 * 1024, - onDragStart = { - scrubbingDiskCacheMaxSize = it - }, - onDrag = { delta -> - scrubbingDiskCacheMaxSize = scrubbingDiskCacheMaxSize?.plus(delta)?.coerceIn(250L * 1024 * 1024, 4096L * 1024 * 1024) - }, - onDragEnd = { - preferences.exoPlayerDiskCacheMaxSizeBytes = scrubbingDiskCacheMaxSize ?: preferences.exoPlayerDiskCacheMaxSizeBytes - scrubbingDiskCacheMaxSize = null - }, - color = colorPalette.text, - backgroundColor = colorPalette.textDisabled, - shape = RoundedCornerShape(8.dp), - modifier = Modifier - .padding(top = 8.dp) - .fillMaxWidth() - ) - } + EnumValueSelectorSettingsEntry( + title = "Max size", + selectedValue = preferences.exoPlayerDiskCacheMaxSize, + onValueSelected = { + preferences.exoPlayerDiskCacheMaxSize = it + } + ) DisabledSettingsEntry( title = "Space used", - text = "${Formatter.formatShortFileSize(context, diskCacheSize)} (${diskCacheSize * 100 / preferences.exoPlayerDiskCacheMaxSizeBytes.coerceAtLeast(1)}%)", + text = buildString { + append(Formatter.formatShortFileSize(context, diskCacheSize)) + + when (val size = preferences.exoPlayerDiskCacheMaxSize) { + ExoPlayerDiskCacheMaxSize.Unlimited -> {} + else -> append("(${diskCacheSize * 100 / size.bytes}%)") + } + } ) } diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/Preferences.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/Preferences.kt index 805a3ff..88a95bb 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/Preferences.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/Preferences.kt @@ -20,8 +20,8 @@ class Preferences( initialSearchFilter: String, initialRepeatMode: Int, initialThumbnailRoundness: ThumbnailRoundness, - initialCoilDiskCacheMaxSizeBytes: Long, - initialExoPlayerDiskCacheMaxSizeBytes: Long, + initialCoilDiskCacheMaxSize: CoilDiskCacheMaxSize, + initialExoPlayerDiskCacheMaxSize: ExoPlayerDiskCacheMaxSize, initialSkipSilence: Boolean, initialVolumeNormalization: Boolean, initialPersistentQueue: Boolean, @@ -38,8 +38,8 @@ class Preferences( initialSearchFilter = preferences.getString(Keys.searchFilter, YouTube.Item.Song.Filter.value)!!, initialRepeatMode = preferences.getInt(Keys.repeatMode, Player.REPEAT_MODE_OFF), initialThumbnailRoundness = preferences.getEnum(Keys.thumbnailRoundness, ThumbnailRoundness.Light), - initialCoilDiskCacheMaxSizeBytes = preferences.getLong(Keys.coilDiskCacheMaxSizeBytes, 512L * 1024 * 1024), - initialExoPlayerDiskCacheMaxSizeBytes = preferences.getLong(Keys.exoPlayerDiskCacheMaxSizeBytes, 512L * 1024 * 1024), + initialCoilDiskCacheMaxSize = preferences.getEnum(Keys.coilDiskCacheMaxSize, CoilDiskCacheMaxSize.`128MB`), + initialExoPlayerDiskCacheMaxSize = preferences.getEnum(Keys.exoPlayerDiskCacheMaxSize, ExoPlayerDiskCacheMaxSize.`2GB`), initialSkipSilence = preferences.getBoolean(Keys.skipSilence, false), initialVolumeNormalization = preferences.getBoolean(Keys.volumeNormalization, false), initialPersistentQueue = preferences.getBoolean(Keys.persistentQueue, false), @@ -67,11 +67,11 @@ class Preferences( var thumbnailRoundness = initialThumbnailRoundness set(value) = edit { putEnum(Keys.thumbnailRoundness, value) } - var coilDiskCacheMaxSizeBytes = initialCoilDiskCacheMaxSizeBytes - set(value) = edit { putLong(Keys.coilDiskCacheMaxSizeBytes, value) } + var coilDiskCacheMaxSize = initialCoilDiskCacheMaxSize + set(value) = edit { putEnum(Keys.coilDiskCacheMaxSize, value) } - var exoPlayerDiskCacheMaxSizeBytes = initialExoPlayerDiskCacheMaxSizeBytes - set(value) = edit { putLong(Keys.exoPlayerDiskCacheMaxSizeBytes, value) } + var exoPlayerDiskCacheMaxSize = initialExoPlayerDiskCacheMaxSize + set(value) = edit { putEnum(Keys.exoPlayerDiskCacheMaxSize, value) } var skipSilence = initialSkipSilence set(value) = edit { putBoolean(Keys.skipSilence, value) } @@ -93,8 +93,8 @@ class Preferences( const val searchFilter = "searchFilter" const val repeatMode = "repeatMode" const val thumbnailRoundness = "thumbnailRoundness" - const val coilDiskCacheMaxSizeBytes = "coilDiskCacheMaxSizeBytes" - const val exoPlayerDiskCacheMaxSizeBytes = "exoPlayerDiskCacheMaxSizeBytes" + const val coilDiskCacheMaxSize = "coilDiskCacheMaxSize" + const val exoPlayerDiskCacheMaxSize = "exoPlayerDiskCacheMaxSize" const val skipSilence = "skipSilence" const val volumeNormalization = "volumeNormalization" const val persistentQueue = "persistentQueue"