mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2025-08-28 13:58:23 +02:00
Fix:Android check local media progress after a pause reverting to previous progress #290
This commit is contained in:
parent
1f60a552e5
commit
2a87f1de28
4 changed files with 91 additions and 24 deletions
|
@ -46,7 +46,10 @@ class MediaProgressSyncer(val playerNotificationService:PlayerNotificationServic
|
||||||
} else {
|
} else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
} else if (playerNotificationService.getCurrentPlaybackSessionId() != currentSessionId) {
|
||||||
|
currentLocalMediaProgress = null
|
||||||
}
|
}
|
||||||
|
|
||||||
listeningTimerRunning = true
|
listeningTimerRunning = true
|
||||||
lastSyncTime = System.currentTimeMillis()
|
lastSyncTime = System.currentTimeMillis()
|
||||||
currentPlaybackSession = playerNotificationService.getCurrentPlaybackSessionCopy()
|
currentPlaybackSession = playerNotificationService.getCurrentPlaybackSessionCopy()
|
||||||
|
@ -63,13 +66,30 @@ class MediaProgressSyncer(val playerNotificationService:PlayerNotificationServic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stop() {
|
fun stop(cb: () -> Unit) {
|
||||||
if (!listeningTimerRunning) return
|
if (!listeningTimerRunning) return
|
||||||
Log.d(tag, "stop: Stopping listening for $currentDisplayTitle")
|
Log.d(tag, "stop: Stopping listening for $currentDisplayTitle")
|
||||||
|
|
||||||
val currentTime = playerNotificationService.getCurrentTimeSeconds()
|
val currentTime = playerNotificationService.getCurrentTimeSeconds()
|
||||||
sync(currentTime) {
|
sync(currentTime) {
|
||||||
reset()
|
reset()
|
||||||
|
cb()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun pause(cb: () -> Unit) {
|
||||||
|
if (!listeningTimerRunning) return
|
||||||
|
Log.d(tag, "pause: Pausing progress syncer for $currentDisplayTitle")
|
||||||
|
|
||||||
|
val currentTime = playerNotificationService.getCurrentTimeSeconds()
|
||||||
|
sync(currentTime) {
|
||||||
|
listeningTimerTask?.cancel()
|
||||||
|
listeningTimerTask = null
|
||||||
|
listeningTimerRunning = false
|
||||||
|
lastSyncTime = 0L
|
||||||
|
failedSyncs = 0
|
||||||
|
|
||||||
|
cb()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +97,6 @@ class MediaProgressSyncer(val playerNotificationService:PlayerNotificationServic
|
||||||
currentPlaybackSession?.let {
|
currentPlaybackSession?.let {
|
||||||
it.updatedAt = mediaProgress.lastUpdate
|
it.updatedAt = mediaProgress.lastUpdate
|
||||||
it.currentTime = mediaProgress.currentTime
|
it.currentTime = mediaProgress.currentTime
|
||||||
|
|
||||||
DeviceManager.dbManager.saveLocalPlaybackSession(it)
|
DeviceManager.dbManager.saveLocalPlaybackSession(it)
|
||||||
saveLocalProgress(it)
|
saveLocalProgress(it)
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,32 +71,36 @@ class PlayerListener(var playerNotificationService:PlayerNotificationService) :
|
||||||
if (player.isPlaying) {
|
if (player.isPlaying) {
|
||||||
Log.d(tag, "SeekBackTime: Player is playing")
|
Log.d(tag, "SeekBackTime: Player is playing")
|
||||||
if (lastPauseTime > 0 && DeviceManager.deviceData.deviceSettings?.disableAutoRewind != true) {
|
if (lastPauseTime > 0 && DeviceManager.deviceData.deviceSettings?.disableAutoRewind != true) {
|
||||||
|
var seekBackTime = 0L
|
||||||
if (onSeekBack) onSeekBack = false
|
if (onSeekBack) onSeekBack = false
|
||||||
else {
|
else {
|
||||||
Log.d(tag, "SeekBackTime: playing started now set seek back time $lastPauseTime")
|
Log.d(tag, "SeekBackTime: playing started now set seek back time $lastPauseTime")
|
||||||
var backTime = calcPauseSeekBackTime()
|
seekBackTime = calcPauseSeekBackTime()
|
||||||
if (backTime > 0) {
|
if (seekBackTime > 0) {
|
||||||
// Current chapter is used so that seek back does not go back to the previous chapter
|
// Current chapter is used so that seek back does not go back to the previous chapter
|
||||||
val currentChapter = playerNotificationService.getCurrentBookChapter()
|
val currentChapter = playerNotificationService.getCurrentBookChapter()
|
||||||
val minSeekBackTime = currentChapter?.startMs ?: 0
|
val minSeekBackTime = currentChapter?.startMs ?: 0
|
||||||
|
|
||||||
val currentTime = playerNotificationService.getCurrentTime()
|
val currentTime = playerNotificationService.getCurrentTime()
|
||||||
val newTime = currentTime - backTime
|
val newTime = currentTime - seekBackTime
|
||||||
if (newTime < minSeekBackTime) {
|
if (newTime < minSeekBackTime) {
|
||||||
backTime = currentTime - minSeekBackTime
|
seekBackTime = currentTime - minSeekBackTime
|
||||||
}
|
}
|
||||||
Log.d(tag, "SeekBackTime $backTime")
|
Log.d(tag, "SeekBackTime $seekBackTime")
|
||||||
onSeekBack = true
|
onSeekBack = true
|
||||||
playerNotificationService.seekBackward(backTime)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if playback session still exists or sync media progress if updated
|
// Check if playback session still exists or sync media progress if updated
|
||||||
val pauseLength: Long = System.currentTimeMillis() - lastPauseTime
|
val pauseLength: Long = System.currentTimeMillis() - lastPauseTime
|
||||||
if (pauseLength > PAUSE_LEN_BEFORE_RECHECK) {
|
if (pauseLength > PAUSE_LEN_BEFORE_RECHECK) {
|
||||||
val shouldCarryOn = playerNotificationService.checkCurrentSessionProgress()
|
val shouldCarryOn = playerNotificationService.checkCurrentSessionProgress(seekBackTime)
|
||||||
if (!shouldCarryOn) return
|
if (!shouldCarryOn) return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (seekBackTime > 0L) {
|
||||||
|
playerNotificationService.seekBackward(seekBackTime)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.d(tag, "SeekBackTime: Player not playing set last pause time")
|
Log.d(tag, "SeekBackTime: Player not playing set last pause time")
|
||||||
|
@ -104,12 +108,13 @@ class PlayerListener(var playerNotificationService:PlayerNotificationService) :
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start/stop progress sync interval
|
// Start/stop progress sync interval
|
||||||
Log.d(tag, "Playing ${playerNotificationService.getCurrentBookTitle()}")
|
|
||||||
if (player.isPlaying) {
|
if (player.isPlaying) {
|
||||||
player.volume = 1F // Volume on sleep timer might have decreased this
|
player.volume = 1F // Volume on sleep timer might have decreased this
|
||||||
playerNotificationService.mediaProgressSyncer.start()
|
playerNotificationService.mediaProgressSyncer.start()
|
||||||
} else {
|
} else {
|
||||||
playerNotificationService.mediaProgressSyncer.stop()
|
playerNotificationService.mediaProgressSyncer.pause {
|
||||||
|
Log.d(tag, "Media Progress Syncer paused and synced")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
playerNotificationService.clientEventEmitter?.onPlayingUpdate(player.isPlaying)
|
playerNotificationService.clientEventEmitter?.onPlayingUpdate(player.isPlaying)
|
||||||
|
|
|
@ -550,10 +550,10 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
||||||
|
|
||||||
// Called from PlayerListener play event
|
// Called from PlayerListener play event
|
||||||
// check with server if progress has updated since last play and sync progress update
|
// check with server if progress has updated since last play and sync progress update
|
||||||
fun checkCurrentSessionProgress():Boolean {
|
fun checkCurrentSessionProgress(seekBackTime:Long):Boolean {
|
||||||
if (currentPlaybackSession == null) return true
|
if (currentPlaybackSession == null) return true
|
||||||
|
|
||||||
currentPlaybackSession?.let { playbackSession ->
|
mediaProgressSyncer.currentPlaybackSession?.let { playbackSession ->
|
||||||
if (!apiHandler.isOnline() || playbackSession.isLocalLibraryItemOnly) {
|
if (!apiHandler.isOnline() || playbackSession.isLocalLibraryItemOnly) {
|
||||||
return true // carry on
|
return true // carry on
|
||||||
}
|
}
|
||||||
|
@ -575,17 +575,29 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
||||||
Log.d(tag, "checkCurrentSessionProgress: Media progress was updated since last play time updating from ${playbackSession.currentTime} to ${mediaProgress.currentTime}")
|
Log.d(tag, "checkCurrentSessionProgress: Media progress was updated since last play time updating from ${playbackSession.currentTime} to ${mediaProgress.currentTime}")
|
||||||
mediaProgressSyncer.syncFromServerProgress(mediaProgress)
|
mediaProgressSyncer.syncFromServerProgress(mediaProgress)
|
||||||
|
|
||||||
Handler(Looper.getMainLooper()).post {
|
// Update current playback session stored in PNS since MediaProgressSyncer version is a copy
|
||||||
seekPlayer(playbackSession.currentTimeMs)
|
mediaProgressSyncer.currentPlaybackSession?.let { updatedPlaybackSession ->
|
||||||
}
|
currentPlaybackSession = updatedPlaybackSession
|
||||||
}
|
}
|
||||||
|
|
||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
|
seekPlayer(playbackSession.currentTimeMs)
|
||||||
// Should already be playing
|
// Should already be playing
|
||||||
currentPlayer.volume = 1F // Volume on sleep timer might have decreased this
|
currentPlayer.volume = 1F // Volume on sleep timer might have decreased this
|
||||||
mediaProgressSyncer.start()
|
mediaProgressSyncer.start()
|
||||||
clientEventEmitter?.onPlayingUpdate(true)
|
clientEventEmitter?.onPlayingUpdate(true)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Handler(Looper.getMainLooper()).post {
|
||||||
|
if (seekBackTime > 0L) {
|
||||||
|
seekBackward(seekBackTime)
|
||||||
|
}
|
||||||
|
// Should already be playing
|
||||||
|
currentPlayer.volume = 1F // Volume on sleep timer might have decreased this
|
||||||
|
mediaProgressSyncer.start()
|
||||||
|
clientEventEmitter?.onPlayingUpdate(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Streaming from server so check if playback session still exists on server
|
// Streaming from server so check if playback session still exists on server
|
||||||
|
@ -607,6 +619,10 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
||||||
} else {
|
} else {
|
||||||
Log.d(tag, "checkCurrentSessionProgress: Playback session still available on server")
|
Log.d(tag, "checkCurrentSessionProgress: Playback session still available on server")
|
||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
|
if (seekBackTime > 0L) {
|
||||||
|
seekBackward(seekBackTime)
|
||||||
|
}
|
||||||
|
|
||||||
currentPlayer.volume = 1F // Volume on sleep timer might have decreased this
|
currentPlayer.volume = 1F // Volume on sleep timer might have decreased this
|
||||||
mediaProgressSyncer.start()
|
mediaProgressSyncer.start()
|
||||||
clientEventEmitter?.onPlayingUpdate(true)
|
clientEventEmitter?.onPlayingUpdate(true)
|
||||||
|
@ -673,7 +689,9 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
||||||
Log.d(tag, "closePlayback")
|
Log.d(tag, "closePlayback")
|
||||||
if (mediaProgressSyncer.listeningTimerRunning) {
|
if (mediaProgressSyncer.listeningTimerRunning) {
|
||||||
Log.i(tag, "About to close playback so stopping media progress syncer first")
|
Log.i(tag, "About to close playback so stopping media progress syncer first")
|
||||||
mediaProgressSyncer.stop()
|
mediaProgressSyncer.stop {
|
||||||
|
Log.d(tag, "Media Progress syncer stopped and synced")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -177,8 +177,22 @@ class AbsAudioPlayer : Plugin() {
|
||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
Log.d(tag, "prepareLibraryItem: Preparing Local Media item ${jacksonMapper.writeValueAsString(it)}")
|
Log.d(tag, "prepareLibraryItem: Preparing Local Media item ${jacksonMapper.writeValueAsString(it)}")
|
||||||
val playbackSession = it.getPlaybackSession(episode)
|
val playbackSession = it.getPlaybackSession(episode)
|
||||||
|
|
||||||
|
if (playerNotificationService.mediaProgressSyncer.listeningTimerRunning) { // If progress syncing then first stop before preparing next
|
||||||
|
playerNotificationService.mediaProgressSyncer.stop {
|
||||||
|
Log.d(tag, "Media progress syncer was already syncing - stopped")
|
||||||
|
Handler(Looper.getMainLooper()).post { // TODO: This was needed again which is probably a design a flaw
|
||||||
|
playerNotificationService.preparePlayer(
|
||||||
|
playbackSession,
|
||||||
|
playWhenReady,
|
||||||
|
playbackRate
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
playerNotificationService.preparePlayer(playbackSession, playWhenReady, playbackRate)
|
playerNotificationService.preparePlayer(playbackSession, playWhenReady, playbackRate)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return call.resolve(JSObject())
|
return call.resolve(JSObject())
|
||||||
}
|
}
|
||||||
} else { // Play library item from server
|
} else { // Play library item from server
|
||||||
|
@ -188,10 +202,21 @@ class AbsAudioPlayer : Plugin() {
|
||||||
if (it == null) {
|
if (it == null) {
|
||||||
call.resolve(JSObject("{\"error\":\"Server play request failed\"}"))
|
call.resolve(JSObject("{\"error\":\"Server play request failed\"}"))
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
Log.d(tag, "Preparing Player TEST ${jacksonMapper.writeValueAsString(it)}")
|
Log.d(tag, "Preparing Player playback session ${jacksonMapper.writeValueAsString(it)}")
|
||||||
|
|
||||||
|
if (playerNotificationService.mediaProgressSyncer.listeningTimerRunning) { // If progress syncing then first stop before preparing next
|
||||||
|
playerNotificationService.mediaProgressSyncer.stop {
|
||||||
|
Log.d(tag, "Media progress syncer was already syncing - stopped")
|
||||||
|
Handler(Looper.getMainLooper()).post { // TODO: This was needed again which is probably a design a flaw
|
||||||
playerNotificationService.preparePlayer(it, playWhenReady, playbackRate)
|
playerNotificationService.preparePlayer(it, playWhenReady, playbackRate)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
playerNotificationService.preparePlayer(it, playWhenReady, playbackRate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
call.resolve(JSObject(jacksonMapper.writeValueAsString(it)))
|
call.resolve(JSObject(jacksonMapper.writeValueAsString(it)))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue