Skip to content

Commit 45d0d18

Browse files
Add media source selection
1 parent d48c1e6 commit 45d0d18

File tree

5 files changed

+32
-15
lines changed

5 files changed

+32
-15
lines changed

playback/jellyfin/src/main/kotlin/mediastream/AudioMediaStreamResolver.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import org.jellyfin.playback.core.mediastream.PlayableMediaStream
88
import org.jellyfin.playback.core.queue.QueueEntry
99
import org.jellyfin.playback.core.support.PlaySupportReport
1010
import org.jellyfin.playback.jellyfin.queue.baseItem
11+
import org.jellyfin.playback.jellyfin.queue.mediaSourceId
1112
import org.jellyfin.sdk.api.client.ApiClient
1213
import org.jellyfin.sdk.api.client.extensions.audioApi
1314
import org.jellyfin.sdk.api.client.extensions.dynamicHlsApi
@@ -54,7 +55,7 @@ class AudioMediaStreamResolver(
5455
val baseItem = queueEntry.baseItem
5556
if (baseItem == null || baseItem.mediaType != MediaType.Audio) return null
5657

57-
val mediaInfo = getPlaybackInfo(baseItem)
58+
val mediaInfo = getPlaybackInfo(baseItem, queueEntry.mediaSourceId)
5859

5960
// Test for direct play support
6061
val directPlayStream = mediaInfo.getDirectPlayStream()

playback/jellyfin/src/main/kotlin/mediastream/JellyfinStreamResolver.kt

+13-12
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import org.jellyfin.sdk.api.client.ApiClient
55
import org.jellyfin.sdk.api.client.extensions.mediaInfoApi
66
import org.jellyfin.sdk.model.api.BaseItemDto
77
import org.jellyfin.sdk.model.api.DeviceProfile
8+
import org.jellyfin.sdk.model.api.MediaProtocol
89
import org.jellyfin.sdk.model.api.MediaSourceInfo
910
import org.jellyfin.sdk.model.api.PlaybackInfoDto
1011

@@ -19,41 +20,41 @@ abstract class JellyfinStreamResolver(
1920

2021
protected suspend fun getPlaybackInfo(
2122
item: BaseItemDto,
22-
mediaSource: MediaSourceInfo? = null,
23+
mediaSourceId: String? = null,
2324
): MediaInfo {
2425
val response by api.mediaInfoApi.getPostedPlaybackInfo(
2526
itemId = item.id,
2627
data = PlaybackInfoDto(
2728
userId = api.userId,
2829
maxStreamingBitrate = profile.maxStreamingBitrate,
29-
mediaSourceId = mediaSource?.id,
30-
liveStreamId = mediaSource?.liveStreamId,
30+
mediaSourceId = mediaSourceId,
3131
deviceProfile = profile,
3232
enableDirectPlay = true,
3333
enableDirectStream = true,
3434
enableTranscoding = true,
3535
allowVideoStreamCopy = true,
3636
allowAudioStreamCopy = true,
37-
autoOpenLiveStream = true,
37+
autoOpenLiveStream = false,
3838
)
3939
)
4040

4141
if (response.errorCode != null) {
42-
error("Failed to get media info for item ${item.id} source ${mediaSource?.id}: ${response.errorCode}")
42+
error("Failed to get media info for item ${item.id} source ${mediaSourceId}: ${response.errorCode}")
4343
}
4444

45-
val responseMediaSource = when (mediaSource) {
46-
null -> response.mediaSources.firstOrNull()
47-
else -> response.mediaSources.firstOrNull { it.id === mediaSource.id }
48-
}
45+
val mediaSource = response.mediaSources
46+
// Filter out invalid streams (like strm files)
47+
.filter { it.protocol == MediaProtocol.FILE && !it.isRemote }
48+
// Select first media source
49+
.firstOrNull { mediaSourceId == null || it.id == mediaSourceId }
4950

50-
requireNotNull(responseMediaSource) {
51-
"Failed to get media info for item ${item.id} source ${mediaSource?.id}: media source missing in response"
51+
requireNotNull(mediaSource) {
52+
"Failed to get media info for item ${item.id} source ${mediaSourceId}: media source missing in response"
5253
}
5354

5455
return MediaInfo(
5556
playSessionId = response.playSessionId.orEmpty(),
56-
mediaSource = responseMediaSource
57+
mediaSource = mediaSource
5758
)
5859
}
5960
}

playback/jellyfin/src/main/kotlin/mediastream/UniversalAudioMediaStreamResolver.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import org.jellyfin.playback.core.mediastream.PlayableMediaStream
66
import org.jellyfin.playback.core.queue.QueueEntry
77
import org.jellyfin.playback.core.support.PlaySupportReport
88
import org.jellyfin.playback.jellyfin.queue.baseItem
9+
import org.jellyfin.playback.jellyfin.queue.mediaSourceId
910
import org.jellyfin.sdk.api.client.ApiClient
1011
import org.jellyfin.sdk.api.client.extensions.universalAudioApi
1112
import org.jellyfin.sdk.model.api.BaseItemKind
@@ -22,7 +23,7 @@ class UniversalAudioMediaStreamResolver(
2223
val baseItem = queueEntry.baseItem
2324
if (baseItem == null || baseItem.type != BaseItemKind.AUDIO) return null
2425

25-
val mediaInfo = getPlaybackInfo(baseItem)
26+
val mediaInfo = getPlaybackInfo(baseItem, queueEntry.mediaSourceId)
2627

2728
val url = api.universalAudioApi.getUniversalAudioStreamUrl(
2829
itemId = baseItem.id,

playback/jellyfin/src/main/kotlin/mediastream/VideoMediaStreamResolver.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import org.jellyfin.playback.core.mediastream.PlayableMediaStream
88
import org.jellyfin.playback.core.queue.QueueEntry
99
import org.jellyfin.playback.core.support.PlaySupportReport
1010
import org.jellyfin.playback.jellyfin.queue.baseItem
11+
import org.jellyfin.playback.jellyfin.queue.mediaSourceId
1112
import org.jellyfin.sdk.api.client.ApiClient
1213
import org.jellyfin.sdk.api.client.extensions.dynamicHlsApi
1314
import org.jellyfin.sdk.api.client.extensions.videosApi
@@ -54,7 +55,7 @@ class VideoMediaStreamResolver(
5455
val baseItem = queueEntry.baseItem
5556
if (baseItem == null || baseItem.mediaType != MediaType.Video) return null
5657

57-
val mediaInfo = getPlaybackInfo(baseItem)
58+
val mediaInfo = getPlaybackInfo(baseItem, queueEntry.mediaSourceId)
5859

5960
// Test for direct play support
6061
val directPlayStream = mediaInfo.getDirectPlayStream()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package org.jellyfin.playback.jellyfin.queue
2+
3+
import org.jellyfin.playback.core.element.ElementKey
4+
import org.jellyfin.playback.core.element.element
5+
import org.jellyfin.playback.core.queue.QueueEntry
6+
7+
private val mediaSourceIdKey = ElementKey<String>("MediaSource")
8+
9+
/**
10+
* Get or set the id of the MediaSource to use during playback. Or null for the default selection
11+
* behavior.
12+
*/
13+
var QueueEntry.mediaSourceId by element(mediaSourceIdKey)

0 commit comments

Comments
 (0)