Fix:Android sync fails when restarting playback session

This commit is contained in:
advplyr 2023-02-04 10:11:31 -06:00
parent 62a5a2d069
commit a12eb7efdf
3 changed files with 30 additions and 21 deletions

View file

@ -40,7 +40,7 @@ class MediaProgressSyncer(val playerNotificationService:PlayerNotificationServic
private val currentDisplayTitle get() = currentPlaybackSession?.displayTitle ?: "Unset"
private val currentIsLocal get() = currentPlaybackSession?.isLocal == true
val currentSessionId get() = currentPlaybackSession?.id ?: ""
private val currentSessionId get() = currentPlaybackSession?.id ?: ""
private val currentPlaybackDuration get() = currentPlaybackSession?.duration ?: 0.0
fun start(playbackSession:PlaybackSession) {
@ -62,8 +62,8 @@ class MediaProgressSyncer(val playerNotificationService:PlayerNotificationServic
listeningTimerRunning = true
lastSyncTime = System.currentTimeMillis()
Log.d(tag, "start: init last sync time $lastSyncTime")
currentPlaybackSession = playbackSession.clone()
Log.d(tag, "start: init last sync time $lastSyncTime with playback session id=${currentPlaybackSession?.id}")
listeningTimerTask = Timer("ListeningTimer", false).schedule(15000L, 15000L) {
Handler(Looper.getMainLooper()).post() {
@ -251,7 +251,7 @@ class MediaProgressSyncer(val playerNotificationService:PlayerNotificationServic
playerNotificationService.alertSyncFailing() // Show alert in client
failedSyncs = 0
}
Log.e(tag, "Local Progress sync failed ($failedSyncs) to send to server $currentDisplayTitle for time $currentTime")
Log.e(tag, "Local Progress sync failed ($failedSyncs) to send to server $currentDisplayTitle for time $currentTime with session id=${it.id}")
}
cb(SyncResult(true, syncSuccess, errorMsg))
@ -274,7 +274,7 @@ class MediaProgressSyncer(val playerNotificationService:PlayerNotificationServic
playerNotificationService.alertSyncFailing() // Show alert in client
failedSyncs = 0
}
Log.e(tag, "Progress sync failed ($failedSyncs) to send to server $currentDisplayTitle for time $currentTime")
Log.e(tag, "Progress sync failed ($failedSyncs) to send to server $currentDisplayTitle for time $currentTime with session id=${currentSessionId}")
}
cb(SyncResult(true, syncSuccess, errorMsg))
}

View file

@ -481,16 +481,19 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
val libraryItemId = playbackSession.libraryItemId ?: "" // Must be true since direct play
val episodeId = playbackSession.episodeId
apiHandler.playLibraryItem(libraryItemId, episodeId, playItemRequestPayload) {
if (it == null) { // Play request failed
clientEventEmitter?.onPlaybackFailed(errorMessage)
closePlayback(true)
} else {
Handler(Looper.getMainLooper()).post {
preparePlayer(it, true, null)
mediaProgressSyncer.stop(false) {
apiHandler.playLibraryItem(libraryItemId, episodeId, playItemRequestPayload) {
if (it == null) { // Play request failed
clientEventEmitter?.onPlaybackFailed(errorMessage)
closePlayback(true)
} else {
Handler(Looper.getMainLooper()).post {
preparePlayer(it, true, null)
}
}
}
}
} else {
clientEventEmitter?.onPlaybackFailed(errorMessage)
closePlayback(true)
@ -528,19 +531,22 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
}
}
fun startNewPlaybackSession() {
private fun startNewPlaybackSession() {
currentPlaybackSession?.let { playbackSession ->
val forceTranscode = playbackSession.isHLS // If already HLS then force
val playItemRequestPayload = getPlayItemRequestPayload(forceTranscode)
val libraryItemId = playbackSession.libraryItemId ?: "" // Must be true since direct play
val episodeId = playbackSession.episodeId
apiHandler.playLibraryItem(libraryItemId, episodeId, playItemRequestPayload) {
if (it == null) {
Log.e(tag, "Failed to start new playback session")
} else {
Handler(Looper.getMainLooper()).post {
preparePlayer(it, true, null)
mediaProgressSyncer.stop(false) {
apiHandler.playLibraryItem(libraryItemId, episodeId, playItemRequestPayload) {
if (it == null) {
Log.e(tag, "Failed to start new playback session")
} else {
Log.d(tag, "New playback session response from server with session id ${it.id} for \"${it.displayTitle}\"")
Handler(Looper.getMainLooper()).post {
preparePlayer(it, true, null)
}
}
}
}
@ -781,6 +787,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
currentPlaybackSession?.currentTime = timeToSeek / 1000.0
val newWindowIndex = currentPlaybackSession?.getCurrentTrackIndex() ?: 0
val newTimeOffset = currentPlaybackSession?.getCurrentTrackTimeMs() ?: 0
Log.d(tag, "seekPlayer seekTo $newWindowIndex | $newTimeOffset")
currentPlayer.seekTo(newWindowIndex, newTimeOffset)
} else {
currentPlayer.seekTo(timeToSeek)
@ -849,7 +856,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
return if(currentPlayer == castPlayer) PLAYER_CAST else PLAYER_EXO
}
fun getDeviceInfo(): DeviceInfo {
private fun getDeviceInfo(): DeviceInfo {
/* EXAMPLE
manufacturer: Google
model: Pixel 6

View file

@ -45,13 +45,15 @@ class ApiHandler(var ctx:Context) {
makeRequest(request, httpClient, cb)
}
fun postRequest(endpoint:String, payload: JSObject, config:ServerConnectionConfig?, cb: (JSObject) -> Unit) {
private fun postRequest(endpoint:String, payload: JSObject, config:ServerConnectionConfig?, cb: (JSObject) -> Unit) {
val address = config?.address ?: DeviceManager.serverAddress
val token = config?.token ?: DeviceManager.token
val mediaType = "application/json; charset=utf-8".toMediaType()
val requestBody = payload.toString().toRequestBody(mediaType)
val requestUrl = "${address}$endpoint"
Log.d(tag, "postRequest to $requestUrl")
val request = Request.Builder().post(requestBody)
.url("${address}$endpoint").addHeader("Authorization", "Bearer ${token}")
.url(requestUrl).addHeader("Authorization", "Bearer ${token}")
.build()
makeRequest(request, null, cb)
}