Skip to content

fix: prevent audible audio interruption during Turbolinks navigation (issues #8, #12)#14

Merged
adurrr merged 1 commit into
mainfrom
fix-audio-interruption-persistence
May 31, 2026
Merged

fix: prevent audible audio interruption during Turbolinks navigation (issues #8, #12)#14
adurrr merged 1 commit into
mainfrom
fix-audio-interruption-persistence

Conversation

@adurrr

@adurrr adurrr commented May 31, 2026

Copy link
Copy Markdown
Owner

Closes #8, Closes #12

Issue #8 — Audio Interruption

Root cause: During Turbolinks navigation, the footer's permanent <audio> element survives and keeps playing. But _applyPositionAndResume() would unconditionally seek (this._audio.currentTime = targetTime) on reconnect, forcing the browser to seek the audio buffer — creating an audible gap/stutter.

Fix: Two changes in PodcastFooter._applyPositionAndResume():

  1. Threshold guard on seek — only seek if the computed targetTime differs from current audio time by > 0.5s. Since the audio keeps playing during navigation, currentTime is already within a few hundred ms of the correct position.

  2. Guard play() call — only call audio.play() if the audio is actually paused. The footer never pauses in disconnectedCallback, so calling play() on an already-playing element is redundant and can cause a glitch.

Issue #12 — Persistence Review

Reviewed the full persistence layer (both <podcast-player> inline players and <podcast-footer>):

  • sessionStorage fallback is sound — footer uses fixed key, inline uses per-instance keys derived from src
  • DOM framework markers correctly applied in _persistenceSetup() with idempotency guard
  • Inline disconnectedCallback marks paused=true to prevent footer audio theft on return
  • Footer disconnectedCallback correctly avoids pausing/clearing audio — enabling uninterrupted playback through navigation
  • No structural issues found; the unnecessary seek was the only behavior causing perceptible problems

Tests

  • ✅ 80 JS unit tests pass (vitest)
  • ✅ 21 E2E tests pass (Playwright, including persistence + Turbolinks)

…(issues #8, #12)

Root cause analysis (#8):
When Turbolinks navigates, the footer's <audio> element survives as a
data-turbolinks-permanent element and keeps playing. However,
_applyPositionAndResume() would unconditionally seek
(this._audio.currentTime = targetTime) on reconnect. This forces the
browser to seek the audio buffer, creating an audible gap/stutter.

Two changes to fix the interruption:

1. Threshold guard on seek: Only seek if the computed targetTime
   differs from the current audio time by > 0.5s. Since the audio
   keeps playing during navigation, currentTime is already within a
   few hundred ms of the correct position — no need to seek.

2. Guard play() call: Only call audio.play() if the audio is actually
   paused. During Turbolinks navigation, the footer never pauses the
   audio (disconnectedCallback explicitly avoids it), so calling
   play() on an already-playing element is redundant and can cause
   an audible glitch on some browsers.

Persistence review (#12):
- sessionStorage as vanilla fallback is sound: footer uses a fixed
  key, inline players use per-instance keys derived from src
- DOM framework markers (data-turbolinks-permanent, etc.) are
  correctly applied in _persistenceSetup() with idempotency guard
- Inline player disconnectedCallback marks paused=true on save to
  prevent footer audio theft on return navigation
- Footer disconnectedCallback correctly avoids pausing/clearing the
  audio, allowing uninterrupted playback through navigation
- No structural issues found; the unnecessary seek was the only
  behavior causing perceptible problems
@adurrr adurrr merged commit 7870320 into main May 31, 2026
3 checks passed
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.

Review persistence option on podcast-player shortcode Fix minimal audio interruption when navigating between pages

1 participant