Skip to content

Conversation

@EvandroLG
Copy link
Owner

@EvandroLG EvandroLG commented Jan 3, 2026

The seek() method currently fails silently when called before audio is decoded or playback has started.

This PR implements a fix for this issue:

  • Added _pendingSeekTime: number | null private property
  • Refactored seek() to accept and store seeks at any lifecycle state
  • Updated play() to apply pending seek before starting playback
  • Improved clamping logic to handle unknown duration gracefully

Note

Improves seek() reliability across lifecycle states.

  • Adds _pendingSeekTime to queue seeks made before decoding/initial playback
  • Updates play() to apply any pending seek before starting
  • Refactors seek() to clamp safely (handles unknown duration) and to queue when not decoded; recreates source when playing, updates pause time when paused
  • Extends tests to cover seeking before play() and before decoding

Written by Cursor Bugbot for commit 26a30f6. This will update automatically on new commits. Configure here.

@EvandroLG EvandroLG self-assigned this Jan 3, 2026
@EvandroLG EvandroLG marked this pull request as ready for review January 3, 2026 10:10
@EvandroLG EvandroLG requested a review from Copilot January 3, 2026 10:10
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes the seek() method to work correctly when called before audio decoding or playback has started, eliminating silent failures in early lifecycle states.

Key Changes:

  • Added _pendingSeekTime property to queue seek requests before audio is ready
  • Modified seek() to store pending seeks instead of failing silently
  • Updated play() to apply any pending seek time before starting playback

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/audio/Audio.ts Implements pending seek storage, updates seek() to handle early calls, and modifies play() to apply pending seeks
src/audio/tests/Audio.test.ts Adds test coverage for seeking before play() is called and before audio is decoded

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@EvandroLG EvandroLG merged commit e58c058 into master Jan 3, 2026
6 checks passed
@EvandroLG EvandroLG deleted the fix/seek branch January 3, 2026 10:20
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

this._pauseTime = this._pendingSeekTime
this._pendingSeekTime = null
}

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pending seek ignored when called after play but before decoding

When seek() is called after play() but before audio decoding completes, the seek time is stored in _pendingSeekTime but never applied. The decoded event listener only checks _pauseTime, not _pendingSeekTime. This means seeks requested during the decoding phase are silently dropped. The pending seek logic at lines 199-203 only handles seeks made before play() is called, not seeks made during the async decoding window.

Additional Locations (1)

Fix in Cursor Fix in Web

if (this._pendingSeekTime !== null) {
this._pauseTime = this._pendingSeekTime
this._pendingSeekTime = null
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pending seek value not re-clamped when applied

When seek() is called before audio is loaded with a time exceeding the eventual duration, the value is stored in _pendingSeekTime without upper-bound clamping (since duration is unknown/zero). When this pending seek is applied in play(), _pauseTime is set directly without re-clamping to the now-known duration. The immediate seek path at line 361 re-clamps with Math.min(clampedTime, this.duration), but the pending seek application path doesn't. This causes source.start() to receive an offset beyond the buffer duration, resulting in immediate silent end of playback.

Additional Locations (1)

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants