refactor: use SSoT for playback speed
This commit is contained in:
@@ -11,10 +11,12 @@ kotlin {
|
||||
commonMain.dependencies {
|
||||
// Core modules
|
||||
implementation(projects.core.audioplayer)
|
||||
implementation(projects.core.coroutines)
|
||||
implementation(projects.core.logging)
|
||||
implementation(projects.core.model)
|
||||
|
||||
// Data modules
|
||||
implementation(projects.data.preferences)
|
||||
implementation(projects.data.records)
|
||||
implementation(projects.data.resources)
|
||||
implementation(projects.data.subtitle)
|
||||
|
||||
+24
-1
@@ -1,5 +1,6 @@
|
||||
package fr.ajaury.gwenedeg.player.data
|
||||
|
||||
import fr.ajaury.gwenedeg.core.coroutines.domain.DispatcherProvider
|
||||
import fr.ajaury.gwenedeg.core.logging.domain.Logger
|
||||
import fr.ajaury.gwenedeg.core.model.Phrase
|
||||
import fr.ajaury.gwenedeg.player.domain.AudioPlayer
|
||||
@@ -7,12 +8,16 @@ import fr.ajaury.gwenedeg.player.domain.PlaybackRepository
|
||||
import fr.ajaury.gwenedeg.player.model.PlaybackState
|
||||
import fr.ajaury.gwenedeg.player.model.PlaybackTiming
|
||||
import fr.ajaury.gwenedeg.player.model.PlayerState
|
||||
import fr.ajaury.gwenedeg.preferences.domain.PreferencesRepository
|
||||
import fr.ajaury.gwenedeg.records.model.Record
|
||||
import fr.ajaury.gwenedeg.resources.domain.ResourceReader
|
||||
import fr.ajaury.gwenedeg.subtitle.domain.GetCurrentSubtitleIndexUseCase
|
||||
import fr.ajaury.gwenedeg.subtitle.domain.SubtitleRepository
|
||||
import fr.ajaury.gwenedeg.subtitle.model.Subtitle
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@@ -22,6 +27,7 @@ import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
@@ -30,9 +36,15 @@ internal class PlaybackRepositoryImpl(
|
||||
private val audioPlayer: AudioPlayer,
|
||||
private val resourceReader: ResourceReader,
|
||||
private val subtitleRepository: SubtitleRepository,
|
||||
private val preferencesRepository: PreferencesRepository,
|
||||
private val getCurrentSubtitleIndex: GetCurrentSubtitleIndexUseCase,
|
||||
private val dispatcherProvider: DispatcherProvider,
|
||||
private val logger: Logger,
|
||||
) : PlaybackRepository {
|
||||
// Audio operations must run on the main thread (e.g. ExoPlayer), so keep the scope on it.
|
||||
private val scope = CoroutineScope(SupervisorJob() + dispatcherProvider.main)
|
||||
private var speedObservationJob: Job? = null
|
||||
|
||||
private val recordTitle = MutableStateFlow(Phrase(transcription = ""))
|
||||
private val subtitle = MutableStateFlow(Subtitle(emptyList()))
|
||||
|
||||
@@ -91,6 +103,17 @@ internal class PlaybackRepositoryImpl(
|
||||
playAudio(filePath = record.audioResourcePath)
|
||||
subtitle.value = loadSubtitle(record = record)
|
||||
recordTitle.value = record.title
|
||||
|
||||
observePlaybackSpeed()
|
||||
}
|
||||
|
||||
private fun observePlaybackSpeed() {
|
||||
speedObservationJob?.cancel()
|
||||
speedObservationJob = scope.launch {
|
||||
preferencesRepository.playbackPreferences.collect { playbackPreferences ->
|
||||
setSpeed(speed = playbackPreferences.speed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun playAudio(filePath: String) {
|
||||
@@ -136,7 +159,7 @@ internal class PlaybackRepositoryImpl(
|
||||
audioPlayer.seekTo(position)
|
||||
}
|
||||
|
||||
override fun setSpeed(speed: Float) {
|
||||
private fun setSpeed(speed: Float) {
|
||||
audioPlayer.setSpeed(speed)
|
||||
}
|
||||
|
||||
|
||||
-2
@@ -25,8 +25,6 @@ interface PlaybackRepository {
|
||||
|
||||
fun seekTo(position: Duration)
|
||||
|
||||
fun setSpeed(speed: Float)
|
||||
|
||||
fun seekToSentence(sentenceIndex: Int)
|
||||
|
||||
fun goToPreviousSentence()
|
||||
|
||||
+1
-8
@@ -62,7 +62,6 @@ class PlayerViewModel(
|
||||
if (alreadyLoadedRecord != null) {
|
||||
logger.debug("Record $recordId already loaded")
|
||||
playbackRepository.load(record = alreadyLoadedRecord)
|
||||
applyCurrentSpeed()
|
||||
return@launch
|
||||
}
|
||||
|
||||
@@ -73,16 +72,10 @@ class PlayerViewModel(
|
||||
}
|
||||
|
||||
playbackRepository.load(record = loadedRecord)
|
||||
applyCurrentSpeed()
|
||||
record.value = loadedRecord
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun applyCurrentSpeed() {
|
||||
val playbackPreferences = preferencesRepository.playbackPreferences.firstOrNull() ?: return
|
||||
playbackRepository.setSpeed(playbackPreferences.speed)
|
||||
}
|
||||
|
||||
fun performMainPlayAction() {
|
||||
when (uiState.value.playerState.playbackState) {
|
||||
PlaybackState.PLAYING -> playbackRepository.pause()
|
||||
@@ -113,9 +106,9 @@ class PlayerViewModel(
|
||||
PlaybackPreferences.MIN_SPEED,
|
||||
PlaybackPreferences.MAX_SPEED,
|
||||
)
|
||||
|
||||
viewModelScope.launch {
|
||||
preferencesRepository.setPlaybackSpeed(clampedSpeed)
|
||||
playbackRepository.setSpeed(clampedSpeed)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user