mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2025-08-28 13:58:23 +02:00
Fix:Android sync fails when restarting playback session
This commit is contained in:
parent
62a5a2d069
commit
a12eb7efdf
3 changed files with 30 additions and 21 deletions
|
@ -40,7 +40,7 @@ class MediaProgressSyncer(val playerNotificationService:PlayerNotificationServic
|
||||||
|
|
||||||
private val currentDisplayTitle get() = currentPlaybackSession?.displayTitle ?: "Unset"
|
private val currentDisplayTitle get() = currentPlaybackSession?.displayTitle ?: "Unset"
|
||||||
private val currentIsLocal get() = currentPlaybackSession?.isLocal == true
|
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
|
private val currentPlaybackDuration get() = currentPlaybackSession?.duration ?: 0.0
|
||||||
|
|
||||||
fun start(playbackSession:PlaybackSession) {
|
fun start(playbackSession:PlaybackSession) {
|
||||||
|
@ -62,8 +62,8 @@ class MediaProgressSyncer(val playerNotificationService:PlayerNotificationServic
|
||||||
|
|
||||||
listeningTimerRunning = true
|
listeningTimerRunning = true
|
||||||
lastSyncTime = System.currentTimeMillis()
|
lastSyncTime = System.currentTimeMillis()
|
||||||
Log.d(tag, "start: init last sync time $lastSyncTime")
|
|
||||||
currentPlaybackSession = playbackSession.clone()
|
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) {
|
listeningTimerTask = Timer("ListeningTimer", false).schedule(15000L, 15000L) {
|
||||||
Handler(Looper.getMainLooper()).post() {
|
Handler(Looper.getMainLooper()).post() {
|
||||||
|
@ -251,7 +251,7 @@ class MediaProgressSyncer(val playerNotificationService:PlayerNotificationServic
|
||||||
playerNotificationService.alertSyncFailing() // Show alert in client
|
playerNotificationService.alertSyncFailing() // Show alert in client
|
||||||
failedSyncs = 0
|
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))
|
cb(SyncResult(true, syncSuccess, errorMsg))
|
||||||
|
@ -274,7 +274,7 @@ class MediaProgressSyncer(val playerNotificationService:PlayerNotificationServic
|
||||||
playerNotificationService.alertSyncFailing() // Show alert in client
|
playerNotificationService.alertSyncFailing() // Show alert in client
|
||||||
failedSyncs = 0
|
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))
|
cb(SyncResult(true, syncSuccess, errorMsg))
|
||||||
}
|
}
|
||||||
|
|
|
@ -481,16 +481,19 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
||||||
|
|
||||||
val libraryItemId = playbackSession.libraryItemId ?: "" // Must be true since direct play
|
val libraryItemId = playbackSession.libraryItemId ?: "" // Must be true since direct play
|
||||||
val episodeId = playbackSession.episodeId
|
val episodeId = playbackSession.episodeId
|
||||||
apiHandler.playLibraryItem(libraryItemId, episodeId, playItemRequestPayload) {
|
mediaProgressSyncer.stop(false) {
|
||||||
if (it == null) { // Play request failed
|
apiHandler.playLibraryItem(libraryItemId, episodeId, playItemRequestPayload) {
|
||||||
clientEventEmitter?.onPlaybackFailed(errorMessage)
|
if (it == null) { // Play request failed
|
||||||
closePlayback(true)
|
clientEventEmitter?.onPlaybackFailed(errorMessage)
|
||||||
} else {
|
closePlayback(true)
|
||||||
Handler(Looper.getMainLooper()).post {
|
} else {
|
||||||
preparePlayer(it, true, null)
|
Handler(Looper.getMainLooper()).post {
|
||||||
|
preparePlayer(it, true, null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
clientEventEmitter?.onPlaybackFailed(errorMessage)
|
clientEventEmitter?.onPlaybackFailed(errorMessage)
|
||||||
closePlayback(true)
|
closePlayback(true)
|
||||||
|
@ -528,19 +531,22 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startNewPlaybackSession() {
|
private fun startNewPlaybackSession() {
|
||||||
currentPlaybackSession?.let { playbackSession ->
|
currentPlaybackSession?.let { playbackSession ->
|
||||||
val forceTranscode = playbackSession.isHLS // If already HLS then force
|
val forceTranscode = playbackSession.isHLS // If already HLS then force
|
||||||
val playItemRequestPayload = getPlayItemRequestPayload(forceTranscode)
|
val playItemRequestPayload = getPlayItemRequestPayload(forceTranscode)
|
||||||
|
|
||||||
val libraryItemId = playbackSession.libraryItemId ?: "" // Must be true since direct play
|
val libraryItemId = playbackSession.libraryItemId ?: "" // Must be true since direct play
|
||||||
val episodeId = playbackSession.episodeId
|
val episodeId = playbackSession.episodeId
|
||||||
apiHandler.playLibraryItem(libraryItemId, episodeId, playItemRequestPayload) {
|
mediaProgressSyncer.stop(false) {
|
||||||
if (it == null) {
|
apiHandler.playLibraryItem(libraryItemId, episodeId, playItemRequestPayload) {
|
||||||
Log.e(tag, "Failed to start new playback session")
|
if (it == null) {
|
||||||
} else {
|
Log.e(tag, "Failed to start new playback session")
|
||||||
Handler(Looper.getMainLooper()).post {
|
} else {
|
||||||
preparePlayer(it, true, null)
|
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
|
currentPlaybackSession?.currentTime = timeToSeek / 1000.0
|
||||||
val newWindowIndex = currentPlaybackSession?.getCurrentTrackIndex() ?: 0
|
val newWindowIndex = currentPlaybackSession?.getCurrentTrackIndex() ?: 0
|
||||||
val newTimeOffset = currentPlaybackSession?.getCurrentTrackTimeMs() ?: 0
|
val newTimeOffset = currentPlaybackSession?.getCurrentTrackTimeMs() ?: 0
|
||||||
|
Log.d(tag, "seekPlayer seekTo $newWindowIndex | $newTimeOffset")
|
||||||
currentPlayer.seekTo(newWindowIndex, newTimeOffset)
|
currentPlayer.seekTo(newWindowIndex, newTimeOffset)
|
||||||
} else {
|
} else {
|
||||||
currentPlayer.seekTo(timeToSeek)
|
currentPlayer.seekTo(timeToSeek)
|
||||||
|
@ -849,7 +856,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
||||||
return if(currentPlayer == castPlayer) PLAYER_CAST else PLAYER_EXO
|
return if(currentPlayer == castPlayer) PLAYER_CAST else PLAYER_EXO
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDeviceInfo(): DeviceInfo {
|
private fun getDeviceInfo(): DeviceInfo {
|
||||||
/* EXAMPLE
|
/* EXAMPLE
|
||||||
manufacturer: Google
|
manufacturer: Google
|
||||||
model: Pixel 6
|
model: Pixel 6
|
||||||
|
|
|
@ -45,13 +45,15 @@ class ApiHandler(var ctx:Context) {
|
||||||
makeRequest(request, httpClient, cb)
|
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 address = config?.address ?: DeviceManager.serverAddress
|
||||||
val token = config?.token ?: DeviceManager.token
|
val token = config?.token ?: DeviceManager.token
|
||||||
val mediaType = "application/json; charset=utf-8".toMediaType()
|
val mediaType = "application/json; charset=utf-8".toMediaType()
|
||||||
val requestBody = payload.toString().toRequestBody(mediaType)
|
val requestBody = payload.toString().toRequestBody(mediaType)
|
||||||
|
val requestUrl = "${address}$endpoint"
|
||||||
|
Log.d(tag, "postRequest to $requestUrl")
|
||||||
val request = Request.Builder().post(requestBody)
|
val request = Request.Builder().post(requestBody)
|
||||||
.url("${address}$endpoint").addHeader("Authorization", "Bearer ${token}")
|
.url(requestUrl).addHeader("Authorization", "Bearer ${token}")
|
||||||
.build()
|
.build()
|
||||||
makeRequest(request, null, cb)
|
makeRequest(request, null, cb)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue