Skip to content

Gapless playback and crossfade - #158

Merged
elcapitantommy merged 2 commits into
mainfrom
feat/crossfade
Oct 19, 2026
Merged

elcapitantommy merged 2 commits into
mainfrom
feat/crossfade

Conversation

@elcapitantommy

Copy link
Copy Markdown
Owner

Requested by Tom · project thread

Before: the next song only started after the current one fired ended, which left a short gap between tracks (noticeable on live and continuous albums), and there was no crossfade.

After: songs play back to back with no gap, and Settings → Playback has a Crossfade slider (Off, or 1 to 12 seconds, per device) that fades the end of each song into the next. Songs from the same album, DJ sets and repeat-one always stay gapless; skipping by hand still changes song at once.

How: the player already pre-loads the next song in a second audio element. In the last second before the hand-over, PlayerRuntime sets a timer to start it about 0.12 s early (gapless) or by the crossfade length, but only if that element has buffered enough to start at once; otherwise it falls back to the old ended path. The element handed over from plays out or fades on equal-power curves through a per-element fade level that multiplies the existing volume and normalisation scale. When it finishes, the element loads the song after next. The play is counted and scrobbled as completed at the hand-over. iPhone and iPad ignore element volume, so they get gapless only (volumeCanFade). Logic in src/lib/crossfade.ts, setting in src/stores/crossfade.ts.

Frontend only: merging deploys the site, with no Worker or agent changes.

Closes #155


Generated by Claude Code

The pre-loaded next song starts just before the current one ends
(gapless), or fades in over the Settings crossfade length while the
current one fades out. Same-album songs, DJ sets and repeat-one stay
gapless; iOS, which ignores element volume, plays gapless only.

Closes #155

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RcNpPocCZdNRCmS9c36eBh
@elcapitantommy elcapitantommy self-assigned this Oct 19, 2026
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RcNpPocCZdNRCmS9c36eBh
@elcapitantommy
elcapitantommy merged commit 7b93865 into main Oct 19, 2026
2 checks passed
@elcapitantommy
elcapitantommy deleted the feat/crossfade branch October 19, 2026 22:05
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.

Crossfade and gapless playback

2 participants