refactor: Added MediaSegments to MediaContext to make it accesible during playback. Also refactored MediaTrackPreferences to load preference in the PlayerViewModel

This commit is contained in:
2026-04-22 19:34:11 +02:00
parent 188efde982
commit 899e2f08b0
12 changed files with 130 additions and 34 deletions

View File

@@ -9,20 +9,27 @@ import androidx.media3.common.util.UnstableApi
import hu.bbara.purefin.core.data.PlayableMediaRepository
import hu.bbara.purefin.core.data.PlaybackReportContext
import hu.bbara.purefin.core.data.session.UserSessionRepository
import hu.bbara.purefin.core.image.ArtworkKind
import hu.bbara.purefin.core.image.ImageUrlBuilder
import hu.bbara.purefin.core.model.MediaSegment
import hu.bbara.purefin.core.model.SegmentType
import hu.bbara.purefin.data.jellyfin.client.JellyfinApiClient
import hu.bbara.purefin.data.jellyfin.playback.JellyfinPlaybackResolver
import hu.bbara.purefin.data.jellyfin.playback.PlaybackDecision
import hu.bbara.purefin.data.jellyfin.playback.playbackCustomCacheKey
import java.util.UUID
import javax.inject.Inject
import javax.inject.Singleton
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.withContext
import hu.bbara.purefin.core.image.ArtworkKind
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.MediaSegmentDto
import org.jellyfin.sdk.model.api.MediaSegmentType.INTRO
import org.jellyfin.sdk.model.api.MediaSegmentType.OUTRO
import org.jellyfin.sdk.model.api.MediaSegmentType.PREVIEW
import org.jellyfin.sdk.model.api.MediaSegmentType.RECAP
import org.jellyfin.sdk.model.api.MediaSourceInfo
import java.util.UUID
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class DefaultPlayableMediaRepository @Inject constructor(
@@ -52,6 +59,13 @@ class DefaultPlayableMediaRepository @Inject constructor(
Pair(mediaItem, resumePositionMs)
}
override suspend fun getMediaSegments(mediaId: UUID): List<MediaSegment> {
val mediaSegments = jellyfinApiClient.getMediaSegments(mediaId)
return mediaSegments.mapNotNull {
it.toMediaSegment()
}
}
override suspend fun getNextUpMediaItems(
episodeId: UUID,
existingIds: Set<String>,
@@ -133,4 +147,20 @@ class DefaultPlayableMediaRepository @Inject constructor(
val episodeNumber = item.indexNumber ?: return null
return "S$seasonNumber:E$episodeNumber"
}
private fun MediaSegmentDto.toMediaSegment(): MediaSegment {
val segmentType = when (type) {
INTRO -> SegmentType.INTRO
PREVIEW -> SegmentType.PREVIEW
RECAP -> SegmentType.RECAP
OUTRO -> SegmentType.OUTRO
else -> SegmentType.MAIN_CONTENT
}
return MediaSegment(
id = itemId,
type = segmentType,
startMs = startTicks,
endMs = endTicks
)
}
}

View File

@@ -13,6 +13,7 @@ import org.jellyfin.sdk.api.client.Response
import org.jellyfin.sdk.api.client.extensions.authenticateUserByName
import org.jellyfin.sdk.api.client.extensions.itemsApi
import org.jellyfin.sdk.api.client.extensions.mediaInfoApi
import org.jellyfin.sdk.api.client.extensions.mediaSegmentsApi
import org.jellyfin.sdk.api.client.extensions.playStateApi
import org.jellyfin.sdk.api.client.extensions.suggestionsApi
import org.jellyfin.sdk.api.client.extensions.tvShowsApi
@@ -30,6 +31,8 @@ import org.jellyfin.sdk.model.api.BaseItemKind
import org.jellyfin.sdk.model.api.CollectionType
import org.jellyfin.sdk.model.api.DeviceProfile
import org.jellyfin.sdk.model.api.ItemFields
import org.jellyfin.sdk.model.api.MediaSegmentDto
import org.jellyfin.sdk.model.api.MediaSegmentType
import org.jellyfin.sdk.model.api.MediaSourceInfo
import org.jellyfin.sdk.model.api.MediaType
import org.jellyfin.sdk.model.api.PlayMethod
@@ -264,6 +267,18 @@ class JellyfinApiClient @Inject constructor(
result.content.mediaSources
}
suspend fun getMediaSegments(mediaId: UUID) : List<MediaSegmentDto> = withContext(Dispatchers.IO) {
if (!ensureConfigured()) {
return@withContext emptyList()
}
val result = api.mediaSegmentsApi.getItemSegments(
itemId = mediaId,
includeSegmentTypes = listOf(MediaSegmentType.INTRO)
)
Log.d("getMediaSegments", result.toString())
result.content.items
}
suspend fun getPlaybackInfo(
mediaId: UUID,
deviceProfile: DeviceProfile,