mirror of
https://github.com/bbara04/Purefin.git
synced 2026-07-22 17:41:39 +00:00
feat: add preferenceMediaId to PlayableMedia and update related logic to make more prone to mistakes
This commit is contained in:
@@ -5,6 +5,7 @@ import java.util.UUID
|
||||
|
||||
sealed class PlayableMedia {
|
||||
abstract val id: UUID
|
||||
abstract val preferenceMediaId: UUID
|
||||
abstract val resumePositionMs: Long
|
||||
abstract val mediaItem: MediaItem
|
||||
abstract val preferences: MediaTrackPreferences
|
||||
@@ -12,6 +13,7 @@ sealed class PlayableMedia {
|
||||
|
||||
data class Movie(
|
||||
override val id: UUID,
|
||||
override val preferenceMediaId: UUID,
|
||||
override val resumePositionMs: Long,
|
||||
override val mediaItem: MediaItem,
|
||||
override val preferences: MediaTrackPreferences,
|
||||
@@ -20,6 +22,7 @@ sealed class PlayableMedia {
|
||||
|
||||
data class Series(
|
||||
override val id: UUID,
|
||||
override val preferenceMediaId: UUID,
|
||||
override val resumePositionMs: Long,
|
||||
override val mediaItem: MediaItem,
|
||||
override val preferences: MediaTrackPreferences,
|
||||
@@ -28,6 +31,7 @@ sealed class PlayableMedia {
|
||||
|
||||
data class Episode(
|
||||
override val id: UUID,
|
||||
override val preferenceMediaId: UUID,
|
||||
override val resumePositionMs: Long,
|
||||
override val mediaItem: MediaItem,
|
||||
override val preferences: MediaTrackPreferences,
|
||||
|
||||
@@ -11,7 +11,6 @@ import androidx.media3.exoplayer.ExoPlayer
|
||||
import dagger.hilt.android.scopes.ViewModelScoped
|
||||
import hu.bbara.purefin.core.data.PlayableMediaRepository
|
||||
import hu.bbara.purefin.core.data.PlaybackReportContext
|
||||
import hu.bbara.purefin.core.feature.content.episode.SeriesIdLookUpUseCase
|
||||
import hu.bbara.purefin.core.player.model.MetadataState
|
||||
import hu.bbara.purefin.core.player.model.PlaybackProgressSnapshot
|
||||
import hu.bbara.purefin.core.player.model.PlaybackStateSnapshot
|
||||
@@ -56,7 +55,6 @@ class PlayerManager @Inject constructor(
|
||||
private val playableMediaRepository: PlayableMediaRepository,
|
||||
private val trackPreferencesRepository: TrackPreferencesRepository,
|
||||
private val trackMatcher: TrackMatcher,
|
||||
private val seriesIdLookUpUseCase: SeriesIdLookUpUseCase,
|
||||
private val settingsRepository: SettingsRepository
|
||||
) {
|
||||
companion object {
|
||||
@@ -116,7 +114,8 @@ class PlayerManager @Inject constructor(
|
||||
|
||||
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
|
||||
clearActiveSkippableSegment()
|
||||
_currentMediaId.value = mediaItem?.mediaId?.let { UUID.fromString(it) }
|
||||
val mediaId = mediaItem?.mediaId?.let { UUID.fromString(it) }
|
||||
_currentMediaId.value = mediaId
|
||||
scope.launch {
|
||||
val currentMedia = _playlist.value.firstOrNull { it.id == _currentMediaId.value }
|
||||
if (currentMedia == null) {
|
||||
@@ -263,6 +262,15 @@ class PlayerManager @Inject constructor(
|
||||
}
|
||||
|
||||
fun selectTrack(option: TrackOption) {
|
||||
scope.launch {
|
||||
if (option.type != TrackType.VIDEO) {
|
||||
saveTrackPreference(option)
|
||||
}
|
||||
applyTrackSelection(option)
|
||||
}
|
||||
}
|
||||
|
||||
private fun applyTrackSelection(option: TrackOption) {
|
||||
val builder = player.trackSelectionParameters.buildUpon()
|
||||
when (option.type) {
|
||||
TrackType.TEXT -> {
|
||||
@@ -296,13 +304,6 @@ class PlayerManager @Inject constructor(
|
||||
}
|
||||
}
|
||||
player.trackSelectionParameters = builder.build()
|
||||
|
||||
// Save track preference if media id is available
|
||||
_currentMediaId.value?.let { mediaId ->
|
||||
scope.launch {
|
||||
saveTrackPreference(option, mediaId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun installMediaSegments(mediaSegments: List<MediaSegment>) {
|
||||
@@ -329,9 +330,14 @@ class PlayerManager @Inject constructor(
|
||||
}
|
||||
|
||||
private suspend fun applyTrackPreferences() {
|
||||
val preferences = currentPlayableMedia.firstOrNull()?.preferences ?: return
|
||||
|
||||
val currentMedia = currentPlayableMedia.firstOrNull() ?: return
|
||||
val currentTrackState = _tracks.value
|
||||
if (currentTrackState.audioTracks.isEmpty() && currentTrackState.textTracks.isEmpty()) return
|
||||
|
||||
val preferences = trackPreferencesRepository
|
||||
.getMediaPreferences(currentMedia.preferenceMediaId.toString())
|
||||
.firstOrNull()
|
||||
?: return
|
||||
|
||||
// Apply audio preference
|
||||
preferences.audioPreference?.let { audioPreference ->
|
||||
@@ -339,7 +345,9 @@ class PlayerManager @Inject constructor(
|
||||
currentTrackState.audioTracks,
|
||||
audioPreference
|
||||
)
|
||||
matchedAudio?.let { selectTrack(it) }
|
||||
if (matchedAudio != null && matchedAudio.id != currentTrackState.selectedAudioTrackId) {
|
||||
applyTrackSelection(matchedAudio)
|
||||
}
|
||||
}
|
||||
|
||||
// Apply subtitle preference
|
||||
@@ -348,15 +356,17 @@ class PlayerManager @Inject constructor(
|
||||
currentTrackState.textTracks,
|
||||
subtitlePreference
|
||||
)
|
||||
matchedSubtitle?.let { selectTrack(it) }
|
||||
if (matchedSubtitle != null && matchedSubtitle.id != currentTrackState.selectedTextTrackId) {
|
||||
applyTrackSelection(matchedSubtitle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun saveTrackPreference(option: TrackOption, mediaId: UUID) {
|
||||
val preferenceMediaId = when (currentPlayableMedia.firstOrNull()) {
|
||||
is PlayableMedia.Episode -> seriesIdLookUpUseCase(mediaId) ?: mediaId
|
||||
else -> mediaId
|
||||
}.toString()
|
||||
private suspend fun saveTrackPreference(option: TrackOption) {
|
||||
val preferenceMediaId = currentPlayableMedia.firstOrNull()
|
||||
?.preferenceMediaId
|
||||
?.toString()
|
||||
?: return
|
||||
|
||||
when (option.type) {
|
||||
TrackType.AUDIO -> {
|
||||
|
||||
@@ -48,11 +48,16 @@ class DefaultPlayableMediaRepository @Inject constructor(
|
||||
|
||||
val mediaItem = getMediaItem(baseItem, playbackDecision)
|
||||
val resumePositionMs = calculateResumePosition(baseItem, playbackDecision.mediaSource)
|
||||
val mediaTrackPreferences = trackPreferencesRepository.getMediaPreferences(baseItem.parentId.toString()).first()
|
||||
val preferenceMediaId = when (baseItem.type) {
|
||||
BaseItemKind.EPISODE -> baseItem.seriesId ?: mediaId
|
||||
else -> mediaId
|
||||
}
|
||||
val mediaTrackPreferences = trackPreferencesRepository.getMediaPreferences(preferenceMediaId.toString()).first()
|
||||
val mediaSegments = getMediaSegments(mediaId)
|
||||
when (baseItem.type) {
|
||||
BaseItemKind.MOVIE -> PlayableMedia.Movie(
|
||||
id = mediaId,
|
||||
preferenceMediaId = preferenceMediaId,
|
||||
mediaItem = mediaItem,
|
||||
resumePositionMs = resumePositionMs ?: 0L,
|
||||
preferences = mediaTrackPreferences,
|
||||
@@ -60,6 +65,7 @@ class DefaultPlayableMediaRepository @Inject constructor(
|
||||
)
|
||||
BaseItemKind.SERIES -> PlayableMedia.Series(
|
||||
id = mediaId,
|
||||
preferenceMediaId = preferenceMediaId,
|
||||
mediaItem = mediaItem,
|
||||
resumePositionMs = resumePositionMs ?: 0L,
|
||||
preferences = mediaTrackPreferences,
|
||||
@@ -67,6 +73,7 @@ class DefaultPlayableMediaRepository @Inject constructor(
|
||||
)
|
||||
BaseItemKind.EPISODE -> PlayableMedia.Episode(
|
||||
id = mediaId,
|
||||
preferenceMediaId = preferenceMediaId,
|
||||
mediaItem = mediaItem,
|
||||
resumePositionMs = resumePositionMs ?: 0L,
|
||||
preferences = mediaTrackPreferences,
|
||||
|
||||
Reference in New Issue
Block a user