[PR #1848] Seek to millisecond rather than flooring to second #1725

Open
opened 2026-04-25 00:00:51 +02:00 by adam · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/advplyr/audiobookshelf-app/pull/1848
Author: @Kyrluckechuck
Created: 4/14/2026
Status: 🔄 Open

Base: masterHead: fix/seek-to-exact-time-rather-than-floored-second


📝 Commits (1)

  • d4e7d0a Seek to millisecond rather than flooring to second

📊 Changes

3 files changed (+5 additions, -4 deletions)

View changed files

📝 android/app/src/main/java/com/audiobookshelf/app/plugins/AbsAudioPlayer.kt (+2 -2)
📝 components/app/AudioPlayer.vue (+2 -1)
📝 components/app/AudioPlayerContainer.vue (+1 -1)

📄 Description

Brief summary

Fixes the "next chapter" button in the in-app player not advancing when a chapter starts at a non-integer second (common with m4b files). The player would land just before the chapter boundary and subsequent presses wouldn't move at all.

Which issue is fixed?

n/a, discovered while testing a separate fix. Happy to file one first if preferred

Pull Request Type

Android native plugin plus JS frontend. iOS already accepted Double values through the seek path so no Swift changes were needed.

In-depth Description

The seek plugin truncated to integer seconds: AbsAudioPlayer.seek({ value: Math.floor(time) }) on the JS side, and call.getInt("value", 0) on the Android side. If a chapter started at 100.5s, Math.floor(100.5) = 100 was sent to native, which seeked to 100000ms.
That's still inside the previous chapter, which ends at 100500ms. Pressing next again produced the same result because nextChapter is computed by comparing against currentTime, and currentTime was still less than nextChapter.start.

Traced the Math.floor back to a 2022 commit that switched the plugin contract from a millisecond string to an integer-seconds value. The floor was defensive to match the new Int required value from Android, not a deliberate precision decision. iOS already accepted Double, so it had never suffered the truncation.

The fix drops the Math.floor in both JS callers of AbsAudioPlayer.seek and switches the Android plugin to read the value as a Double and convert to ms with full precision. seekForward and seekBackward are unchanged since their values are always integer-second jump intervals from device settings.

One minor side effect is that drag-to-seek on the timeline now lands exactly where you drop rather than at the floor of the nearest second. That's an improvement IMO, but also a tiny behavior shift, so flagging it here and it could potentially be worked around to stay as it was if that's preferred.

How have you tested this?

  • Tested by toggling on chapters in the player and using next/previous buttons

Screenshots

  • N/A

🔄 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/1848 **Author:** [@Kyrluckechuck](https://github.com/Kyrluckechuck) **Created:** 4/14/2026 **Status:** 🔄 Open **Base:** `master` ← **Head:** `fix/seek-to-exact-time-rather-than-floored-second` --- ### 📝 Commits (1) - [`d4e7d0a`](https://github.com/advplyr/audiobookshelf-app/commit/d4e7d0abf9d602c1187db271f9c3c561f8b1a8ae) Seek to millisecond rather than flooring to second ### 📊 Changes **3 files changed** (+5 additions, -4 deletions) <details> <summary>View changed files</summary> 📝 `android/app/src/main/java/com/audiobookshelf/app/plugins/AbsAudioPlayer.kt` (+2 -2) 📝 `components/app/AudioPlayer.vue` (+2 -1) 📝 `components/app/AudioPlayerContainer.vue` (+1 -1) </details> ### 📄 Description ## Brief summary Fixes the "next chapter" button in the in-app player not advancing when a chapter starts at a non-integer second (common with m4b files). The player would land just before the chapter boundary and subsequent presses wouldn't move at all. ## Which issue is fixed? n/a, discovered while testing a separate fix. Happy to file one first if preferred ## Pull Request Type Android native plugin plus JS frontend. iOS already accepted Double values through the seek path so no Swift changes were needed. ## In-depth Description The seek plugin truncated to integer seconds: `AbsAudioPlayer.seek({ value: Math.floor(time) })` on the JS side, and `call.getInt("value", 0)` on the Android side. If a chapter started at 100.5s, `Math.floor(100.5) = 100` was sent to native, which seeked to 100000ms. That's still inside the previous chapter, which ends at 100500ms. Pressing next again produced the same result because `nextChapter` is computed by comparing against `currentTime`, and `currentTime` was still less than `nextChapter.start`. Traced the Math.floor back to a 2022 commit that switched the plugin contract from a millisecond string to an integer-seconds value. The floor was defensive to match the new Int required value from Android, not a deliberate precision decision. iOS already accepted Double, so it had never suffered the truncation. The fix drops the Math.floor in both JS callers of `AbsAudioPlayer.seek` and switches the Android plugin to read the value as a Double and convert to ms with full precision. `seekForward` and `seekBackward` are unchanged since their values are always integer-second jump intervals from device settings. One minor side effect is that drag-to-seek on the timeline now lands exactly where you drop rather than at the floor of the nearest second. That's an improvement IMO, but also a tiny behavior shift, so flagging it here and it could potentially be worked around to stay as it was if that's preferred. ## How have you tested this? - Tested by toggling on chapters in the player and using next/previous buttons ## Screenshots - N/A --- <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-25 00:00:51 +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#1725