Fix visualizer init

This commit is contained in:
Damontecres 2026-03-06 15:30:12 -05:00
parent e4422375ce
commit 7f75da2493
No known key found for this signature in database
7 changed files with 54 additions and 35 deletions

View file

@ -152,6 +152,15 @@ class AppPreferencesSerializer
slideshowDuration = AppPreference.SlideshowDuration.defaultValue slideshowDuration = AppPreference.SlideshowDuration.defaultValue
slideshowPlayVideos = AppPreference.SlideshowPlayVideos.defaultValue slideshowPlayVideos = AppPreference.SlideshowPlayVideos.defaultValue
}.build() }.build()
musicPreferences =
MusicPreferences
.newBuilder()
.apply {
showBackdrop = true
showLyrics = true
showAlbumArt = true
}.build()
}.build() }.build()
override suspend fun readFrom(input: InputStream): AppPreferences { override suspend fun readFrom(input: InputStream): AppPreferences {

View file

@ -15,6 +15,7 @@ import com.github.damontecres.wholphin.preferences.updateHomePagePreferences
import com.github.damontecres.wholphin.preferences.updateInterfacePreferences import com.github.damontecres.wholphin.preferences.updateInterfacePreferences
import com.github.damontecres.wholphin.preferences.updateLiveTvPreferences import com.github.damontecres.wholphin.preferences.updateLiveTvPreferences
import com.github.damontecres.wholphin.preferences.updateMpvOptions import com.github.damontecres.wholphin.preferences.updateMpvOptions
import com.github.damontecres.wholphin.preferences.updateMusicPreferences
import com.github.damontecres.wholphin.preferences.updatePhotoPreferences import com.github.damontecres.wholphin.preferences.updatePhotoPreferences
import com.github.damontecres.wholphin.preferences.updatePlaybackOverrides import com.github.damontecres.wholphin.preferences.updatePlaybackOverrides
import com.github.damontecres.wholphin.preferences.updateScreensaverPreferences import com.github.damontecres.wholphin.preferences.updateScreensaverPreferences
@ -263,4 +264,14 @@ suspend fun upgradeApp(
} }
} }
} }
if (previous.isEqualOrBefore(Version.fromString("0.5.2-1=g0"))) {
appPreferences.updateData {
it.updateMusicPreferences {
showBackdrop = true
showLyrics = true
showAlbumArt = true
}
}
}
} }

View file

