refactor(playback): simplify getVideoStreamUrl usage and improve direct play handling

This commit is contained in:
2026-05-29 18:09:12 +02:00
parent 97dcea57ec
commit 5c1ddffe7a
3 changed files with 16 additions and 27 deletions

View File

@@ -465,21 +465,11 @@ class JellyfinApiClient @Inject constructor(
}
fun getVideoStreamUrl(
itemId: UUID,
mediaSourceId: String?,
container: String? = null,
tag: String? = null,
playSessionId: String? = null,
liveStreamId: String? = null,
itemId: UUID
): String = try {
api.videosApi.getVideoStreamUrl(
itemId = itemId,
container = container,
mediaSourceId = mediaSourceId,
static = true,
tag = tag,
playSessionId = playSessionId,
liveStreamId = liveStreamId,
)
} catch (error: Exception) {
Timber.tag(TAG).e(error, "getVideoStreamUrl")

View File

@@ -2,15 +2,15 @@ package hu.bbara.purefin.data.jellyfin.playback
import hu.bbara.purefin.core.data.UserSessionRepository
import hu.bbara.purefin.data.jellyfin.client.JellyfinApiClient
import java.util.UUID
import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject
import javax.inject.Singleton
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.withContext
import org.jellyfin.sdk.model.ServerVersion
import timber.log.Timber
import java.util.UUID
import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class JellyfinPlaybackResolver @Inject constructor(
@@ -37,20 +37,19 @@ class JellyfinPlaybackResolver @Inject constructor(
return@withContext null
}
val directPlayUrl = jellyfinApiClient.getVideoStreamUrl(
itemId = mediaId,
)
if (directPlayUrl.isBlank()) {
Timber.tag(TAG).e("Direct play URL is blank for $mediaId")
return@withContext null
}
val decision = PlaybackDecisionResolver.resolve(
mediaSources = playbackInfo.mediaSources,
playSessionId = playbackInfo.playSessionId,
serverUrl = serverUrl,
directPlayUrl = { mediaSource ->
jellyfinApiClient.getVideoStreamUrl(
itemId = mediaId,
container = mediaSource.container,
mediaSourceId = mediaSource.id,
tag = mediaSource.eTag,
playSessionId = playbackInfo.playSessionId,
liveStreamId = mediaSource.liveStreamId,
)
},
directPlayUrl = directPlayUrl
)
if (decision == null) {

View File

@@ -10,7 +10,7 @@ internal object PlaybackDecisionResolver {
mediaSources: List<MediaSourceInfo>,
playSessionId: String?,
serverUrl: String,
directPlayUrl: (MediaSourceInfo) -> String,
directPlayUrl: String,
): PlaybackDecision? {
val mediaSource = mediaSources.firstOrNull { it.protocol == MediaProtocol.FILE && !it.isRemote }
?: return null
@@ -23,7 +23,7 @@ internal object PlaybackDecisionResolver {
}
val url = when (playMethod) {
PlaybackMethod.DIRECT_PLAY -> directPlayUrl(mediaSource)
PlaybackMethod.DIRECT_PLAY -> directPlayUrl
PlaybackMethod.DIRECT_STREAM,
PlaybackMethod.TRANSCODE,
-> absolutePlaybackUrl(serverUrl, requireNotNull(mediaSource.transcodingUrl))