Merged transcoding support with main branch
This commit is contained in:
parent
4aafb806f1
commit
9edfc8b28e
5 changed files with 48 additions and 69 deletions
|
@ -8,11 +8,6 @@
|
||||||
app:summary="@string/preferred_quality"
|
app:summary="@string/preferred_quality"
|
||||||
app:title="@string/quality" />
|
app:title="@string/quality" />
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
|
||||||
app:key="pref_player_display_extended_title"
|
|
||||||
app:summary="@string/display_extended_title_summary"
|
|
||||||
app:title="@string/display_extended_title" />
|
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
app:key="pref_player_subtitles"
|
app:key="pref_player_subtitles"
|
||||||
app:summary="@string/subtitles_summary"
|
app:summary="@string/subtitles_summary"
|
||||||
|
|
|
@ -288,44 +288,45 @@ class JellyfinRepositoryImpl(
|
||||||
override suspend fun getMediaSources(itemId: UUID, includePath: Boolean): List<FindroidSource> =
|
override suspend fun getMediaSources(itemId: UUID, includePath: Boolean): List<FindroidSource> =
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
val sources = mutableListOf<FindroidSource>()
|
val sources = mutableListOf<FindroidSource>()
|
||||||
sources.addAll(
|
val playbackInfo = jellyfinApi.mediaInfoApi.getPostedPlaybackInfo(
|
||||||
jellyfinApi.mediaInfoApi.getPostedPlaybackInfo(
|
itemId,
|
||||||
itemId,
|
PlaybackInfoDto(
|
||||||
PlaybackInfoDto(
|
userId = jellyfinApi.userId!!,
|
||||||
userId = jellyfinApi.userId!!,
|
deviceProfile = DeviceProfile(
|
||||||
deviceProfile = DeviceProfile(
|
name = "Direct play all",
|
||||||
name = "Direct play all",
|
maxStaticBitrate = 1_000_000_000,
|
||||||
maxStaticBitrate = 1_000_000_000,
|
|
||||||
maxStreamingBitrate = 1_000_000_000,
|
|
||||||
codecProfiles = emptyList(),
|
|
||||||
containerProfiles = emptyList(),
|
|
||||||
directPlayProfiles = listOf(
|
|
||||||
DirectPlayProfile(type = DlnaProfileType.VIDEO),
|
|
||||||
DirectPlayProfile(type = DlnaProfileType.AUDIO),
|
|
||||||
),
|
|
||||||
transcodingProfiles = emptyList(),
|
|
||||||
responseProfiles = emptyList(),
|
|
||||||
subtitleProfiles = listOf(
|
|
||||||
SubtitleProfile("srt", SubtitleDeliveryMethod.EXTERNAL),
|
|
||||||
SubtitleProfile("vtt", SubtitleDeliveryMethod.EXTERNAL),
|
|
||||||
SubtitleProfile("ass", SubtitleDeliveryMethod.EXTERNAL),
|
|
||||||
),
|
|
||||||
xmlRootAttributes = emptyList(),
|
|
||||||
supportedMediaTypes = "",
|
|
||||||
enableAlbumArtInDidl = false,
|
|
||||||
enableMsMediaReceiverRegistrar = false,
|
|
||||||
enableSingleAlbumArtLimit = false,
|
|
||||||
enableSingleSubtitleLimit = false,
|
|
||||||
ignoreTranscodeByteRangeRequests = false,
|
|
||||||
maxAlbumArtHeight = 1_000_000_000,
|
|
||||||
maxAlbumArtWidth = 1_000_000_000,
|
|
||||||
requiresPlainFolders = false,
|
|
||||||
requiresPlainVideoItems = false,
|
|
||||||
timelineOffsetSeconds = 0,
|
|
||||||
),
|
|
||||||
maxStreamingBitrate = 1_000_000_000,
|
maxStreamingBitrate = 1_000_000_000,
|
||||||
|
codecProfiles = emptyList(),
|
||||||
|
containerProfiles = emptyList(),
|
||||||
|
directPlayProfiles = listOf(
|
||||||
|
DirectPlayProfile(type = DlnaProfileType.VIDEO),
|
||||||
|
DirectPlayProfile(type = DlnaProfileType.AUDIO),
|
||||||
|
),
|
||||||
|
transcodingProfiles = emptyList(),
|
||||||
|
responseProfiles = emptyList(),
|
||||||
|
subtitleProfiles = listOf(
|
||||||
|
SubtitleProfile("srt", SubtitleDeliveryMethod.EXTERNAL),
|
||||||
|
SubtitleProfile("vtt", SubtitleDeliveryMethod.EXTERNAL),
|
||||||
|
SubtitleProfile("ass", SubtitleDeliveryMethod.EXTERNAL),
|
||||||
|
),
|
||||||
|
xmlRootAttributes = emptyList(),
|
||||||
|
supportedMediaTypes = "",
|
||||||
|
enableAlbumArtInDidl = false,
|
||||||
|
enableMsMediaReceiverRegistrar = false,
|
||||||
|
enableSingleAlbumArtLimit = false,
|
||||||
|
enableSingleSubtitleLimit = false,
|
||||||
|
ignoreTranscodeByteRangeRequests = false,
|
||||||
|
maxAlbumArtHeight = 1_000_000_000,
|
||||||
|
maxAlbumArtWidth = 1_000_000_000,
|
||||||
|
requiresPlainFolders = false,
|
||||||
|
requiresPlainVideoItems = false,
|
||||||
|
timelineOffsetSeconds = 0,
|
||||||
),
|
),
|
||||||
).content.mediaSources.map {
|
maxStreamingBitrate = 1_000_000_000,
|
||||||
|
),
|
||||||
|
).content
|
||||||
|
playSessionIds[itemId] = playbackInfo.playSessionId
|
||||||
|
sources.addAll(playbackInfo.mediaSources.map {
|
||||||
it.toFindroidSource(
|
it.toFindroidSource(
|
||||||
this@JellyfinRepositoryImpl,
|
this@JellyfinRepositoryImpl,
|
||||||
itemId,
|
itemId,
|
||||||
|
|
|
@ -179,6 +179,14 @@ class JellyfinRepositoryOfflineImpl(
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun getHlsPlaylistUrl(
|
||||||
|
itemId: UUID,
|
||||||
|
mediaSourceId: String,
|
||||||
|
transcodeResolution: Int?
|
||||||
|
): String {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun getIntroTimestamps(itemId: UUID): Intro? =
|
override suspend fun getIntroTimestamps(itemId: UUID): Intro? =
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
database.getIntro(itemId)?.toIntro()
|
database.getIntro(itemId)?.toIntro()
|
||||||
|
|
|
@ -145,7 +145,6 @@ constructor(
|
||||||
val mediaItems = mutableListOf<MediaItem>()
|
val mediaItems = mutableListOf<MediaItem>()
|
||||||
try {
|
try {
|
||||||
for (item in items) {
|
for (item in items) {
|
||||||
val streamUrl = item.mediaSourceUri
|
|
||||||
val transcodeResolution = getTranscodeResolution(appPreferences.playerPreferredQuality)
|
val transcodeResolution = getTranscodeResolution(appPreferences.playerPreferredQuality)
|
||||||
val streamUrl = when {
|
val streamUrl = when {
|
||||||
item.mediaSourceUri.isNotEmpty() -> item.mediaSourceUri
|
item.mediaSourceUri.isNotEmpty() -> item.mediaSourceUri
|
||||||
|
|
|
@ -20,7 +20,6 @@ import kotlinx.coroutines.channels.BufferOverflow
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.jellyfin.sdk.model.api.ItemFields
|
import org.jellyfin.sdk.model.api.ItemFields
|
||||||
import org.jellyfin.sdk.model.api.MediaProtocol
|
|
||||||
import org.jellyfin.sdk.model.api.MediaStreamType
|
import org.jellyfin.sdk.model.api.MediaStreamType
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -139,7 +138,8 @@ class PlayerViewModel @Inject internal constructor(
|
||||||
mediaSourceIndex: Int?,
|
mediaSourceIndex: Int?,
|
||||||
playbackPosition: Long,
|
playbackPosition: Long,
|
||||||
): PlayerItem {
|
): PlayerItem {
|
||||||
val mediaSources = repository.getMediaSources(id, true)
|
val shouldTranscode = appPreferences.playerPreferredQuality != "Original"
|
||||||
|
val mediaSources = repository.getMediaSources(id, !shouldTranscode)
|
||||||
val mediaSource = if (mediaSourceIndex == null) {
|
val mediaSource = if (mediaSourceIndex == null) {
|
||||||
mediaSources.firstOrNull { it.type == FindroidSourceType.LOCAL } ?: mediaSources[0]
|
mediaSources.firstOrNull { it.type == FindroidSourceType.LOCAL } ?: mediaSources[0]
|
||||||
} else {
|
} else {
|
||||||
|
@ -172,30 +172,7 @@ class PlayerViewModel @Inject internal constructor(
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return when (mediaSource.protocol) {
|
return PlayerItem(
|
||||||
MediaProtocol.FILE -> PlayerItem(
|
|
||||||
name = name,
|
|
||||||
itemId = id,
|
|
||||||
mediaSourceId = mediaSource.id,
|
|
||||||
mediaSourceUri = mediaSource.path,
|
|
||||||
playbackPosition = playbackPosition,
|
|
||||||
parentIndexNumber = if (this is FindroidEpisode) parentIndexNumber else null,
|
|
||||||
indexNumber = if (this is FindroidEpisode) indexNumber else null,
|
|
||||||
indexNumberEnd = if (this is FindroidEpisode) indexNumberEnd else null,
|
|
||||||
externalSubtitles = externalSubtitles
|
|
||||||
)
|
|
||||||
MediaProtocol.HTTP -> PlayerItem(
|
|
||||||
name = name,
|
|
||||||
itemId = id,
|
|
||||||
mediaSourceId = mediaSource.id,
|
|
||||||
mediaSourceUri = mediaSource.path,
|
|
||||||
playbackPosition = playbackPosition,
|
|
||||||
parentIndexNumber = if (this is FindroidEpisode) parentIndexNumber else null,
|
|
||||||
indexNumber = if (this is FindroidEpisode) indexNumber else null,
|
|
||||||
indexNumberEnd = if (this is FindroidEpisode) indexNumberEnd else null,
|
|
||||||
externalSubtitles = externalSubtitles
|
|
||||||
)
|
|
||||||
else -> PlayerItem(
|
|
||||||
name = name,
|
name = name,
|
||||||
itemId = id,
|
itemId = id,
|
||||||
mediaSourceId = mediaSource.id,
|
mediaSourceId = mediaSource.id,
|
||||||
|
@ -206,7 +183,6 @@ class PlayerViewModel @Inject internal constructor(
|
||||||
indexNumberEnd = if (this is FindroidEpisode) indexNumberEnd else null,
|
indexNumberEnd = if (this is FindroidEpisode) indexNumberEnd else null,
|
||||||
externalSubtitles = externalSubtitles,
|
externalSubtitles = externalSubtitles,
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class PlayerItemState
|
sealed class PlayerItemState
|
||||||
|
|
Loading…
Reference in a new issue