Improve cache settings
This commit is contained in:
parent
9ed0f7e9d6
commit
0ddd49fd10
|
@ -19,7 +19,7 @@ class MainApplication : Application(), ImageLoaderFactory {
|
||||||
.diskCache(
|
.diskCache(
|
||||||
DiskCache.Builder()
|
DiskCache.Builder()
|
||||||
.directory(filesDir.resolve("coil"))
|
.directory(filesDir.resolve("coil"))
|
||||||
.maxSizeBytes(Preferences().coilDiskCacheMaxSizeBytes)
|
.maxSizeBytes(Preferences().coilDiskCacheMaxSize.bytes)
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
.build()
|
.build()
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ import androidx.media3.datasource.ResolvingDataSource
|
||||||
import androidx.media3.datasource.cache.Cache
|
import androidx.media3.datasource.cache.Cache
|
||||||
import androidx.media3.datasource.cache.CacheDataSource
|
import androidx.media3.datasource.cache.CacheDataSource
|
||||||
import androidx.media3.datasource.cache.LeastRecentlyUsedCacheEvictor
|
import androidx.media3.datasource.cache.LeastRecentlyUsedCacheEvictor
|
||||||
|
import androidx.media3.datasource.cache.NoOpCacheEvictor
|
||||||
import androidx.media3.datasource.cache.SimpleCache
|
import androidx.media3.datasource.cache.SimpleCache
|
||||||
import androidx.media3.exoplayer.ExoPlayer
|
import androidx.media3.exoplayer.ExoPlayer
|
||||||
import androidx.media3.exoplayer.RenderersFactory
|
import androidx.media3.exoplayer.RenderersFactory
|
||||||
|
@ -41,6 +42,7 @@ import androidx.media3.extractor.mkv.MatroskaExtractor
|
||||||
import it.vfsfitvnm.vimusic.Database
|
import it.vfsfitvnm.vimusic.Database
|
||||||
import it.vfsfitvnm.vimusic.MainActivity
|
import it.vfsfitvnm.vimusic.MainActivity
|
||||||
import it.vfsfitvnm.vimusic.R
|
import it.vfsfitvnm.vimusic.R
|
||||||
|
import it.vfsfitvnm.vimusic.enums.ExoPlayerDiskCacheMaxSize
|
||||||
import it.vfsfitvnm.vimusic.models.QueuedMediaItem
|
import it.vfsfitvnm.vimusic.models.QueuedMediaItem
|
||||||
import it.vfsfitvnm.vimusic.query
|
import it.vfsfitvnm.vimusic.query
|
||||||
import it.vfsfitvnm.vimusic.utils.*
|
import it.vfsfitvnm.vimusic.utils.*
|
||||||
|
@ -124,7 +126,11 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene
|
||||||
isVolumeNormalizationEnabled = preferences.volumeNormalization
|
isVolumeNormalizationEnabled = preferences.volumeNormalization
|
||||||
isInvincibilityEnabled = preferences.isInvincibilityEnabled
|
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))
|
cache = SimpleCache(cacheDir, cacheEvictor, StandaloneDatabaseProvider(this))
|
||||||
|
|
||||||
player = ExoPlayer.Builder(this, createRendersFactory(), createMediaSourceFactory())
|
player = ExoPlayer.Builder(this, createRendersFactory(), createMediaSourceFactory())
|
||||||
|
|
|
@ -16,6 +16,7 @@ import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import kotlin.math.roundToLong
|
import kotlin.math.roundToLong
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SeekBar(
|
fun SeekBar(
|
||||||
value: Long,
|
value: Long,
|
||||||
|
|
|
@ -4,7 +4,6 @@ import android.text.format.Formatter
|
||||||
import androidx.compose.animation.ExperimentalAnimationApi
|
import androidx.compose.animation.ExperimentalAnimationApi
|
||||||
import androidx.compose.foundation.*
|
import androidx.compose.foundation.*
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
||||||
import androidx.compose.foundation.text.BasicText
|
import androidx.compose.foundation.text.BasicText
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
@ -17,14 +16,13 @@ import coil.annotation.ExperimentalCoilApi
|
||||||
import it.vfsfitvnm.route.RouteHandler
|
import it.vfsfitvnm.route.RouteHandler
|
||||||
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
||||||
import it.vfsfitvnm.vimusic.R
|
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.TopAppBar
|
||||||
import it.vfsfitvnm.vimusic.ui.components.themed.TextCard
|
import it.vfsfitvnm.vimusic.ui.components.themed.TextCard
|
||||||
import it.vfsfitvnm.vimusic.ui.screens.*
|
import it.vfsfitvnm.vimusic.ui.screens.*
|
||||||
import it.vfsfitvnm.vimusic.ui.styling.LocalColorPalette
|
import it.vfsfitvnm.vimusic.ui.styling.LocalColorPalette
|
||||||
import it.vfsfitvnm.vimusic.ui.styling.LocalTypography
|
import it.vfsfitvnm.vimusic.ui.styling.LocalTypography
|
||||||
import it.vfsfitvnm.vimusic.utils.LocalPreferences
|
import it.vfsfitvnm.vimusic.utils.LocalPreferences
|
||||||
import it.vfsfitvnm.vimusic.utils.secondary
|
|
||||||
import it.vfsfitvnm.vimusic.utils.semiBold
|
import it.vfsfitvnm.vimusic.utils.semiBold
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
@ -98,54 +96,28 @@ fun CacheSettingsScreen() {
|
||||||
mutableStateOf(diskCache.size)
|
mutableStateOf(diskCache.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
var scrubbingDiskCacheMaxSize by remember {
|
|
||||||
mutableStateOf<Long?>(null)
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsEntryGroupText(title = "IMAGE CACHE")
|
SettingsEntryGroupText(title = "IMAGE CACHE")
|
||||||
|
|
||||||
Column(
|
EnumValueSelectorSettingsEntry(
|
||||||
modifier = Modifier
|
title = "Max size",
|
||||||
.padding(start = 24.dp)
|
selectedValue = preferences.coilDiskCacheMaxSize,
|
||||||
.padding(horizontal = 32.dp, vertical = 16.dp)
|
onValueSelected = {
|
||||||
.fillMaxWidth()
|
preferences.coilDiskCacheMaxSize = it
|
||||||
) {
|
}
|
||||||
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()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
DisabledSettingsEntry(
|
DisabledSettingsEntry(
|
||||||
title = "Space used",
|
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(
|
SettingsEntry(
|
||||||
|
@ -167,54 +139,26 @@ fun CacheSettingsScreen() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var scrubbingDiskCacheMaxSize by remember {
|
|
||||||
mutableStateOf<Long?>(null)
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsEntryGroupText(title = "SONG CACHE")
|
SettingsEntryGroupText(title = "SONG CACHE")
|
||||||
|
|
||||||
Column(
|
EnumValueSelectorSettingsEntry(
|
||||||
modifier = Modifier
|
title = "Max size",
|
||||||
.padding(start = 24.dp)
|
selectedValue = preferences.exoPlayerDiskCacheMaxSize,
|
||||||
.padding(horizontal = 32.dp, vertical = 16.dp)
|
onValueSelected = {
|
||||||
.fillMaxWidth()
|
preferences.exoPlayerDiskCacheMaxSize = it
|
||||||
) {
|
}
|
||||||
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()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
DisabledSettingsEntry(
|
DisabledSettingsEntry(
|
||||||
title = "Space used",
|
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}%)")
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@ class Preferences(
|
||||||
initialSearchFilter: String,
|
initialSearchFilter: String,
|
||||||
initialRepeatMode: Int,
|
initialRepeatMode: Int,
|
||||||
initialThumbnailRoundness: ThumbnailRoundness,
|
initialThumbnailRoundness: ThumbnailRoundness,
|
||||||
initialCoilDiskCacheMaxSizeBytes: Long,
|
initialCoilDiskCacheMaxSize: CoilDiskCacheMaxSize,
|
||||||
initialExoPlayerDiskCacheMaxSizeBytes: Long,
|
initialExoPlayerDiskCacheMaxSize: ExoPlayerDiskCacheMaxSize,
|
||||||
initialSkipSilence: Boolean,
|
initialSkipSilence: Boolean,
|
||||||
initialVolumeNormalization: Boolean,
|
initialVolumeNormalization: Boolean,
|
||||||
initialPersistentQueue: Boolean,
|
initialPersistentQueue: Boolean,
|
||||||
|
@ -38,8 +38,8 @@ class Preferences(
|
||||||
initialSearchFilter = preferences.getString(Keys.searchFilter, YouTube.Item.Song.Filter.value)!!,
|
initialSearchFilter = preferences.getString(Keys.searchFilter, YouTube.Item.Song.Filter.value)!!,
|
||||||
initialRepeatMode = preferences.getInt(Keys.repeatMode, Player.REPEAT_MODE_OFF),
|
initialRepeatMode = preferences.getInt(Keys.repeatMode, Player.REPEAT_MODE_OFF),
|
||||||
initialThumbnailRoundness = preferences.getEnum(Keys.thumbnailRoundness, ThumbnailRoundness.Light),
|
initialThumbnailRoundness = preferences.getEnum(Keys.thumbnailRoundness, ThumbnailRoundness.Light),
|
||||||
initialCoilDiskCacheMaxSizeBytes = preferences.getLong(Keys.coilDiskCacheMaxSizeBytes, 512L * 1024 * 1024),
|
initialCoilDiskCacheMaxSize = preferences.getEnum(Keys.coilDiskCacheMaxSize, CoilDiskCacheMaxSize.`128MB`),
|
||||||
initialExoPlayerDiskCacheMaxSizeBytes = preferences.getLong(Keys.exoPlayerDiskCacheMaxSizeBytes, 512L * 1024 * 1024),
|
initialExoPlayerDiskCacheMaxSize = preferences.getEnum(Keys.exoPlayerDiskCacheMaxSize, ExoPlayerDiskCacheMaxSize.`2GB`),
|
||||||
initialSkipSilence = preferences.getBoolean(Keys.skipSilence, false),
|
initialSkipSilence = preferences.getBoolean(Keys.skipSilence, false),
|
||||||
initialVolumeNormalization = preferences.getBoolean(Keys.volumeNormalization, false),
|
initialVolumeNormalization = preferences.getBoolean(Keys.volumeNormalization, false),
|
||||||
initialPersistentQueue = preferences.getBoolean(Keys.persistentQueue, false),
|
initialPersistentQueue = preferences.getBoolean(Keys.persistentQueue, false),
|
||||||
|
@ -67,11 +67,11 @@ class Preferences(
|
||||||
var thumbnailRoundness = initialThumbnailRoundness
|
var thumbnailRoundness = initialThumbnailRoundness
|
||||||
set(value) = edit { putEnum(Keys.thumbnailRoundness, value) }
|
set(value) = edit { putEnum(Keys.thumbnailRoundness, value) }
|
||||||
|
|
||||||
var coilDiskCacheMaxSizeBytes = initialCoilDiskCacheMaxSizeBytes
|
var coilDiskCacheMaxSize = initialCoilDiskCacheMaxSize
|
||||||
set(value) = edit { putLong(Keys.coilDiskCacheMaxSizeBytes, value) }
|
set(value) = edit { putEnum(Keys.coilDiskCacheMaxSize, value) }
|
||||||
|
|
||||||
var exoPlayerDiskCacheMaxSizeBytes = initialExoPlayerDiskCacheMaxSizeBytes
|
var exoPlayerDiskCacheMaxSize = initialExoPlayerDiskCacheMaxSize
|
||||||
set(value) = edit { putLong(Keys.exoPlayerDiskCacheMaxSizeBytes, value) }
|
set(value) = edit { putEnum(Keys.exoPlayerDiskCacheMaxSize, value) }
|
||||||
|
|
||||||
var skipSilence = initialSkipSilence
|
var skipSilence = initialSkipSilence
|
||||||
set(value) = edit { putBoolean(Keys.skipSilence, value) }
|
set(value) = edit { putBoolean(Keys.skipSilence, value) }
|
||||||
|
@ -93,8 +93,8 @@ class Preferences(
|
||||||
const val searchFilter = "searchFilter"
|
const val searchFilter = "searchFilter"
|
||||||
const val repeatMode = "repeatMode"
|
const val repeatMode = "repeatMode"
|
||||||
const val thumbnailRoundness = "thumbnailRoundness"
|
const val thumbnailRoundness = "thumbnailRoundness"
|
||||||
const val coilDiskCacheMaxSizeBytes = "coilDiskCacheMaxSizeBytes"
|
const val coilDiskCacheMaxSize = "coilDiskCacheMaxSize"
|
||||||
const val exoPlayerDiskCacheMaxSizeBytes = "exoPlayerDiskCacheMaxSizeBytes"
|
const val exoPlayerDiskCacheMaxSize = "exoPlayerDiskCacheMaxSize"
|
||||||
const val skipSilence = "skipSilence"
|
const val skipSilence = "skipSilence"
|
||||||
const val volumeNormalization = "volumeNormalization"
|
const val volumeNormalization = "volumeNormalization"
|
||||||
const val persistentQueue = "persistentQueue"
|
const val persistentQueue = "persistentQueue"
|
||||||
|
|
Loading…
Reference in a new issue