Repository navigation
Releases: whleucka/soprano
Releases · whleucka/soprano
Release list
v1.7.1
Playback
- The next track is buffered before the current one ends. The player now preloads the upcoming track's audio ahead of the handoff instead of starting the request at the moment of the switch, which removes the gap of dead air between tracks on slow connections. If the queue changes in the meantime, the preload is simply discarded.
- The lock screen and car display now update for preloaded tracks. A track that came from the preload kept showing the previous track's title and artwork, because its metadata had already loaded before it took over.
- A stalled stream request is retried instead of hanging. On a weak cellular link a request could die without raising an error, leaving the player silent until the page was reloaded. After 8 seconds with no progress it is re-issued and playback resumes from where it was, up to 3 tries per stall.
Full changelog: v1.7.0...v1.7.1
v1.7.0
Radio
- 87 more stations, bringing the directory to 91 across Canada, the UK, France, Australia, Brazil, Japan and more. Every stream is HLS and was checked through to a live segment with CORS headers.
- The radio page is reorganised: one heading per country, with your liked stations grouped first. A filter in the header matches station name, city or country and ignores accents, so "montreal" finds Montréal. On desktop the grid fills the row.
- Station logos are no longer cropped. Most are wide wordmarks, and filling a square tile used to cut them down to a few letters. ICI Première showed as "Da". Wide and tall logos now sit uncropped on a white tile, while square ones still fill the tile like album art. A logo that fails to load falls back to the default art. The home page's favourite-stations rail uses the same card.
Playlists
- Rename a saved playlist with the pencil next to delete on the playlist page. Names are free text, emoji included.
- Rename and delete are offered only on playlists you made. Generated mixes such as Heavy Rotation could previously be deleted, and the next nightly run recreated them under a new link, so any shared URL went dead.
Interface
- The section headers (search, radio, podcasts, playlists) are overhauled into one consistent bar, and long titles no longer overflow it.
- In the home rails' "More" lists, track rows have a third line with play count, when you last played the track, and when you liked or added it.
- On mobile, Back closes the queue panel instead of leaving it covering a page that has already changed.
- The profile page shows the Soprano version, read from the latest git tag.
- Fixes: track row focus and active-row highlighting, albums missing from Recently played, and plays-by-source on the admin dashboard capped at the chart height.
Full changelog: v1.6.0...v1.7.0
v1.6.0
Listening
- Data saver — a new profile switch. Streams everything as 128k Opus, including the high-bitrate lossy sources that used to be sent as-is. Roughly half the bytes, and on a weak mobile signal it is the difference between a track starting in a few seconds and stalling for the better part of a minute. It only re-encodes when the encode is meaningfully smaller than the original, so a 96k MP3 is left alone rather than "shrunk" into something bigger.
- Transcode audio — a new profile switch, on by default. Turn it off to receive the original file untouched: better quality, far more data, and some browsers stall on large FLACs. Data saver has nothing to reach for while it is off.
- ReplayGain follows whichever path a track actually took — baked into the encode when the track is served as Opus, applied by the player when it streams from the source, never both.
Playback
- Crossfade now rides an equal-power (sin/cos) curve instead of two linear ramps. Complementary linear ramps sum to about -6 dB at the midpoint, so every handoff dipped in the middle and was heard as one track stopping and another starting; the perceived level now stays flat across the whole overlap.
- Each side of a fade peaks at its own ReplayGain target, so the crossfade rides on top of normalisation instead of flattening it.
- An end-of-track advance now names the track it is leaving, so the server can tell a retried advance from a genuinely new one. Before this, a retry that landed late advanced the queue for real and silently skipped a track.
- The hidden-tab pre-advance handoff added in v1.5.0 has been withdrawn. The tagged advance retries cover the same lost-advance case without parking a second audio element mid-queue.
Admin dashboard
Rebuilt around one time window and the listening data.
- One range selector at the top — 24 hours, 7 days, 30 days, 90 days, all time — drives every widget, and the choice is sticky per session. The four separate requests charts that all showed the same metric are gone. KPIs carry a delta against the previous equal-length window, suppressed for all-time rather than compared against a partial period.
- New headline strip: listening time, plays, completion, listeners, library and reach, each with a sparkline.
- New widgets: listening over time, listening clock, plays by source, source quality, top tracks, top artists, top albums, library growth, listeners, and visitors by country.
- The eight operations cards that each duplicated an admin module collapse into a single Operations strip, with every cell linking through to the module that owns the detail.
- Widgets declare their own band and position, so the layout is fixed regardless of registration order.
Interface
- The Admin link in the sidebar and account menu is now shown only to clients flagged
is_admin, instead of pointing every listener at a login wall they have no account for. The flag appears in no form or settings payload — granting it takes an UPDATE against the database.
Full changelog: v1.5.0...v1.6.0
v1.5.0
Podcasts
- Episodes in Continue Listening can now be dismissed with an × on the row, on both the home rail and the podcasts page. Dismissing an episode that is still playing stays dismissed for the rest of the session.
- The Continue Listening section now loads as its own fragment and disappears once the last episode is finished or dismissed.
Admin
- The backend has moved off the
admin.subdomain and now lives at/adminon the main host. The API stays at/api/v1. - Added an Admin link to the sidebar and to the account menu.
robots.txtnow disallows/adminand/api/, replacing the nginx rule that used to do it per-subdomain.
Performance
- Recently Played renders 50 tracks instead of a full week of listening (~900 cards) on load, every 2 minutes, and again on every track change. The full list is still behind "More".
- Top Played, Top Played This Month and Rediscover rewritten to aggregate play history before joining the track tables. Measured 5x faster on top-played and 6.5x on rediscover against a 5.5k-play history, and the gap widens as the history grows.
- New
track_playsindex covering the recently-played window, so the grouping never leaves the index.
Interface
- The heart and ⋯ controls on a card now have a 44px tap target. Both sit on the cover art, which plays the track, so a near-miss used to start playback instead of doing nothing.
- Album cards are 120px on mobile, up from 100px, with the next card still peeking past the edge to show the rail scrolls.
- An open ⋯ menu is no longer painted over by cards further along the rail.
Full changelog: v1.4.0...v1.5.0
v1.4.0
Stations
- Seven new stations: Feel Good, Steady, Wind Down, Rainy Day, Full Throttle, Dynamics and Deep Cuts
- Stations are chosen by time of day, and one with an empty pool is hidden rather than dealt as a dead end
- Pool sizes cached for an hour, so the home rail stops scanning
track_featurestwice on every load - Stations rail refreshes every 10 minutes, so it fills in as the feature backfill progresses
Interface
- Recently played cards badge who played the track and how long ago
- Rediscover cards show the album title
- Year badge no longer renders as an empty pill on albums with no year
- Fix the hover effect on station cards
Operations
- Bump the
app.csscache buster so the new badge styles reach cached clients
Full changelog: v1.3.0...v1.4.0
v1.3.0
Features
- ReplayGain scanning for tracks, plus the 800-track backfill
- Liked playlists surfaced in the Playlists section
- Reworked mobile player and progress bar position
Playback
- Fix end-of-track advance; queue no longer silently halts
- Fix crossfade bug and enable crossfade by default
- Exclude tracks under 20 seconds from generated playlists
Interface
- Album card scrim now scales with the cover on hover; neutral card-menu hover
- Playlist queue toggle, queue and search loading skeletons
- Playlist track rows show cover art; random/liked playlists get icons
Operations
- Console commands moved to
./echo - Logging forwarded to the soprano channel
Full changelog: v1.2.0...v1.3.0
v1.2.0
This is a big release! It's been a while! The application is maturing well.
Highlights
- Auto-generated playlists powered by Essentia audio analysis
- Artist radio + curated stations (kids dance party, feel-good, etc.), tunable via new soprano:stations command
- Synced lyrics via LRCLIB with automatic backfill
- Crossfade between tracks
- Replay gain volume normalization
- Skip-aware feeds — recommendations now factor in skips, not just plays
Features
- feat: essentia playlists
- feat: kids dance party station
- feat: artist radio
- feat: LRCLIB lyrics
- feat: crossfade audio
- feat: replay gain volume normalization
- feat: skip-aware feeds
- feat: like from artist and album pages
- feat: soprano:stations command; station tuning + more stations
- add: radio stations insert migration
Fixes & polish
- Home page reorg, recently played / "made for you" tweaks
- Search ordering fixes (tiered search, genre/decade ordering)
- Play queue: hidePlaylist bug fix, reworked actions, remove-from-queue
- Artist/track/album fixes: artist vs. track-artist distinction, name/font fixes, album art links to album
- Lyrics recheck/backfill fixes
- Cache fixes (incl. history cache size)
- Genre/decade back-history navigation fix
- Sign in / register: trim username
- UI polish: dropdown truncation, scrollbar style, player cover radius, margins
Notes
- New migration (radio stations) — run migrations as part of deploy
- Essentia extraction ~15s/track on prod; large libraries take time to backfill
Stay tuned for the next release in October!
v1.0.0
First release. Soprano is a self-hosted music server with a web player.
Features
- Music library streaming with search, albums, artists, and cover art
- Playlists: create, edit, add from anywhere via dropdown or queue
- Liked tracks with real-time sync across views
- Generated playlists ("Made for You") built from play history, skips, and completions
- Internet radio stations with likes
- Podcasts with saved progress and a Continue Listening widget on home
- Synced lyrics via LRCLIB
- Year End Review
- Play queue with repeat modes and play context
- Persistent login: sign in once per device, stay signed in
- Admin dashboard with library sync, metadata refresh, and activity logs
Notes
- Requires one sign-in per device after upgrade to pick up the new session token
- Run migrations before first boot