Skip to content

Commit ededd66

Browse files
sentinelwebsentinelweb
andauthored
Bugfix/484 playersession hold item (#485)
* #484 use item in PlayerSession.kt * #484 use item in MediaSessionManager.kt --------- Co-authored-by: sentinelweb <robmunro@robs-mbp.home>
1 parent f74e211 commit ededd66

File tree

11 files changed

+87
-82
lines changed

11 files changed

+87
-82
lines changed

app/src/main/java/uk/co/sentinelweb/cuer/app/util/chromecast/listener/YouTubePlayerListener.kt

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import uk.co.sentinelweb.cuer.app.util.mediasession.MediaSessionContract
1414
import uk.co.sentinelweb.cuer.core.providers.CoroutineContextProvider
1515
import uk.co.sentinelweb.cuer.core.providers.TimeProvider
1616
import uk.co.sentinelweb.cuer.core.wrapper.LogWrapper
17-
import uk.co.sentinelweb.cuer.domain.MediaDomain
1817
import uk.co.sentinelweb.cuer.domain.PlayerStateDomain
1918
import uk.co.sentinelweb.cuer.domain.PlaylistItemDomain
2019
import uk.co.sentinelweb.cuer.domain.ext.isLiveOrUpcoming
@@ -40,7 +39,7 @@ class YouTubePlayerListener(
4039
var playState: PlayerStateDomain = PlayerStateDomain.UNKNOWN,
4140
var positionSec: Float = 0f,
4241
var durationSec: Float = 0f,
43-
var currentMedia: MediaDomain? = null,
42+
var currentItem: PlaylistItemDomain? = null,
4443
var lastUpdateMedia: Long = -1L,
4544
var lastUpdateUI: Long = -1L,
4645
var receivedVideoId: String? = null,
@@ -62,7 +61,7 @@ class YouTubePlayerListener(
6261
queue.currentItemFlow
6362
.distinctUntilChanged { old, new -> old?.media?.id == new?.media?.id }
6463
.onEach { loadVideo(it) }
65-
.onEach { item -> item?.let { mediaSessionManager.setMedia(item.media, queue.playlist) } }
64+
.onEach { item -> item?.let { mediaSessionManager.setItem(item, queue.playlist) } }
6665
.launchIn(coroutines.mainScope)
6766
}
6867

@@ -100,14 +99,14 @@ class YouTubePlayerListener(
10099
// log.d("onVideoDuration dur=${state.durationSec} durObTime=${state.durationObtainedTime}")
101100
this.youTubePlayer = youTubePlayer
102101
state.durationSec = duration
103-
state.currentMedia
102+
state.currentItem?.media
104103
?.takeIf { it.isLiveBroadcast }
105104
?.apply { livePlaybackController.gotDuration((duration * 1000).toLong()) }
106105
playerUi?.setDuration(duration)
107106
updateMedia(false, durSec = duration)
108107
playerUi?.setButtons(buildButtons(queue.currentItem))
109-
state.currentMedia
110-
?.apply { mediaSessionManager.setMedia(this, queue.playlist) }
108+
state.currentItem
109+
?.apply { mediaSessionManager.setItem(this, queue.playlist) }
111110
}
112111

113112
override fun onCurrentSecond(youTubePlayer: YouTubePlayer, second: Float) {
@@ -126,11 +125,11 @@ class YouTubePlayerListener(
126125
}
127126

128127
private fun updateMediaSessionManagerPlaybackState() {
129-
state.currentMedia?.apply {
128+
state.currentItem?.apply {
130129
mediaSessionManager.updatePlaybackState(
131130
this,
132131
state.playState,
133-
if (isLiveBroadcast) getLiveOffsetMs() else null,
132+
if (media.isLiveBroadcast) getLiveOffsetMs() else null,
134133
queue.playlist
135134
)
136135
}
@@ -143,17 +142,20 @@ class YouTubePlayerListener(
143142
}
144143

145144
private fun updateMedia(throttle: Boolean, posSec: Float? = null, durSec: Float? = null) {
146-
state.currentMedia = state.currentMedia?.run {
145+
state.currentItem = state.currentItem?.run {
147146
copy(
148-
positon = posSec?.let { (it * 1000).toLong() } ?: positon,
149-
duration = durSec?.let { (it * 1000).toLong() } ?: duration,
150-
dateLastPlayed = timeProvider.instant()
147+
media = media.copy(
148+
positon = posSec?.let { (it * 1000).toLong() } ?: media.positon,
149+
duration = durSec?.let { (it * 1000).toLong() } ?: media.duration,
150+
dateLastPlayed = timeProvider.instant()
151+
)
151152
)
152153
}
154+
153155
if (shouldUpdateMedia(throttle)) {
154-
if (state.receivedVideoId != null && state.receivedVideoId == state.currentMedia?.platformId) {
155-
state.currentMedia?.apply { queue.updateCurrentMediaItem(this) }
156-
} else log.d("Not updating media: ${state.receivedVideoId} != ${state.currentMedia?.platformId}")
156+
if (state.receivedVideoId != null && state.receivedVideoId == state.currentItem?.media?.platformId) {
157+
state.currentItem?.media?.apply { queue.updateCurrentMediaItem(this) }
158+
} else log.d("Not updating media: ${state.receivedVideoId} != ${state.currentItem?.media?.platformId}")
157159
setTimeUpdateMedia()
158160
}
159161
}
@@ -208,13 +210,13 @@ class YouTubePlayerListener(
208210
this.youTubePlayer = youTubePlayer
209211
state.receivedVideoId = videoId
210212
livePlaybackController.gotVideoId(videoId)
211-
log.d("Got id: $videoId media=${state.currentMedia?.stringMedia()}")
213+
log.d("Got id: $videoId media=${state.currentItem?.media?.stringMedia()}")
212214
}
213215

214216
override fun onVideoLoadedFraction(youTubePlayer: YouTubePlayer, loadedFraction: Float) {
215217
this.youTubePlayer = youTubePlayer
216218
}
217-
// endregion
219+
// endregion
218220

219221
// region CastPlayerContract.PresenterExternal.Listener
220222
override fun play() {
@@ -276,7 +278,7 @@ class YouTubePlayerListener(
276278
handleError(e)
277279
}
278280
}
279-
// endregion
281+
// endregion
280282

281283
private fun handleError(e: Exception) {
282284
playerUi?.error("Error: ${e.message ?: "Unknown - check log"}")
@@ -289,13 +291,13 @@ class YouTubePlayerListener(
289291
livePlaybackController.clear(media.platformId)
290292
log.d("loadVideo: play position: pos = $startPos ms")
291293
youTubePlayer?.loadVideo(media.platformId, (startPos / 1000).toFloat())
292-
state.currentMedia = media
294+
state.currentItem = this
293295
playerUi?.setPlaylistItem(queue.currentItem)
294296
playerUi?.setPlaylistName(queue.playlist?.title ?: "none")
295297
playerUi?.setPlaylistImage(queue.playlist?.let { it.thumb ?: it.image })
296298
playerUi?.setButtons(buildButtons(this))
297299
} ?: run {
298-
state.currentMedia = null
300+
state.currentItem = null
299301
state.receivedVideoId = null
300302
youTubePlayer?.pause()
301303
playerUi?.reset()
@@ -316,12 +318,12 @@ class YouTubePlayerListener(
316318
private fun setupPlayer(controls: PlayerContract.PlayerControls) {
317319
controls.apply {
318320
addListener(this@YouTubePlayerListener)
319-
setTitle(state.currentMedia?.title ?: "No Media")
321+
setTitle(state.currentItem?.media?.title ?: "No Media")
320322
setPlayerState(state.playState)
321323
setDuration(state.durationSec)
322324
setCurrentSecond(state.positionSec)
323-
if (state.currentMedia == null) {
324-
state.currentMedia = queue.currentItem?.media
325+
if (state.currentItem?.media == null) {
326+
state.currentItem = queue.currentItem
325327
}
326328
setPlaylistItem(queue.currentItem)
327329
}

app/src/main/java/uk/co/sentinelweb/cuer/app/util/mediasession/MediaSessionManager.kt

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import uk.co.sentinelweb.cuer.core.wrapper.LogWrapper
1313
import uk.co.sentinelweb.cuer.domain.MediaDomain
1414
import uk.co.sentinelweb.cuer.domain.PlayerStateDomain
1515
import uk.co.sentinelweb.cuer.domain.PlaylistDomain
16+
import uk.co.sentinelweb.cuer.domain.PlaylistItemDomain
1617

1718
class MediaSessionManager(
1819
private val appState: CuerAppState,
@@ -52,15 +53,15 @@ class MediaSessionManager(
5253
state.bitmapUrl = null
5354
}
5455

55-
override fun setMedia(media: MediaDomain, playlist: PlaylistDomain?) {
56-
if (media.thumbNail == null) {
56+
override fun setItem(item: PlaylistItemDomain, playlist: PlaylistDomain?) {
57+
if (item.media.thumbNail == null) {
5758
state.bitmapUrl = null
5859
state.bitmap = null
59-
} else if (media.thumbNail?.url != state.bitmapUrl) {
60-
state.bitmapUrl = media.thumbNail?.url
61-
Glide.with(context).asBitmap().load(state.bitmapUrl).into(BitmapLoadTarget(media, playlist))
60+
} else if (item.media.thumbNail?.url != state.bitmapUrl) {
61+
state.bitmapUrl = item.media.thumbNail?.url
62+
Glide.with(context).asBitmap().load(state.bitmapUrl).into(BitmapLoadTarget(item.media, playlist))
6263
}
63-
appState.mediaSession?.setMetadata(metadataMapper.map(media, state.bitmap, playlist))
64+
appState.mediaSession?.setMetadata(metadataMapper.map(item.media, state.bitmap, playlist))
6465
}
6566

6667
inner class BitmapLoadTarget(
@@ -77,12 +78,12 @@ class MediaSessionManager(
7778
}
7879

7980
override fun updatePlaybackState(
80-
media: MediaDomain,
81+
item: PlaylistItemDomain,
8182
state: PlayerStateDomain,
8283
liveOffset: Long?,
8384
playlist: PlaylistDomain?
8485
) {
85-
appState.mediaSession?.setPlaybackState(playbackStateMapper.map(media, state, liveOffset, playlist))
86+
appState.mediaSession?.setPlaybackState(playbackStateMapper.map(item.media, state, liveOffset, playlist))
8687
}
8788

8889
// override fun setRemotePlaybackType() {

domain/src/commonMain/kotlin/uk/co/sentinelweb/cuer/remote/server/player/PlayerSession.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ class PlayerSession(
1313
val id: OrchestratorContract.Identifier<GUID>,
1414
var controlsListener: PlayerSessionContract.Listener,
1515
) {
16-
//var item: PlaylistItemDomain? = null
17-
var media: MediaDomain? = null
16+
var item: PlaylistItemDomain? = null
17+
// var media: MediaDomain? = null
1818
var playlist: PlaylistDomain? = null
1919
var playbackState: PlayerStateDomain? = null
2020
var liveOffset: Long? = null

domain/src/commonMain/kotlin/uk/co/sentinelweb/cuer/remote/server/player/PlayerSessionContract.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ interface PlayerSessionContract {
1717
// playlist: PlaylistDomain?
1818
// )
1919

20-
fun setMedia(media: MediaDomain, playlist: PlaylistDomain?)
20+
//fun setMedia(media: MediaDomain, playlist: PlaylistDomain?)
21+
fun setItem(item: PlaylistItemDomain, playlist: PlaylistDomain?)
2122
fun updatePlaybackState(
22-
media: MediaDomain,
23+
item: PlaylistItemDomain,
2324
state: PlayerStateDomain,
2425
liveOffset: Long?,
2526
playlist: PlaylistDomain?

domain/src/commonMain/kotlin/uk/co/sentinelweb/cuer/remote/server/player/PlayerSessionMessageMapper.kt

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package uk.co.sentinelweb.cuer.remote.server.player
22

3-
import kotlinx.datetime.Clock
4-
import uk.co.sentinelweb.cuer.app.orchestrator.OrchestratorContract
3+
import rewriteIdsToSource
54
import uk.co.sentinelweb.cuer.app.orchestrator.OrchestratorContract.Source.LOCAL_NETWORK
65
import uk.co.sentinelweb.cuer.domain.PlayerStateDomain
7-
import uk.co.sentinelweb.cuer.domain.PlaylistItemDomain
86
import uk.co.sentinelweb.cuer.domain.creator.GuidCreator
97
import uk.co.sentinelweb.cuer.remote.server.LocalRepository
108
import uk.co.sentinelweb.cuer.remote.server.locator
@@ -17,18 +15,12 @@ class PlayerSessionMessageMapper(
1715
fun map(session: PlayerSession): PlayerStatusMessage =
1816
PlayerStatusMessage(
1917
id = session.id,
20-
item = PlaylistItemDomain(
21-
// fixme remove id gen when item is stored in PlayerSession
22-
id = OrchestratorContract.Identifier(
23-
guidCreator.create(),
24-
LOCAL_NETWORK,
25-
localRepository.localNode.locator()
26-
),
27-
media = session.media!!, // fixme remove !!
28-
dateAdded = Clock.System.now(),
29-
order = 0,
30-
playlistId = null
31-
),
18+
item = if (session.item?.id?.source == LOCAL_NETWORK) {
19+
session.item ?: error("No item")
20+
} else {
21+
session.item?.rewriteIdsToSource(LOCAL_NETWORK, localRepository.localNode.locator())
22+
?: error("No item")
23+
},
3224
liveOffset = session.liveOffset ?: 0,
3325
playbackState = session.playbackState ?: PlayerStateDomain.UNKNOWN,
3426
volume = session.volume,

hub/src/main/kotlin/uk/co/sentinelweb/cuer/hub/ui/player/vlc/EmptyMediaSessionManager.kt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,21 @@ import uk.co.sentinelweb.cuer.app.util.mediasession.MediaSessionContract
55
import uk.co.sentinelweb.cuer.domain.MediaDomain
66
import uk.co.sentinelweb.cuer.domain.PlayerStateDomain
77
import uk.co.sentinelweb.cuer.domain.PlaylistDomain
8+
import uk.co.sentinelweb.cuer.domain.PlaylistItemDomain
89

910
class EmptyMediaSessionManager : MediaSessionContract.Manager {
11+
1012
override fun checkCreateMediaSession(controls: PlayerContract.PlayerControls.Listener) = Unit
1113

1214
override fun destroyMediaSession() = Unit
1315

14-
override fun setMedia(media: MediaDomain, playlist: PlaylistDomain?) = Unit
16+
override fun setItem(item: PlaylistItemDomain, playlist: PlaylistDomain?)=Unit
1517

1618
override fun updatePlaybackState(
17-
media: MediaDomain,
19+
item: PlaylistItemDomain,
1820
state: PlayerStateDomain,
1921
liveOffset: Long?,
2022
playlist: PlaylistDomain?
21-
) = Unit
22-
}
23+
) = Unit
24+
25+
}

shared/src/commonMain/kotlin/uk/co/sentinelweb/cuer/app/service/remote/player/PlayerSessionManager.kt

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@ package uk.co.sentinelweb.cuer.app.service.remote.player
33
import uk.co.sentinelweb.cuer.app.orchestrator.OrchestratorContract.Source.LOCAL
44
import uk.co.sentinelweb.cuer.app.orchestrator.toIdentifier
55
import uk.co.sentinelweb.cuer.core.wrapper.LogWrapper
6-
import uk.co.sentinelweb.cuer.domain.MediaDomain
7-
import uk.co.sentinelweb.cuer.domain.PlayerNodeDomain
8-
import uk.co.sentinelweb.cuer.domain.PlayerStateDomain
9-
import uk.co.sentinelweb.cuer.domain.PlaylistDomain
6+
import uk.co.sentinelweb.cuer.domain.*
107
import uk.co.sentinelweb.cuer.domain.creator.GuidCreator
118
import uk.co.sentinelweb.cuer.remote.server.player.PlayerSession
129
import uk.co.sentinelweb.cuer.remote.server.player.PlayerSessionContract
@@ -37,18 +34,18 @@ class PlayerSessionManager(
3734
playerSessionHolder.playerSession = null
3835
}
3936

40-
override fun setMedia(media: MediaDomain, playlist: PlaylistDomain?) {
41-
playerSessionHolder.playerSession?.media = media
37+
override fun setItem(item: PlaylistItemDomain, playlist: PlaylistDomain?) {
38+
playerSessionHolder.playerSession?.item = item
4239
playerSessionHolder.playerSession?.playlist = playlist
4340
}
4441

4542
override fun updatePlaybackState(
46-
media: MediaDomain,
43+
item: PlaylistItemDomain,
4744
state: PlayerStateDomain,
4845
liveOffset: Long?,
4946
playlist: PlaylistDomain?
5047
) {
51-
playerSessionHolder.playerSession?.media = media
48+
playerSessionHolder.playerSession?.item = item
5249
playerSessionHolder.playerSession?.playlist = playlist
5350
playerSessionHolder.playerSession?.liveOffset = liveOffset
5451
playerSessionHolder.playerSession?.playbackState = state

shared/src/commonMain/kotlin/uk/co/sentinelweb/cuer/app/ui/play_control/CastPlayerPresenter.kt

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ package uk.co.sentinelweb.cuer.app.ui.play_control
22

33
import uk.co.sentinelweb.cuer.app.ui.cast.CastController
44
import uk.co.sentinelweb.cuer.app.ui.common.navigation.NavigationModel
5+
import uk.co.sentinelweb.cuer.app.ui.common.navigation.NavigationModel.Param
6+
import uk.co.sentinelweb.cuer.app.ui.common.navigation.NavigationModel.Param.*
7+
import uk.co.sentinelweb.cuer.app.ui.common.navigation.NavigationModel.Target.FOLDER_LIST
8+
import uk.co.sentinelweb.cuer.app.ui.common.navigation.NavigationModel.Target.PLAYLIST_ITEM
59
import uk.co.sentinelweb.cuer.app.ui.common.skip.SkipContract
610
import uk.co.sentinelweb.cuer.app.ui.play_control.CastPlayerContract.DurationStyle.*
711
import uk.co.sentinelweb.cuer.app.ui.play_control.CastPlayerContract.State.TargetDetails
@@ -11,8 +15,10 @@ import uk.co.sentinelweb.cuer.app.usecase.PlayUseCase
1115
import uk.co.sentinelweb.cuer.core.wrapper.LogWrapper
1216
import uk.co.sentinelweb.cuer.domain.ImageDomain
1317
import uk.co.sentinelweb.cuer.domain.PlatformDomain
18+
import uk.co.sentinelweb.cuer.domain.PlatformDomain.FILESYSTEM
1419
import uk.co.sentinelweb.cuer.domain.PlayerStateDomain
1520
import uk.co.sentinelweb.cuer.domain.PlaylistItemDomain
21+
import uk.co.sentinelweb.cuer.domain.ext.name
1622
import uk.co.sentinelweb.cuer.domain.mappers.PlaylistAndItemMapper
1723
import uk.co.sentinelweb.cuer.remote.server.RemotesRepository
1824

@@ -270,9 +276,9 @@ class CastPlayerPresenter(
270276
NavigationModel(
271277
NavigationModel.Target.PLAYLIST,
272278
mapOf(
273-
NavigationModel.Param.PLAYLIST_ID to it.id.value,
274-
NavigationModel.Param.PLAY_NOW to false,
275-
NavigationModel.Param.SOURCE to it.source
279+
Param.PLAYLIST_ID to it.id.value,
280+
Param.PLAY_NOW to false,
281+
SOURCE to it.source
276282
)
277283
)
278284
)
@@ -282,24 +288,26 @@ class CastPlayerPresenter(
282288
override fun onPlaylistItemClick() {
283289
state.playlistItem?.let { item ->
284290
when (item.media.platform) {
285-
PlatformDomain.FILESYSTEM -> (item.id?.locator
291+
FILESYSTEM -> (item.id?.locator
292+
?.also { log.d("locator: $it") }
286293
?.let { remotesRepository.getByLocator(it) })
294+
?.also { log.d("found: ${it.name()}") }
287295
?.let { foundNode ->
288296
NavigationModel(
289-
NavigationModel.Target.FOLDER_LIST,
297+
FOLDER_LIST,
290298
mapOf(
291-
NavigationModel.Param.REMOTE_ID to foundNode.id?.id?.value,
292-
NavigationModel.Param.FILE_PATH to item.media.platformId.substringBeforeLast("/")
299+
REMOTE_ID to foundNode.id?.id?.value,
300+
FILE_PATH to item.media.platformId.substringBeforeLast("/")
293301
)
294302
)
295303
}
296304

297305
else -> NavigationModel(
298-
NavigationModel.Target.PLAYLIST_ITEM,
306+
PLAYLIST_ITEM,
299307
mapOf(
300-
NavigationModel.Param.PLAYLIST_ITEM to item,
308+
Param.PLAYLIST_ITEM to item,
301309
//FRAGMENT_NAV_EXTRAS to view.makeItemTransitemionExtras(),
302-
NavigationModel.Param.SOURCE to item.id!!.source
310+
SOURCE to item.id!!.source
303311
)
304312
)
305313
}?.also { view.navigate(it) }

0 commit comments

Comments
 (0)