Add song cache settings

This commit is contained in:
vfsfitvnm 2022-06-12 14:40:41 +02:00
parent 05afb475d4
commit 625fbb0247
5 changed files with 87 additions and 24 deletions

View file

@ -42,6 +42,7 @@ import it.vfsfitvnm.vimusic.ui.components.rememberBottomSheetState
import it.vfsfitvnm.vimusic.ui.components.rememberMenuState
import it.vfsfitvnm.vimusic.ui.screens.HomeScreen
import it.vfsfitvnm.vimusic.ui.screens.IntentUriScreen
import it.vfsfitvnm.vimusic.ui.screens.settings.OtherScreen
import it.vfsfitvnm.vimusic.ui.styling.*
import it.vfsfitvnm.vimusic.ui.views.PlayerView
import it.vfsfitvnm.vimusic.utils.*

View file

@ -1,7 +1,6 @@
package it.vfsfitvnm.vimusic
import android.app.Application
import android.content.Context
import coil.ImageLoader
import coil.ImageLoaderFactory
import coil.disk.DiskCache
@ -15,18 +14,14 @@ class MainApplication : Application(), ImageLoaderFactory {
}
override fun newImageLoader(): ImageLoader {
return defaultCoilImageLoader(preferences.coilDiskCacheMaxSizeBytes)
return ImageLoader.Builder(this)
.crossfade(true)
.diskCache(
DiskCache.Builder()
.directory(filesDir.resolve("coil"))
.maxSizeBytes(preferences.coilDiskCacheMaxSizeBytes)
.build()
)
.build()
}
}
fun Context.defaultCoilImageLoader(diskCacheMaxSize: Long): ImageLoader {
return ImageLoader.Builder(this)
.crossfade(true)
.diskCache(
DiskCache.Builder()
.directory(filesDir.resolve("coil"))
.maxSizeBytes(diskCacheMaxSize)
.build()
)
.build()
}

View file

@ -18,6 +18,7 @@ import androidx.core.app.NotificationCompat
import androidx.core.graphics.drawable.IconCompat
import androidx.core.graphics.drawable.toBitmap
import androidx.core.net.toUri
import androidx.core.os.bundleOf
import androidx.media3.common.*
import androidx.media3.common.util.Util
import androidx.media3.database.StandaloneDatabaseProvider
@ -25,7 +26,7 @@ import androidx.media3.datasource.DataSource
import androidx.media3.datasource.DefaultHttpDataSource
import androidx.media3.datasource.ResolvingDataSource
import androidx.media3.datasource.cache.CacheDataSource
import androidx.media3.datasource.cache.NoOpCacheEvictor
import androidx.media3.datasource.cache.LeastRecentlyUsedCacheEvictor
import androidx.media3.datasource.cache.SimpleCache
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.analytics.AnalyticsListener
@ -36,11 +37,10 @@ import androidx.media3.session.*
import androidx.media3.session.MediaNotification.ActionFactory
import coil.ImageLoader
import coil.request.ImageRequest
import com.google.common.util.concurrent.Futures
import com.google.common.util.concurrent.ListenableFuture
import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.MainActivity
import it.vfsfitvnm.vimusic.*
import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.internal
import it.vfsfitvnm.vimusic.models.QueuedMediaItem
import it.vfsfitvnm.vimusic.utils.*
import it.vfsfitvnm.youtubemusic.Outcome
@ -52,6 +52,8 @@ val StartRadioCommand = SessionCommand("StartRadioCommand", Bundle.EMPTY)
val StartArtistRadioCommand = SessionCommand("StartArtistRadioCommand", Bundle.EMPTY)
val StopRadioCommand = SessionCommand("StopRadioCommand", Bundle.EMPTY)
val GetCacheSizeCommand = SessionCommand("GetCacheSizeCommand", Bundle.EMPTY)
@ExperimentalAnimationApi
@ExperimentalFoundationApi
class PlayerService : MediaSessionService(), MediaSession.MediaItemFiller,
@ -83,7 +85,8 @@ class PlayerService : MediaSessionService(), MediaSession.MediaItemFiller,
createNotificationChannel()
setMediaNotificationProvider(this)
cache = SimpleCache(cacheDir, NoOpCacheEvictor(), StandaloneDatabaseProvider(this))
val cacheEvictor = LeastRecentlyUsedCacheEvictor(preferences.exoPlayerDiskCacheMaxSizeBytes)
cache = SimpleCache(cacheDir, cacheEvictor, StandaloneDatabaseProvider(this))
val player = ExoPlayer.Builder(this)
.setHandleAudioBecomingNoisy(true)
@ -176,6 +179,7 @@ class PlayerService : MediaSessionService(), MediaSession.MediaItemFiller,
.add(StartRadioCommand)
.add(StartArtistRadioCommand)
.add(StopRadioCommand)
.add(GetCacheSizeCommand)
.build()
val playerCommands = Player.Commands.Builder().addAllCommands().build()
return MediaSession.ConnectionResult.accept(sessionCommands, playerCommands)
@ -206,6 +210,9 @@ class PlayerService : MediaSessionService(), MediaSession.MediaItemFiller,
}
}
StopRadioCommand -> radio = null
GetCacheSizeCommand -> {
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS, bundleOf("cacheSize" to cache.cacheSpace)))
}
}
return super.onCustomCommand(session, controller, customCommand, args)

