Post start, stop and progress of media to the server

This commit is contained in:
Jarne Demeulemeester 2021-07-14 12:00:05 +02:00
parent e87a9804ec
commit 00ec736ff4
No known key found for this signature in database
GPG key ID: 60884A0C1EBA43E5
4 changed files with 68 additions and 1 deletions

View file

@ -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

View file

@ -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)
}

View file

@ -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)
}
}
}

View file

@ -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