Post start, stop and progress of media to the server
This commit is contained in:
parent
e87a9804ec
commit
00ec736ff4
4 changed files with 68 additions and 1 deletions
|
@ -34,6 +34,7 @@ class JellyfinApi(context: Context, baseUrl: String) {
|
|||
val sessionApi = SessionApi(api)
|
||||
val videosApi = VideosApi(api)
|
||||
val mediaInfoApi = MediaInfoApi(api)
|
||||
val playstateApi = PlayStateApi(api)
|
||||
|
||||
companion object {
|
||||
@Volatile
|
||||
|
|
|
@ -19,4 +19,10 @@ interface JellyfinRepository {
|
|||
suspend fun getMediaSources(itemId: UUID): List<MediaSourceInfo>
|
||||
|
||||
suspend fun getStreamUrl(itemId: UUID, mediaSourceId: String): String
|
||||
|
||||
suspend fun postPlaybackStart(itemId: UUID)
|
||||
|
||||
suspend fun postPlaybackStop(itemId: UUID, positionTicks: Long)
|
||||
|
||||
suspend fun postPlaybackProgress(itemId: UUID, positionTicks: Long, isPaused: Boolean)
|
||||
}
|
|
@ -101,7 +101,7 @@ class JellyfinRepositoryImpl(private val jellyfinApi: JellyfinApi) : JellyfinRep
|
|||
}
|
||||
|
||||
override suspend fun getStreamUrl(itemId: UUID, mediaSourceId: String): String {
|
||||
var streamUrl: String = ""
|
||||
var streamUrl = ""
|
||||
withContext(Dispatchers.IO) {
|
||||
try {
|
||||
streamUrl = jellyfinApi.videosApi.getVideoStreamUrl(
|
||||
|
@ -115,4 +115,24 @@ class JellyfinRepositoryImpl(private val jellyfinApi: JellyfinApi) : JellyfinRep
|
|||
}
|
||||
return streamUrl
|
||||
}
|
||||
|
||||
override suspend fun postPlaybackStart(itemId: UUID) {
|
||||
Log.d("PlayerActivity", "Sending start $itemId")
|
||||
withContext(Dispatchers.IO) {
|
||||
jellyfinApi.playstateApi.onPlaybackStart(jellyfinApi.userId!!, itemId)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun postPlaybackStop(itemId: UUID, positionTicks: Long) {
|
||||
Log.d("PlayerActivity", "Sending stop $itemId")
|
||||
withContext(Dispatchers.IO) {
|
||||
jellyfinApi.playstateApi.onPlaybackStopped(jellyfinApi.userId!!, itemId, positionTicks = positionTicks)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun postPlaybackProgress(itemId: UUID, positionTicks: Long, isPaused: Boolean) {
|
||||
withContext(Dispatchers.IO) {
|
||||
jellyfinApi.playstateApi.onPlaybackProgress(jellyfinApi.userId!!, itemId, positionTicks = positionTicks, isPaused = isPaused)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
package dev.jdtech.jellyfin.viewmodels
|
||||
|
||||
import android.app.Application
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
|
@ -11,6 +13,7 @@ import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
|
|||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dev.jdtech.jellyfin.repository.JellyfinRepository
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -30,6 +33,8 @@ constructor(
|
|||
private var playbackPosition: Long = 0
|
||||
private var _playbackStateListener: PlaybackStateListener
|
||||
|
||||
private var itemId: UUID? = null
|
||||
|
||||
val playbackStateListener: PlaybackStateListener
|
||||
get() = _playbackStateListener
|
||||
|
||||
|
@ -38,6 +43,8 @@ constructor(
|
|||
}
|
||||
|
||||
fun initializePlayer(itemId: UUID, mediaSourceId: String, playbackPosition: Long) {
|
||||
this.itemId = itemId
|
||||
|
||||
val renderersFactory =
|
||||
DefaultRenderersFactory(application).setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON)
|
||||
val trackSelector = DefaultTrackSelector(application)
|
||||
|
@ -62,10 +69,22 @@ constructor(
|
|||
player.playWhenReady = playWhenReady
|
||||
player.prepare()
|
||||
_player.value = player
|
||||
|
||||
jellyfinRepository.postPlaybackStart(itemId)
|
||||
}
|
||||
|
||||
pollPosition(player, itemId)
|
||||
}
|
||||
|
||||
private fun releasePlayer() {
|
||||
itemId?.let { itemId ->
|
||||
_player.value?.let { player ->
|
||||
runBlocking {
|
||||
jellyfinRepository.postPlaybackStop(itemId, player.currentPosition.times(10000))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (player.value != null) {
|
||||
playWhenReady = player.value!!.playWhenReady
|
||||
playbackPosition = player.value!!.currentPosition
|
||||
|
@ -76,6 +95,27 @@ constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun pollPosition(player: SimpleExoPlayer, itemId: UUID) {
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
val runnable: Runnable = object : Runnable {
|
||||
override fun run() {
|
||||
viewModelScope.launch {
|
||||
Log.d(
|
||||
"PlayerActivity",
|
||||
"Posting progress of $itemId, position: ${player.currentPosition}"
|
||||
)
|
||||
jellyfinRepository.postPlaybackProgress(
|
||||
itemId,
|
||||
player.currentPosition.times(10000),
|
||||
!player.isPlaying
|
||||
)
|
||||
}
|
||||
handler.postDelayed(this, 2000)
|
||||
}
|
||||
}
|
||||
handler.post(runnable)
|
||||
}
|
||||
|
||||
class PlaybackStateListener : Player.Listener {
|
||||
private val _navigateBack = MutableLiveData<Boolean>()
|
||||
val navigateBack: LiveData<Boolean> = _navigateBack
|
||||
|
|
Loading…
Reference in a new issue