View file

@ -1,5 +1,6 @@
package it.vfsfitvnm.vimusic.ui.screens.settings
import android.os.Bundle
import android.text.format.Formatter
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.*
@ -16,15 +17,18 @@ import coil.Coil
import coil.annotation.ExperimentalCoilApi
import it.vfsfitvnm.route.RouteHandler
import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.services.GetCacheSizeCommand
import it.vfsfitvnm.vimusic.ui.components.SeekBar
import it.vfsfitvnm.vimusic.ui.components.TopAppBar
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.LocalYoutubePlayer
import it.vfsfitvnm.vimusic.utils.secondary
import it.vfsfitvnm.vimusic.utils.semiBold
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.guava.await
import kotlinx.coroutines.launch
@OptIn(ExperimentalCoilApi::class)
@ -54,10 +58,9 @@ fun OtherScreen() {
val colorPalette = LocalColorPalette.current
val typography = LocalTypography.current
val preferences = LocalPreferences.current
val mediaController = LocalYoutubePlayer.current?.mediaController
var coilDiskCache by remember {
mutableStateOf(Coil.imageLoader(context).diskCache)
}
val coilDiskCache = Coil.imageLoader(context).diskCache
val coroutineScope = rememberCoroutineScope()
@ -94,7 +97,6 @@ fun OtherScreen() {
)
}
coilDiskCache?.let { diskCache ->
var diskCacheSize by remember(diskCache) {
mutableStateOf(diskCache.size)
@ -133,7 +135,6 @@ fun OtherScreen() {
},
onDrag = { delta ->
scrubbingDiskCacheMaxSize = scrubbingDiskCacheMaxSize?.plus(delta)?.coerceIn(250L * 1024 * 1024, 2048L * 1024 * 1024)
println("new = $scrubbingDiskCacheMaxSize")
},
onDragEnd = {
preferences.coilDiskCacheMaxSizeBytes = scrubbingDiskCacheMaxSize ?: preferences.coilDiskCacheMaxSizeBytes
@ -164,6 +165,64 @@ fun OtherScreen() {
}
)
}
mediaController?.let { mediaController ->
val diskCacheSize by produceState(initialValue = 0L) {
value = mediaController.sendCustomCommand(GetCacheSizeCommand, Bundle.EMPTY).await().extras.getLong("cacheSize")
}
var scrubbingDiskCacheMaxSize by remember {
mutableStateOf<Long?>(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()
)
}
DisabledSettingsEntry(
title = "Space used",
text = "${Formatter.formatShortFileSize(context, diskCacheSize)} (${diskCacheSize * 100 / preferences.exoPlayerDiskCacheMaxSizeBytes.coerceAtLeast(1)}%)",
)
}
}
}
}

View file

@ -23,6 +23,7 @@ class Preferences(holder: SharedPreferences) : SharedPreferences by holder {
var homePageSongCollection by preference("homePageSongCollection", SongCollection.MostPlayed)
var thumbnailRoundness by preference("thumbnailRoundness", ThumbnailRoundness.Light)
var coilDiskCacheMaxSizeBytes by preference("coilDiskCacheMaxSizeBytes", 512L * 1024 * 1024)
var exoPlayerDiskCacheMaxSizeBytes by preference("exoPlayerDiskCacheMaxSizeBytes", 512L * 1024 * 1024)
var displayLikeButtonInNotification by preference("displayLikeButtonInNotification", false)
var persistentQueue by preference("persistentQueue", false)
}