[PR #330] [MERGED] Improve iOS Player Sync Logic #1408

Closed
opened 2026-04-24 23:58:14 +02:00 by adam · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/advplyr/audiobookshelf-app/pull/330
Author: @ronaldheft
Created: 8/23/2022
Status: Merged
Merged: 8/27/2022
Merged by: @advplyr

Base: masterHead: bug-ios-background-currenttime


📝 Commits (10+)

  • 27d2ed2 Convert PlayerHandler to shared instance
  • 8952cbf Start of refactor
  • d57fe44 Sleep timer using native time observer
  • ccecba7 If adjusting sleep time from chapter, convert to regular sleep timer
  • d084958 Scale time reporting by the rate
  • fe042f3 Fix NaN causing bad data
  • 2448b46 Re-implement the paused timer
  • cdd2f40 Merge branch 'master' into bug-ios-background-currenttime
  • 06f87d2 Fix merge conflict
  • 94e261d Fix bad data being encoded

📊 Changes

18 files changed (+697 additions, -369 deletions)

View changed files

📝 ios/App/App/AppDelegate.swift (+9 -1)
📝 ios/App/App/plugins/AbsAudioPlayer.swift (+30 -28)
📝 ios/App/App/plugins/AbsDatabase.swift (+34 -28)
📝 ios/App/App/plugins/AbsDownloader.swift (+5 -5)
📝 ios/App/App/plugins/AbsFileSystem.swift (+20 -15)
📝 ios/App/Shared/models/PlaybackSession.swift (+1 -0)
📝 ios/App/Shared/models/download/DownloadItem.swift (+2 -2)
📝 ios/App/Shared/models/local/LocalLibraryItem.swift (+2 -2)
📝 ios/App/Shared/models/local/LocalMediaProgress.swift (+29 -20)
📝 ios/App/Shared/models/server/AudioTrack.swift (+1 -1)
📝 ios/App/Shared/player/AudioPlayer.swift (+220 -18)
📝 ios/App/Shared/player/PlayerHandler.swift (+90 -155)
📝 ios/App/Shared/player/PlayerProgress.swift (+109 -22)
📝 ios/App/Shared/util/ApiClient.swift (+6 -1)
📝 ios/App/Shared/util/DaoExtensions.swift (+8 -8)
📝 ios/App/Shared/util/Database.swift (+111 -52)
📝 ios/App/Shared/util/NowPlayingInfo.swift (+11 -6)
📝 ios/App/Shared/util/Store.swift (+9 -5)

📄 Description

This PR refactors the iOS player sync hooks to rely on the native instead AVPlayer time observation hooks instead of using timers.

The theory is in low memory situations, iOS is stopping the current tick timer in the background, leading to issues where the player does not have the most accurate currentTime.

Changes

  • Persisting a syncing sessions are now done via addPeriodicTimeObserver() firing every 0.5 wall-clock seconds
    • The database currentTime is updated on every invocation
    • The server receives the latest session and media progress every 10 wall-clock seconds and when the player is paused or stopped
  • timeListening is now calculated based on updateAt times between sync vs. running an incremental counter each second
    • This ensures it's reliable regardless of the interval the value is updated
  • Sleep timers are now done via addBoundaryTimeObserver scheduled for the time to stop sleep
    • This refactor takes into account playbackSpeed, changes in playbackSpeed, seeks, and locks on a specific chapter time when required, to ensure the scheduled sleep time is always accurate
  • Syncing the current progress from the server is still done via a timer, but has been refactored into the Audio Player, and is now aware of pauses using the Now Playing widget or a remote
  • When resuming audio with allowed seek back, the last played time is based off the database session, allowing persistence across app restarts
  • Fixes an existing Realm memory leak that was made worse by this change
    • Adds lots of error handling logic as part of tracking down this memory leak

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/advplyr/audiobookshelf-app/pull/330 **Author:** [@ronaldheft](https://github.com/ronaldheft) **Created:** 8/23/2022 **Status:** ✅ Merged **Merged:** 8/27/2022 **Merged by:** [@advplyr](https://github.com/advplyr) **Base:** `master` ← **Head:** `bug-ios-background-currenttime` --- ### 📝 Commits (10+) - [`27d2ed2`](https://github.com/advplyr/audiobookshelf-app/commit/27d2ed230446219b370c7ff523bf18992ee3730e) Convert PlayerHandler to shared instance - [`8952cbf`](https://github.com/advplyr/audiobookshelf-app/commit/8952cbfd20eec6cccdc2c76c1b274464bd2aff7b) Start of refactor - [`d57fe44`](https://github.com/advplyr/audiobookshelf-app/commit/d57fe44bcc8b73ee50cb9d855c9164c80213c503) Sleep timer using native time observer - [`ccecba7`](https://github.com/advplyr/audiobookshelf-app/commit/ccecba7a19d34161223a6e9060bfb3f30789cbd3) If adjusting sleep time from chapter, convert to regular sleep timer - [`d084958`](https://github.com/advplyr/audiobookshelf-app/commit/d084958f2db13d7abc2510fdea1bfa6b072f9098) Scale time reporting by the rate - [`fe042f3`](https://github.com/advplyr/audiobookshelf-app/commit/fe042f3f83a6e67566d61b89c4192d5aa13990a5) Fix NaN causing bad data - [`2448b46`](https://github.com/advplyr/audiobookshelf-app/commit/2448b461f09344da1d6e116effaf4a8e79f69293) Re-implement the paused timer - [`cdd2f40`](https://github.com/advplyr/audiobookshelf-app/commit/cdd2f40ef9646ec794b015c10c21337d5a33dab0) Merge branch 'master' into bug-ios-background-currenttime - [`06f87d2`](https://github.com/advplyr/audiobookshelf-app/commit/06f87d24a707720b5c8796b7f1ccf64de792c1bd) Fix merge conflict - [`94e261d`](https://github.com/advplyr/audiobookshelf-app/commit/94e261d7bfe47c181eee6dcff5966b176bde793e) Fix bad data being encoded ### 📊 Changes **18 files changed** (+697 additions, -369 deletions) <details> <summary>View changed files</summary> 📝 `ios/App/App/AppDelegate.swift` (+9 -1) 📝 `ios/App/App/plugins/AbsAudioPlayer.swift` (+30 -28) 📝 `ios/App/App/plugins/AbsDatabase.swift` (+34 -28) 📝 `ios/App/App/plugins/AbsDownloader.swift` (+5 -5) 📝 `ios/App/App/plugins/AbsFileSystem.swift` (+20 -15) 📝 `ios/App/Shared/models/PlaybackSession.swift` (+1 -0) 📝 `ios/App/Shared/models/download/DownloadItem.swift` (+2 -2) 📝 `ios/App/Shared/models/local/LocalLibraryItem.swift` (+2 -2) 📝 `ios/App/Shared/models/local/LocalMediaProgress.swift` (+29 -20) 📝 `ios/App/Shared/models/server/AudioTrack.swift` (+1 -1) 📝 `ios/App/Shared/player/AudioPlayer.swift` (+220 -18) 📝 `ios/App/Shared/player/PlayerHandler.swift` (+90 -155) 📝 `ios/App/Shared/player/PlayerProgress.swift` (+109 -22) 📝 `ios/App/Shared/util/ApiClient.swift` (+6 -1) 📝 `ios/App/Shared/util/DaoExtensions.swift` (+8 -8) 📝 `ios/App/Shared/util/Database.swift` (+111 -52) 📝 `ios/App/Shared/util/NowPlayingInfo.swift` (+11 -6) 📝 `ios/App/Shared/util/Store.swift` (+9 -5) </details> ### 📄 Description This PR refactors the iOS player sync hooks to rely on the native instead `AVPlayer` time observation hooks instead of using timers. The theory is in low memory situations, iOS is stopping the current tick timer in the background, leading to issues where the player does not have the most accurate `currentTime`. ## Changes * Persisting a syncing sessions are now done via `addPeriodicTimeObserver()` firing every 0.5 wall-clock seconds * The database `currentTime` is updated on every invocation * The server receives the latest session and media progress every 10 wall-clock seconds and when the player is paused or stopped * `timeListening` is now calculated based on `updateAt` times between sync vs. running an incremental counter each second * This ensures it's reliable regardless of the interval the value is updated * Sleep timers are now done via `addBoundaryTimeObserver` scheduled for the time to stop sleep * This refactor takes into account playbackSpeed, changes in playbackSpeed, seeks, and locks on a specific chapter time when required, to ensure the scheduled sleep time is always accurate * Syncing the current progress from the server is still done via a timer, but has been refactored into the Audio Player, and is now aware of pauses using the Now Playing widget or a remote * When resuming audio with allowed seek back, the last played time is based off the database session, allowing persistence across app restarts * Fixes an existing Realm memory leak that was made worse by this change * Adds lots of error handling logic as part of tracking down this memory leak --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
adam added the pull-request label 2026-04-24 23:58:14 +02:00
adam closed this issue 2026-04-24 23:58:14 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/audiobookshelf-app#1408