mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-09 16:11:20 +02:00
Add device profile & improvement playback reporting
This commit is contained in:
parent
3bf382a6b9
commit
bd75539cb6
19 changed files with 1056 additions and 117 deletions
|
|
@ -1,49 +0,0 @@
|
|||
package com.github.damontecres.dolphin.ui.cards
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.tv.material3.Text
|
||||
import com.github.damontecres.dolphin.data.model.BaseItem
|
||||
|
||||
@Composable
|
||||
fun CardRow(
|
||||
title: String,
|
||||
items: List<BaseItem?>,
|
||||
onClickItem: (BaseItem) -> Unit,
|
||||
onLongClickItem: (BaseItem) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
modifier = modifier,
|
||||
) {
|
||||
Text(
|
||||
text = title,
|
||||
)
|
||||
LazyRow(
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
contentPadding = PaddingValues(8.dp),
|
||||
modifier =
|
||||
Modifier
|
||||
.padding(start = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
items(items) { item ->
|
||||
ItemCard(
|
||||
item = item,
|
||||
onClick = { if (item != null) onClickItem.invoke(item) },
|
||||
onLongClick = { if (item != null) onLongClickItem.invoke(item) },
|
||||
modifier = Modifier,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
package com.github.damontecres.dolphin.ui.cards
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.focus.focusRestorer
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.tv.material3.MaterialTheme
|
||||
import androidx.tv.material3.Text
|
||||
import com.github.damontecres.dolphin.data.model.BaseItem
|
||||
import com.github.damontecres.dolphin.util.FocusPair
|
||||
|
||||
@Composable
|
||||
fun ItemRow(
|
||||
title: String,
|
||||
items: List<BaseItem?>,
|
||||
onClickItem: (BaseItem) -> Unit,
|
||||
onLongClickItem: (BaseItem) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
focusPair: FocusPair? = null,
|
||||
cardOnFocus: ((isFocused: Boolean, index: Int) -> Unit)? = null,
|
||||
) {
|
||||
val state = rememberLazyListState()
|
||||
val firstFocus = remember { FocusRequester() }
|
||||
var focusedIndex by remember { mutableIntStateOf(focusPair?.column ?: 0) }
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
modifier = modifier,
|
||||
) {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
LazyRow(
|
||||
state = state,
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
contentPadding = PaddingValues(8.dp),
|
||||
modifier =
|
||||
Modifier
|
||||
.padding(start = 16.dp)
|
||||
.fillMaxWidth()
|
||||
.focusRestorer(focusPair?.focusRequester ?: firstFocus),
|
||||
) {
|
||||
itemsIndexed(items) { index, item ->
|
||||
val cardModifier =
|
||||
if (index == 0 && focusPair == null) {
|
||||
Modifier.focusRequester(firstFocus)
|
||||
} else {
|
||||
if (focusPair != null && focusPair.column == index) {
|
||||
Modifier.focusRequester(focusPair.focusRequester)
|
||||
} else {
|
||||
Modifier
|
||||
}
|
||||
}.onFocusChanged {
|
||||
if (it.isFocused) {
|
||||
focusedIndex = index
|
||||
}
|
||||
cardOnFocus?.invoke(it.isFocused, index)
|
||||
}
|
||||
ItemCard(
|
||||
item = item,
|
||||
onClick = { if (item != null) onClickItem.invoke(item) },
|
||||
onLongClick = { if (item != null) onLongClickItem.invoke(item) },
|
||||
modifier = cardModifier,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,9 @@ import com.github.damontecres.dolphin.ui.nav.Destination
|
|||
import com.github.damontecres.dolphin.ui.nav.NavigationManager
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import org.jellyfin.sdk.api.client.ApiClient
|
||||
import org.jellyfin.sdk.model.extensions.ticks
|
||||
import javax.inject.Inject
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
@HiltViewModel
|
||||
class EpisodeViewModel
|
||||
|
|
@ -64,6 +66,25 @@ fun EpisodeDetails(
|
|||
Text(text = it)
|
||||
}
|
||||
}
|
||||
dto.userData?.playbackPositionTicks?.ticks?.let {
|
||||
if (it > 60.seconds) {
|
||||
item {
|
||||
Button(
|
||||
onClick = {
|
||||
navigationManager.navigateTo(
|
||||
Destination.Playback(
|
||||
item.id,
|
||||
it.inWholeMilliseconds,
|
||||
item,
|
||||
),
|
||||
)
|
||||
},
|
||||
) {
|
||||
Text(text = "Resume")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
item {
|
||||
Button(
|
||||
onClick = {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import androidx.tv.material3.Text
|
|||
import com.github.damontecres.dolphin.data.model.BaseItem
|
||||
import com.github.damontecres.dolphin.data.model.Video
|
||||
import com.github.damontecres.dolphin.preferences.UserPreferences
|
||||
import com.github.damontecres.dolphin.ui.cards.CardRow
|
||||
import com.github.damontecres.dolphin.ui.cards.ItemRow
|
||||
import com.github.damontecres.dolphin.ui.nav.Destination
|
||||
import com.github.damontecres.dolphin.ui.nav.NavigationManager
|
||||
import com.github.damontecres.dolphin.util.DolphinPager
|
||||
|
|
@ -83,7 +83,7 @@ fun SeasonDetails(
|
|||
Text(text = item.name ?: "Unknown")
|
||||
}
|
||||
item {
|
||||
CardRow(
|
||||
ItemRow(
|
||||
title = "Episodes",
|
||||
items = episodes,
|
||||
onClickItem = { navigationManager.navigateTo(it.destination()) },
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import androidx.tv.material3.Text
|
|||
import com.github.damontecres.dolphin.data.model.BaseItem
|
||||
import com.github.damontecres.dolphin.data.model.Video
|
||||
import com.github.damontecres.dolphin.preferences.UserPreferences
|
||||
import com.github.damontecres.dolphin.ui.cards.CardRow
|
||||
import com.github.damontecres.dolphin.ui.cards.ItemRow
|
||||
import com.github.damontecres.dolphin.ui.nav.Destination
|
||||
import com.github.damontecres.dolphin.ui.nav.NavigationManager
|
||||
import com.github.damontecres.dolphin.util.DolphinPager
|
||||
|
|
@ -88,7 +88,7 @@ fun SeriesDetails(
|
|||
Text(text = item.name ?: "Unknown")
|
||||
}
|
||||
item {
|
||||
CardRow(
|
||||
ItemRow(
|
||||
title = "Seasons",
|
||||
items = seasons,
|
||||
onClickItem = { navigationManager.navigateTo(it.destination()) },
|
||||
|
|
|
|||
|
|
@ -4,9 +4,7 @@ import androidx.compose.foundation.layout.Arrangement
|
|||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
|
|
@ -18,12 +16,11 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
|||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.tv.material3.Text
|
||||
import com.github.damontecres.dolphin.data.model.BaseItem
|
||||
import com.github.damontecres.dolphin.isNotNullOrBlank
|
||||
import com.github.damontecres.dolphin.preferences.UserPreferences
|
||||
import com.github.damontecres.dolphin.ui.DefaultItemFields
|
||||
import com.github.damontecres.dolphin.ui.cards.ItemCard
|
||||
import com.github.damontecres.dolphin.ui.cards.ItemRow
|
||||
import com.github.damontecres.dolphin.ui.nav.Destination
|
||||
import com.github.damontecres.dolphin.ui.nav.NavigationManager
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
|
|
@ -165,56 +162,24 @@ fun MainPage(
|
|||
val homeRows by viewModel.homeRows.observeAsState(listOf())
|
||||
Column(modifier = modifier) {
|
||||
// TODO header?
|
||||
LazyColumn {
|
||||
homeRows.forEach { row ->
|
||||
item {
|
||||
HomePageRow(
|
||||
row = row,
|
||||
onClickItem = {
|
||||
navigationManager.navigateTo(
|
||||
Destination.MediaItem(
|
||||
it.id,
|
||||
it.type,
|
||||
),
|
||||
)
|
||||
},
|
||||
onLongClickItem = {},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun HomePageRow(
|
||||
row: HomeRow,
|
||||
onClickItem: (BaseItem) -> Unit,
|
||||
onLongClickItem: (BaseItem) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
modifier = modifier,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(row.section.nameRes),
|
||||
)
|
||||
LazyRow(
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
contentPadding = PaddingValues(8.dp),
|
||||
modifier =
|
||||
Modifier
|
||||
.padding(start = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
LazyColumn(
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
contentPadding = PaddingValues(16.dp),
|
||||
) {
|
||||
items(row.items) { item ->
|
||||
ItemCard(
|
||||
item = item,
|
||||
onClick = { onClickItem.invoke(item) },
|
||||
onLongClick = { onLongClickItem.invoke(item) },
|
||||
modifier = Modifier,
|
||||
items(homeRows) { row ->
|
||||
ItemRow(
|
||||
title = stringResource(row.section.nameRes),
|
||||
items = row.items,
|
||||
onClickItem = {
|
||||
navigationManager.navigateTo(
|
||||
Destination.MediaItem(
|
||||
it.id,
|
||||
it.type,
|
||||
),
|
||||
)
|
||||
},
|
||||
onLongClickItem = {},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,10 +10,12 @@ import androidx.navigation3.runtime.rememberSavedStateNavEntryDecorator
|
|||
import androidx.navigation3.scene.rememberSceneSetupNavEntryDecorator
|
||||
import androidx.navigation3.ui.NavDisplay
|
||||
import com.github.damontecres.dolphin.preferences.UserPreferences
|
||||
import org.jellyfin.sdk.model.api.DeviceProfile
|
||||
|
||||
@Composable
|
||||
fun ApplicationContent(
|
||||
preferences: UserPreferences,
|
||||
deviceProfile: DeviceProfile,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val backStack = rememberNavBackStack(Destination.Main)
|
||||
|
|
@ -51,6 +53,7 @@ fun ApplicationContent(
|
|||
destination = key,
|
||||
preferences = preferences,
|
||||
navigationManager = navigationManager,
|
||||
deviceProfile = deviceProfile,
|
||||
modifier = modifier.fillMaxSize(),
|
||||
)
|
||||
} else {
|
||||
|
|
@ -58,6 +61,7 @@ fun ApplicationContent(
|
|||
destination = key,
|
||||
preferences = preferences,
|
||||
navigationManager = navigationManager,
|
||||
deviceProfile = deviceProfile,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,12 +6,14 @@ import com.github.damontecres.dolphin.preferences.UserPreferences
|
|||
import com.github.damontecres.dolphin.ui.detail.MediaItemContent
|
||||
import com.github.damontecres.dolphin.ui.main.MainPage
|
||||
import com.github.damontecres.dolphin.ui.playback.PlaybackContent
|
||||
import org.jellyfin.sdk.model.api.DeviceProfile
|
||||
|
||||
@Composable
|
||||
fun DestinationContent(
|
||||
destination: Destination,
|
||||
preferences: UserPreferences,
|
||||
navigationManager: NavigationManager,
|
||||
deviceProfile: DeviceProfile,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
when (destination) {
|
||||
|
|
@ -35,6 +37,7 @@ fun DestinationContent(
|
|||
PlaybackContent(
|
||||
preferences = preferences,
|
||||
navigationManager = navigationManager,
|
||||
deviceProfile = deviceProfile,
|
||||
destination = destination,
|
||||
modifier = modifier,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ import kotlinx.coroutines.launch
|
|||
import org.jellyfin.sdk.api.client.ApiClient
|
||||
import org.jellyfin.sdk.api.client.extensions.userViewsApi
|
||||
import org.jellyfin.sdk.model.api.CollectionType
|
||||
import org.jellyfin.sdk.model.api.DeviceProfile
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
|
|
@ -81,6 +82,7 @@ fun NavDrawer(
|
|||
destination: Destination,
|
||||
preferences: UserPreferences,
|
||||
navigationManager: NavigationManager,
|
||||
deviceProfile: DeviceProfile,
|
||||
modifier: Modifier = Modifier,
|
||||
viewModel: NavDrawerViewModel = hiltViewModel(LocalView.current.findViewTreeViewModelStoreOwner()!!),
|
||||
) {
|
||||
|
|
@ -126,7 +128,7 @@ fun NavDrawer(
|
|||
IconNavItem(
|
||||
text = "Home",
|
||||
icon = Icons.Default.Home,
|
||||
onClick = {},
|
||||
onClick = { navigationManager.goToHome() },
|
||||
)
|
||||
}
|
||||
items(libraries) {
|
||||
|
|
@ -158,6 +160,7 @@ fun NavDrawer(
|
|||
destination = destination,
|
||||
preferences = preferences,
|
||||
navigationManager = navigationManager,
|
||||
deviceProfile = deviceProfile,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ import com.github.damontecres.dolphin.ui.nav.Destination
|
|||
import com.github.damontecres.dolphin.ui.nav.NavigationManager
|
||||
import com.github.damontecres.stashapp.ui.components.playback.SkipIndicator
|
||||
import com.github.damontecres.stashapp.ui.components.playback.rememberSeekBarState
|
||||
import org.jellyfin.sdk.model.api.DeviceProfile
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
@OptIn(UnstableApi::class)
|
||||
|
|
@ -57,13 +58,14 @@ import kotlin.time.Duration.Companion.milliseconds
|
|||
fun PlaybackContent(
|
||||
preferences: UserPreferences,
|
||||
navigationManager: NavigationManager,
|
||||
deviceProfile: DeviceProfile,
|
||||
destination: Destination.Playback,
|
||||
modifier: Modifier = Modifier,
|
||||
viewModel: PlaybackViewModel = hiltViewModel(),
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
LaunchedEffect(destination.itemId) {
|
||||
viewModel.init(destination.itemId, destination.item)
|
||||
viewModel.init(destination, deviceProfile)
|
||||
}
|
||||
val player = viewModel.player
|
||||
val stream by viewModel.stream.observeAsState(null)
|
||||
|
|
|
|||
|
|
@ -5,9 +5,10 @@ import androidx.core.net.toUri
|
|||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.media3.common.C
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.exoplayer.ExoPlayer
|
||||
import com.github.damontecres.dolphin.data.model.BaseItem
|
||||
import com.github.damontecres.dolphin.ui.nav.Destination
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
|
@ -15,9 +16,15 @@ import kotlinx.coroutines.launch
|
|||
import kotlinx.coroutines.withContext
|
||||
import org.jellyfin.sdk.api.client.ApiClient
|
||||
import org.jellyfin.sdk.api.client.extensions.mediaInfoApi
|
||||
import org.jellyfin.sdk.api.client.extensions.playStateApi
|
||||
import org.jellyfin.sdk.api.client.extensions.videosApi
|
||||
import org.jellyfin.sdk.model.api.BaseItemKind
|
||||
import org.jellyfin.sdk.model.api.DeviceProfile
|
||||
import org.jellyfin.sdk.model.api.PlayMethod
|
||||
import org.jellyfin.sdk.model.api.PlaybackInfoDto
|
||||
import org.jellyfin.sdk.model.api.PlaybackOrder
|
||||
import org.jellyfin.sdk.model.api.PlaybackStartInfo
|
||||
import org.jellyfin.sdk.model.api.RepeatMode
|
||||
import org.jellyfin.sdk.model.extensions.ticks
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
|
|
@ -69,9 +76,11 @@ class PlaybackViewModel
|
|||
}
|
||||
|
||||
fun init(
|
||||
itemId: UUID,
|
||||
item: BaseItem?,
|
||||
destination: Destination.Playback,
|
||||
deviceProfile: DeviceProfile,
|
||||
) {
|
||||
val itemId = destination.itemId
|
||||
val item = destination.item
|
||||
if (item != null) {
|
||||
title.value = item.name
|
||||
val base = item.data
|
||||
|
|
@ -99,7 +108,7 @@ class PlaybackViewModel
|
|||
// TODO device profile, etc
|
||||
PlaybackInfoDto(
|
||||
startTimeTicks = null,
|
||||
deviceProfile = null,
|
||||
deviceProfile = deviceProfile,
|
||||
enableDirectStream = true,
|
||||
enableDirectPlay = true,
|
||||
maxAudioChannels = null,
|
||||
|
|
@ -134,6 +143,23 @@ class PlaybackViewModel
|
|||
else -> throw Exception("No supported playback method")
|
||||
}
|
||||
val decision = StreamDecision(itemId, mediaUrl, transcodeType)
|
||||
api.playStateApi.reportPlaybackStart(
|
||||
PlaybackStartInfo(
|
||||
itemId = itemId,
|
||||
canSeek = false,
|
||||
isPaused = true,
|
||||
isMuted = false,
|
||||
playMethod =
|
||||
when {
|
||||
it.supportsDirectPlay -> PlayMethod.DIRECT_PLAY
|
||||
it.supportsDirectStream -> PlayMethod.DIRECT_STREAM
|
||||
it.supportsTranscoding -> PlayMethod.TRANSCODE
|
||||
else -> throw Exception("No supported playback method")
|
||||
},
|
||||
repeatMode = RepeatMode.REPEAT_NONE,
|
||||
playbackOrder = PlaybackOrder.DEFAULT,
|
||||
),
|
||||
)
|
||||
withContext(Dispatchers.Main) {
|
||||
val activityListener =
|
||||
TrackActivityPlaybackListener(api, itemId, player)
|
||||
|
|
@ -141,7 +167,10 @@ class PlaybackViewModel
|
|||
player.addListener(activityListener)
|
||||
duration.value = source.runTimeTicks?.ticks
|
||||
stream.value = decision
|
||||
player.setMediaItem(decision.mediaItem)
|
||||
player.setMediaItem(
|
||||
decision.mediaItem,
|
||||
if (destination.positionMs > 0) destination.positionMs else C.TIME_UNSET,
|
||||
)
|
||||
player.prepare()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import org.jellyfin.sdk.api.client.extensions.playStateApi
|
|||
import org.jellyfin.sdk.model.api.PlayMethod
|
||||
import org.jellyfin.sdk.model.api.PlaybackOrder
|
||||
import org.jellyfin.sdk.model.api.PlaybackProgressInfo
|
||||
import org.jellyfin.sdk.model.api.PlaybackStopInfo
|
||||
import org.jellyfin.sdk.model.api.RepeatMode
|
||||
import org.jellyfin.sdk.model.extensions.inWholeTicks
|
||||
import timber.log.Timber
|
||||
|
|
@ -73,6 +74,15 @@ class TrackActivityPlaybackListener(
|
|||
fun release() {
|
||||
task.cancel()
|
||||
TIMER.purge()
|
||||
coroutineScope.launch {
|
||||
api.playStateApi.reportPlaybackStopped(
|
||||
PlaybackStopInfo(
|
||||
itemId = itemId,
|
||||
positionTicks = player.currentPosition.milliseconds.inWholeTicks,
|
||||
failed = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onIsPlayingChanged(isPlaying: Boolean) {
|
||||
|
|
@ -96,12 +106,14 @@ class TrackActivityPlaybackListener(
|
|||
private fun saveActivity(position: Long) {
|
||||
coroutineScope.launch {
|
||||
val totalDuration = totalPlayDurationMilliseconds.get()
|
||||
val calcPosition = (if (position >= 0) position else player.currentPosition).milliseconds.inWholeTicks
|
||||
val calcPosition =
|
||||
(if (position >= 0) position else player.currentPosition).milliseconds
|
||||
Timber.v("saveActivity: itemId=$itemId, pos=$calcPosition")
|
||||
// TODO parameters
|
||||
api.playStateApi.reportPlaybackProgress(
|
||||
PlaybackProgressInfo(
|
||||
itemId = itemId,
|
||||
positionTicks = calcPosition,
|
||||
positionTicks = calcPosition.inWholeTicks,
|
||||
canSeek = true,
|
||||
isPaused = !player.isPlaying,
|
||||
isMuted = false,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue