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