@ -36,7 +36,7 @@ import timber.log.Timber
import java.util.UUID import java.util.UUID
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.hours
@Singleton @Singleton
class NavDrawerService class NavDrawerService
@ -101,7 +101,7 @@ class NavDrawerService
} }
NowPlayingStatus.PAUSED -> { NowPlayingStatus.PAUSED -> {
delay(2.minutes) delay(2.hours)
_state.update { _state.update {
it.copy( it.copy(
nowPlayingEnabled = false, nowPlayingEnabled = false,

View file

@ -49,7 +49,6 @@ fun BoxScope.BarVisualizer(
.width(width) .width(width)
.padding(start = if (index == 0) 0.dp else padding) .padding(start = if (index == 0) 0.dp else padding)
.background(MaterialTheme.colorScheme.border), .background(MaterialTheme.colorScheme.border),
// .align(Alignment.Bottom),
) )
} }
} }

View file

@ -168,9 +168,10 @@ fun NowPlayingOverlay(
Modifier Modifier
.fillMaxWidth() .fillMaxWidth()
.background( .background(
color = MaterialTheme.colorScheme.surface.copy(alpha = .75f), color = MaterialTheme.colorScheme.surface.copy(alpha = .5f),
shape = RoundedCornerShape(8.dp), shape = RoundedCornerShape(8.dp),
).onFocusChanged { ).padding(end = 8.dp)
.onFocusChanged {
if (it.hasFocus) showButtons = index < 3 if (it.hasFocus) showButtons = index < 3
controllerViewState.pulseControls() controllerViewState.pulseControls()
}.animateItem(), }.animateItem(),

View file

@ -19,6 +19,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
@ -28,6 +29,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.focus.focusRequester
@ -165,7 +167,8 @@ fun NowPlayingPage(
model = current?.imageUrl, model = current?.imageUrl,
modifier = modifier =
Modifier Modifier
.height(320.dp), .height(320.dp)
.clip(RoundedCornerShape(16.dp)),
) )
current?.title?.let { current?.title?.let {
Text( Text(

View file

@ -1,6 +1,5 @@
package com.github.damontecres.wholphin.ui.detail.music package com.github.damontecres.wholphin.ui.detail.music
import android.content.Context
import android.media.audiofx.Visualizer import android.media.audiofx.Visualizer
import androidx.datastore.core.DataStore import androidx.datastore.core.DataStore
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
@ -13,9 +12,9 @@ import com.github.damontecres.wholphin.data.model.BaseItem
import com.github.damontecres.wholphin.preferences.AppPreference import com.github.damontecres.wholphin.preferences.AppPreference
import com.github.damontecres.wholphin.preferences.AppPreferences import com.github.damontecres.wholphin.preferences.AppPreferences
import com.github.damontecres.wholphin.services.BackdropService import com.github.damontecres.wholphin.services.BackdropService
import com.github.damontecres.wholphin.services.ImageUrlService
import com.github.damontecres.wholphin.services.MusicService import com.github.damontecres.wholphin.services.MusicService
import com.github.damontecres.wholphin.services.NavigationManager import com.github.damontecres.wholphin.services.NavigationManager
import com.github.damontecres.wholphin.services.NowPlayingStatus
import com.github.damontecres.wholphin.services.UserPreferencesService import com.github.damontecres.wholphin.services.UserPreferencesService
import com.github.damontecres.wholphin.ui.launchDefault import com.github.damontecres.wholphin.ui.launchDefault
import com.github.damontecres.wholphin.ui.main.settings.MoveDirection import com.github.damontecres.wholphin.ui.main.settings.MoveDirection
@ -25,7 +24,6 @@ import com.mayakapps.kache.InMemoryKache
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@ -51,12 +49,10 @@ class NowPlayingViewModel
@AssistedInject @AssistedInject
constructor( constructor(
private val api: ApiClient, private val api: ApiClient,
@param:ApplicationContext private val context: Context,
val navigationManager: NavigationManager,
private val musicService: MusicService, private val musicService: MusicService,
private val imageUrlService: ImageUrlService,
private val backdropService: BackdropService, private val backdropService: BackdropService,
private val preferencesDataStore: DataStore<AppPreferences>, private val preferencesDataStore: DataStore<AppPreferences>,
val navigationManager: NavigationManager,
val userPreferencesService: UserPreferencesService, val userPreferencesService: UserPreferencesService,
) : ViewModel(), ) : ViewModel(),
Visualizer.OnDataCaptureListener, Visualizer.OnDataCaptureListener,
@ -66,15 +62,11 @@ class NowPlayingViewModel
fun create(): NowPlayingViewModel fun create(): NowPlayingViewModel
} }
private val visualizer by lazy { private var visualizer: Visualizer? = null
Visualizer(player.audioSessionId).apply {
captureSize = Visualizer.getCaptureSizeRange()[1]
}
}
val controllerViewState = val controllerViewState =
ControllerViewState( ControllerViewState(
AppPreference.Companion.ControllerTimeout.defaultValue, AppPreference.ControllerTimeout.defaultValue,
true, true,
) )
@ -90,20 +82,32 @@ class NowPlayingViewModel
init { init {
player.addListener(this) player.addListener(this)
visualizer.setDataCaptureListener(
this,
Visualizer.getMaxCaptureRate() / 2,
true,
false,
)
visualizer.enabled = true
addCloseable { addCloseable {
player.removeListener(this) player.removeListener(this)
visualizer.release() visualizer?.release()
} }
viewModelScope.launchDefault { viewModelScope.launchDefault {
musicService.state.collectLatest { musicServiceState -> musicService.state.collectLatest { musicServiceState ->
if (musicServiceState.status != NowPlayingStatus.IDLE) {
viewModelScope.launchDefault {
if (visualizer == null) {
visualizer =
Visualizer(onMain { player.audioSessionId }).apply {
captureSize = Visualizer.getCaptureSizeRange()[1]
setDataCaptureListener(
this@NowPlayingViewModel,
Visualizer.getMaxCaptureRate() / 2,
true,
false,
)
}
}
visualizer?.enabled =
musicServiceState.status == NowPlayingStatus.PLAYING
}
}
state.update { it.copy(musicServiceState = musicServiceState) } state.update { it.copy(musicServiceState = musicServiceState) }
} }
} }
@ -265,18 +269,10 @@ class NowPlayingViewModel
val processed = IntArray(resolution) val processed = IntArray(resolution)
val captureSize = val captureSize =
Visualizer.getCaptureSizeRange()[1] Visualizer.getCaptureSizeRange()[1]
// val groupSize = captureSize / resolution
val groupSize = captureSize / resolution.toFloat() val groupSize = captureSize / resolution.toFloat()
for (i in 0 until resolution) { for (i in 0 until resolution) {
// processed[i] =
// waveform
// .map { abs(it.toInt()) }
// .map { it.toInt() }
// .subList(i * groupSize, min((i + 1) * groupSize, waveform.size))
// .average()
// .toInt()
val v = abs(waveform[ceil(i * groupSize).toInt()].toInt()) val v = abs(waveform[ceil(i * groupSize).toInt()].toInt())
processed[i] = v * v / (128) processed[i] = abs(v * v / (128) - 128)
} }
viz.update { processed } viz.update { processed }
} }