fix(recordings): не зависать плееру записи; меньше задержка обложки
Bug1: плеер записи (singleton ExoPlayer) не глушился при закрытии шторки и уходе с экрана → аудио-сирота без управления, запуск радио конфликтовал. Теперь воспроизведение записи останавливается на onDismiss и onDispose экрана записей, а старт радио глушит плеер записи (взаимоисключение). Bug2: обложка/трек на открытом плеере обновлялись с задержкой при записи. Эмиссия спектра ограничена ~45/с (было ~86/с) — меньше перегруз перерисовки; поллинг now-playing в захвате маркеров ускорен 15с→8с (точнее тайм-коды). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -97,7 +97,7 @@ class RecordingRepositoryImpl @Inject constructor(
|
||||
launch {
|
||||
while (isActive) {
|
||||
try { nowPlayingRepository.refreshNowPlaying() } catch (_: Exception) {}
|
||||
delay(15_000)
|
||||
delay(8_000) // чаще — точнее тайм-коды треков в записи
|
||||
}
|
||||
}
|
||||
nowPlayingRepository.getNowPlaying(station.id)
|
||||
|
||||
@@ -86,6 +86,7 @@ class AudioSpectrumAnalyzer(
|
||||
private var channelCount = 2
|
||||
private var pcm16 = true
|
||||
private var sampleRate = 44100
|
||||
private var lastEmit = 0L
|
||||
// Автогейн: бегущий пик амплитуды — чтобы столбики всегда использовали всю
|
||||
// высоту независимо от громкости трека.
|
||||
private var agcPeak = 1e-4f
|
||||
@@ -159,6 +160,12 @@ class AudioSpectrumAnalyzer(
|
||||
smoothed[band] = if (v > prev) v else prev * 0.55f + v * 0.45f
|
||||
out[band] = smoothed[band]
|
||||
}
|
||||
_spectrum.value = out
|
||||
// Считаем сглаживание каждый хоп (плавность), но эмитим в UI ~45/с, чтобы
|
||||
// не перегружать перерисовку плеера.
|
||||
val now = System.nanoTime()
|
||||
if (now - lastEmit >= 22_000_000L) {
|
||||
lastEmit = now
|
||||
_spectrum.value = out
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,8 @@ class PlayerViewModel @Inject constructor(
|
||||
private val settingsRepository: SettingsRepository,
|
||||
private val recordingRepository: RecordingRepository,
|
||||
private val pushHistoryUseCase: PushHistoryUseCase,
|
||||
private val loveStreamResolver: com.radiola.data.remote.LoveStreamResolver
|
||||
private val loveStreamResolver: com.radiola.data.remote.LoveStreamResolver,
|
||||
private val recordingPlaybackController: com.radiola.service.RecordingPlaybackController
|
||||
) : ViewModel() {
|
||||
|
||||
val isPlaying: StateFlow<Boolean> = playerController.isPlaying
|
||||
@@ -98,6 +99,9 @@ class PlayerViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
fun play(station: Station, playlist: List<Station>? = null) {
|
||||
// Глушим плеер записи, если он играл — иначе два ExoPlayer'а конфликтуют
|
||||
// (радио не стартует, запись зависает без управления).
|
||||
recordingPlaybackController.stop()
|
||||
_currentStation.value = station
|
||||
_currentTrack.value = null
|
||||
_playlist.value = playlist ?: _stations.value
|
||||
|
||||
@@ -48,6 +48,13 @@ fun RecordingsScreen(
|
||||
val isRecording by viewModel.isRecording.collectAsState()
|
||||
val colors = RadiolaTheme.colors
|
||||
var playing by remember { mutableStateOf<Recording?>(null) }
|
||||
// Плеер записи — singleton-контроллер; держим его VM здесь, чтобы корректно
|
||||
// ОСТАНОВИТЬ воспроизведение при закрытии шторки и уходе с экрана (иначе
|
||||
// аудио продолжает играть без UI и конфликтует с радио).
|
||||
val recPlayerVm: RecordingPlayerViewModel = hiltViewModel()
|
||||
DisposableEffect(Unit) {
|
||||
onDispose { recPlayerVm.close() }
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
@@ -133,14 +140,14 @@ fun RecordingsScreen(
|
||||
// налезает на системную навигацию.
|
||||
playing?.let { rec ->
|
||||
ModalBottomSheet(
|
||||
onDismissRequest = { playing = null },
|
||||
onDismissRequest = { recPlayerVm.close(); playing = null },
|
||||
sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true),
|
||||
containerColor = colors.bgBase
|
||||
) {
|
||||
RecordingPlayerSheet(
|
||||
recording = rec,
|
||||
onDismiss = { playing = null },
|
||||
viewModel = hiltViewModel()
|
||||
onDismiss = { recPlayerVm.close(); playing = null },
|
||||
viewModel = recPlayerVm
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user