Releases: ALunfb/tracklist-link
v0.8.0 — Simplified Tune panel, no more beat detection
What's new
Big simplification pass based on real-use feedback from v0.7.x.
Tune panel: fewer sliders, better defaults
- Removed: Attack, Release, Noise gate, Beat sensitivity. These overlapped with internal FFT smoothing and muddied the feel.
- Renamed: Spectrum tilt → Bass boost (0-100%). The old treble side had no visible effect on MilkDrop presets; the new knob only affects the bottom third of the spectrum, which is what actually moves the viz.
- Kept: Audio gain, Bass boost, Auto-cycle, Blend time.
Beat detection removed entirely
The BPM counter was noisy and not accurate enough to be useful. The whole path is gone: detector module, WebSocket audio/beat topic (deprecated-empty for backward compat), BPM display in the companion header, beat-driven visual pulses. If you want per-song BPM in the future, that's better served by an external lookup service (getsongbpm.com has a free API) than on-device detection.
Tighter frequency response
The FFT now spans 30 Hz to 16 kHz (was 20 Hz – 20 kHz). Most music has no meaningful energy below 30 Hz or above 16 kHz, so concentrating 64 log-spaced bands over the audible range makes every bar react.
16:9 everywhere
Visualizer renders at a fixed 16:9 aspect ratio in all three surfaces (companion app, /visualizer page, OBS Browser Source) with clean letterbox/pillarbox in non-16:9 containers. OBS source size controls display scale; internal render stays at native resolution × device-pixel-ratio.
Paired web changes
The web side (music.blackpearl.gg) also removes BPM displays from the dashboard tile, tempo column on session detail, Tempo chapter on stats, and the BPM filter on /sessions. Already deployed to Vercel — just refresh the page after installing v0.8.0.
How to install
- Download
tracklist-link.exebelow. - Right-click your Tracklist Link tray icon → Quit.
- Replace your existing
.exewith this one. - Double-click to launch. It'll start into the tray like before.
- Refresh any open
/visualizerbrowser tabs or restart any OBS Browser Sources so they pick up the deployed web-side changes.
Technical
- Binary: 15 MB, clean-built from commit 4346f98.
- Config migration is automatic — the old
beat_sensitivityfield in your config.toml is silently ignored by v0.8.0. - Protocol: `VizSettings` fields renamed on the wire. `Topic::AudioBeat` kept in the enum (deprecated, no-op) so older cached web clients don't error-out their subscribe message.
v0.7.1 — Preset sync across all visualizer instances
What's new
All your visualizer instances now show the same preset at the same time.
v0.7.0 synced Tune-panel settings (gain, tilt, etc.) but each visualizer (companion app, web /visualizer in a browser, OBS Browser Source pointed at /visualizer) was still picking its own random preset independently — three different visuals on screen at once, making the tool useless.
This release adds a new viz/preset WebSocket broadcast. Every time the companion loads a preset (auto-cycle or manual pick), it pushes the preset name to every connected client. All web instances mirror the companion's selection within one frame.
Bonus: a snapshot is sent the instant a client connects, so a freshly-opened OBS Browser Source lands on the companion's current preset immediately — no waiting for the next cycle.
How to install
- Download
tracklist-link.exebelow. - Close the currently-running companion (right-click the tray icon → Quit).
- Replace your existing
tracklist-link.exewith this one. - Launch it. Your next auto-cycle or manual preset pick should immediately propagate to any
/visualizerpage you have open.
How to verify
- Open the companion. Go to the Visualizer tab.
- In a second browser window, open your
/visualizer?token=…URL. - Optionally add it as an OBS Browser Source too.
- Click a preset in the companion. All visualizers should jump to the same preset within a frame.
- Enable auto-cycle — all instances cycle together.
Technical notes
- New
Topic::VizPreset,ServerMessage::VizPreset, andVizPresetstruct. set_viz_presetTauri command invoked from the frontend'sloadPreseteffect.- Snapshot sent in the post-Hello handshake (empty name = skip, so nothing overrides the client's initial pick before the companion has loaded anything).
- Always-on broadcast (like Heartbeat + VizSettings), no subscription needed.
- Backward compatible: clients without the topic handler silently ignore the unknown
kind.
v0.7.0 — Live Tune-panel sync to web /visualizer
What's new
Your Tune-panel sliders now drive the web /visualizer live.
Previously, the sliders in the companion's Tune panel only affected the in-app visualizer. If you had the web /visualizer running in OBS as a Browser Source, it ignored your tuning — you'd have to regenerate the OBS URL or refresh the source to see any change.
This release adds a new viz/settings WebSocket topic. Every slider drag (Audio gain, Attack, Release, Spectrum tilt, Noise gate, Auto-cycle, Blend time) broadcasts live to every connected external client. Your OBS viz now mirrors the Tune panel in real time.
How to install
- Download
tracklist-link.exebelow. - Close the currently-running companion (right-click tray icon → Quit).
- Replace your existing
tracklist-link.exewith this one. - Launch it. The WebSocket server starts immediately and any paired OBS
/visualizerBrowser Source will start receiving Tune updates within a second.
What pairs with this release
The web side of the live-sync wiring shipped as part of twitch-spotify-tool#2 and is already live on https://music.blackpearl.gg. That PR also fixed:
- Preset catalog 404 on
/visualizers - Site header showing inside
/visualizerOBS Browser Sources - Low-res / cropped rendering on larger OBS sources
- Music overlay analyzer's per-frequency response (removed the uniform beat-driven boost)
Technical
- Tokio broadcast channel + new
ServerMessage::VizSettingsvariant - Snapshot sent right after Hello so new clients catch up without requiring a slider change
- Always-on broadcast (like Heartbeat) — no subscription required
- Companion frontend invokes
set_viz_settingsalongside localStorage writes
Protocol is backwards-compatible — older clients ignore the unknown kind: viz/settings per the forward-compat rules.
v0.6.0 — One-click OBS install + silence detection + more polish
Big release. The companion's "Add to OBS" button becomes a real one-click install via obs-websocket, silence detection joins beat detection on the reactive-signals bus, and a handful of web-side features round out the stats and overlay stories.
Companion-side (tracklist-link v0.6.0)
One-click OBS install
- New "One-click install" tab in the Add-to-OBS modal. Paste your OBS WebSocket password (from Tools → WebSocket Server Settings → Show Connect Info), hit Connect to OBS, then Install into "". The companion creates a Browser Source pointing at the visualizer URL, places it in your active scene, tells you it's done.
- Remember-password option stores it in the companion's localStorage (Windows user profile scope).
- Connection errors map to actionable messages: "OBS not running," "WebSocket server not enabled," "wrong password." Not silent.
- The "Copy URL" tab remains for streamers who prefer to paste manually or use Streamlabs.
- Zero new Rust dependencies — hand-rolled obs-websocket v5 client (~200 LOC) over the native WebSocket API that ships in Tauri's webview.
Silence detection
- Second reactive-signal producer on the bus alongside beat detection. Emits `audio/silence` events on silence entry + exit with hysteresis — 1.5 s enter debounce, 250 ms exit debounce, so single dropouts don't trip and a single kick wakes it.
- Edge-triggered, not per-frame. State-change semantics match future CS2 GSI events so the same consumers can bind.
- Default RMS threshold 0.02 (tuneable in a future settings pass).
Other
- CSP expanded to allow `ws:` in connect-src — needed for obs-websocket, nothing else. Everything else still locked.
- docs/VERIFICATION_CHECKLIST.md captures the 7-step smoke test for this multi-commit landing.
Web-side (shipped alongside, auto-deploys)
Sessions BPM filter
- /sessions accepts `?bpmMin=&bpmMax=` URL params. The Tempo panel's bucket rows link into this; click a bucket, see every session that played at least one track in that tempo range.
- Active filter shows as a dismissible pill so the streamer always knows why results are scoped.
Mood chapter on /stats
- Three-axis horizontal-rail view of the streamer's Spotify audio-features averages: Energy, Danceability, Valence (musical positivity). Coarse derived label at the top ("Dancey intense & moody," "Warm & melodic," etc.) as an identity hook.
Overlay ticker
- `?ticker=bottom` renders a scrolling marquee under the card with the last 10 tracks + artists. CSS keyframe, 30 s loop, duplicated content so the scroll is seamless. Opt-in — most streamers want the minimal card, but VOD viewers joining mid-song love the backfill context.
Verify
After downloading the binary:
- Open it. Paste your OBS WebSocket password (Tools → WebSocket Server Settings → Show Connect Info) into the One-click install tab.
- Click Connect to OBS → Install into "".
- Check OBS — a new "Tracklist Visualizer " Browser Source should be in your scene, rendered at 1920 × 1080.
- Play audio. The viz flashes on kicks. When you pause, silence is detected after 1.5 s (no consumer UI yet — that's a future feature).
```bash
git clone https://github.com/ALunfb/tracklist-link.git
cd tracklist-link
git checkout v0.6.0
cd frontend && npm install && npm run build && cd ..
cargo build --release
sha256sum target/release/tracklist-link.exe
```
v0.5.0 — OBS fullscreen visualizer integration
One-click visualizer → OBS. The companion now assembles a Browser Source URL that renders the fullscreen MilkDrop visualizer inside OBS, connecting back to your companion for audio. No second monitor, no window capture.
What's new since v0.4.1
- Visualizer tab → Add to OBS button. Opens a modal that copies a ready-to-paste Browser Source URL to your clipboard (and a Preview button that opens the URL in your default browser for a sanity-check first).
- music.blackpearl.gg/visualizer — new fullscreen viz page. ~1 MB lazy-loaded chunk, WebGL MilkDrop via Butterchurn. Connects to the companion via WS using the token in the URL, just like the overlay.
- Auto-cycles presets every 30 s by default (override with `?cycle=`). Beat-reactive gain boost on kicks, same as the companion's internal viz.
- URL params for tuning: `token`, `port`, `preset`, `cycle`, `accent`. All optional except token.
- Fade-in HUD shows connection status + current preset + live BPM for 6 s on load, then disappears. Hovering/clicking the source brings it back briefly — handy while aligning in OBS.
Three-step setup
- Companion Visualizer tab → Add to OBS → Copy.
- OBS: Sources → + → Browser. Paste URL. W/H 1920 × 1080. Tick Shutdown source when not visible to save CPU when off-scene.
- Click OK. Viz is live.
Plan docs updated
`docs/OBS_INTEGRATION.md` covers:
- What shipped in this release (paste-the-URL flow).
- Phase A — obs-websocket auto-install (next session): click "Install into current scene" and the companion handles the Browser Source creation via OBS's built-in WebSocket v5 protocol. 4-6 hour ship, well-scoped.
- Phases B-D: multi-scene install, scene-pinned presets, MilkDrop 3 fullscreen mode once the projectM sidecar lands.
Verify
```bash
git clone https://github.com/ALunfb/tracklist-link.git
cd tracklist-link
git checkout v0.5.0
cd frontend && npm install && npm run build && cd ..
cargo build --release
sha256sum target/release/tracklist-link.exe
```
v0.4.1 — tuneable beat detection + live BPM + analyzer punch
Tuning pass on v0.4.0's beat detection framework. Three quality-of-life wins, plus a plan doc for the stats-page tempo panel.
Install / upgrade
Download `tracklist-link.exe` below. Drop-in replacement for v0.4.0 — your existing config (paired token, autostart, preset folder) survives.
What changed since v0.4.0
Beat detection quality
- Sensitivity slider in the Visualizer Tune panel. Drops beat detection threshold from the previous hardcoded 1.6× stddev all the way to 0.5× if you want a hot trigger. Critical for streamers running Spotify at reduced volume under voice chat — the v0.4.0 default was tuned for "music at full blast," which nobody actually does.
- Slider applies live via Arc — no restart needed. Persists to config.
Visualizer reactivity
- Beat events now drive a +55% gain pulse on the analyzer spectrum in the companion viz + the overlay card's bar analyzer. 88%-per-frame decay → ~180 ms half-life. Every preset visibly "punches" on kicks regardless of whether the preset itself keys on bass.
- Overlay card's border-pulse CSS animation now has a beatPulse toggle in the dashboard Overlay tile. Defaults on; `?beat=0` URL param opts out.
BPM where it belongs
- Running beat counter was noise. Replaced with a median-based BPM estimate in both the Visualizer header and the dashboard companion-status tile.
- 8-beat rolling window + 12s staleness cutoff. Silence resets the display to "—" instead of hanging a stale 128.
- docs/STATS_BPM_DISTRIBUTION.md scopes the persistent per-streamer tempo panel for the stats page: Spotify audio-features ingestion, genre-bucketed chart, clickable filtering back into the session archive. Plan only; separate PR when we're ready.
Known caveats
- The default beat_sensitivity of 1.6 is unchanged. If your stream is quieter than most, open Settings → Tune panel → Beat detection and drop it to 0.9–1.2 until the visualizer starts pulsing reliably on kicks.
- Beat detection remains energy-based. Real onset detection (spectral flux, with distinct kick/snare topics) is a future direction — see docs/REACTIVE_SIGNALS.md for the planned topic slots.
Verify the binary
```bash
git clone https://github.com/ALunfb/tracklist-link.git
cd tracklist-link
git checkout v0.4.1
cd frontend && npm install && npm run build && cd ..
cargo build --release
sha256sum target/release/tracklist-link.exe
```
v0.4.0 — Beat detection + audio device selector + reactive-signals framework
Companion and website now share a single reactive-signals bus — FFT, level, beat events all flow through the same pub/sub and drive a matrix of visual effects. This release lays the foundation for future CS2 GSI integration: new topic producers plug in, existing consumers get new reactive dimensions for free.
Install
- Download `tracklist-link.exe` below.
- Double-click. Tray → Pair dashboard. Or just launch the app and paste the token into the dashboard manually.
- Play music. Visualizer tab flashes its accent border on kicks; the overlay card (if paired) pulses too.
What's new since v0.3.0
Beat detection
- Energy-based onset detector on the low 8 log bands. Rolling 1.5s mean + stddev with `sensitivity × stddev` threshold, 180 ms debounce (333 BPM ceiling).
- Emits `audio/beat` frames with a `confidence` 0..1 on the same bus the FFT rides. Wire latency ~20 ms from kick → pulse.
- Visualizer tab: accent border pulses on each beat. Running beat counter in the header.
- Overlay card: pulses the card's border in the streamer's accent color. No extra setup needed — just pair.
- Dashboard companion-status tile: surfaces FFT fps + peak + live beat count as a "your companion is alive" confirmation.
Audio device selector
- Settings tab → new dropdown listing every cpal output device on your machine.
- Default follows Windows system default. Change persists to config. Takes effect on next restart (hot-swap mid-capture is a bigger refactor; shipping the simpler thing).
- Graceful fallback — a named device that's been unplugged since last launch falls back to system default rather than failing startup.
Reactive signals framework
- New `docs/REACTIVE_SIGNALS.md` lays out the producer/consumer contract. Every topic is a wire-level `kind` with `t_ms` + optional `confidence`; consumers subscribe to topic names.
- Current producers: audio capture (FFT + level + beat), server heartbeat.
- Planned producers: CS2 GSI (`game/cs2/round`, `game/cs2/player`, `game/cs2/match`) per `CS2_GSI_ARCHITECTURE.md`. Once the listener lands, every reactive consumer (viz flash, overlay pulse, dashboard tile) automatically picks up CS2 events with zero consumer changes.
Preset previews (scaffold)
- `docs/PRESET_PREVIEWS.md` with the full batch plan.
- `scripts/generate-preset-previews.mjs` in the website repo — Puppeteer-based WebP renderer with 4-worker parallelism. Run with `npm install puppeteer --save-dev && npm run presets:preview`.
- Gallery cards and catalog are ready to surface previews when the batch finishes. Nothing breaks while they're not rendered.
Platform-side shipped alongside
On music.blackpearl.gg:
- Reactivity filter in the preset gallery (bass / mid / treb / vol, with counts). Catalog generator parses each preset's compiled equations at build time to tag it.
- Dashboard companion-status tile: real-time health check for your paired companion.
- Offline-fallback consistency: streamer page header, discover cards, overlay all gracefully render the last session when a stream is offline.
Security
Unchanged: `127.0.0.1` only, origin allowlist, per-install 32-byte token. Hardened CSP with `unsafe-eval` (Butterchurn's compiler needs it) and everything else locked down. MIT-licensed. See `SECURITY.md`.
Verify the binary
```bash
git clone https://github.com/ALunfb/tracklist-link.git
cd tracklist-link
git checkout v0.4.0
cd frontend && npm install && npm run build && cd ..
cargo build --release
sha256sum target/release/tracklist-link.exe
```
v0.3.0 — Tune panel + one-click preset install + autostart + hardened CSP
Follow-up to v0.2.0. The companion is now a legitimately polished desktop app — tuneable visualizer, one-click preset installs, start-on-login with silent tray boot, locked-down Content Security Policy.
Install
- Download `tracklist-link.exe` below.
- Double-click to run. A 1280×820 window + tray icon appear.
- Tray → Pair dashboard pairs with your Tracklist account in one click.
- Browse music.blackpearl.gg/visualizers for presets — click Install URL, paste into the companion's Presets tab → Install. The new preset appears in the Visualizer dropdown with a ◯ prefix.
What's new since v0.2.0
Visualizer tuning
- Tune panel (Visualizer → Tune button): live sliders for audio gain (0.1×-5×), attack + release envelope smoothing, spectrum tilt (bass ↔ treble), noise gate, auto-cycle interval (5-300 s), preset blend time (0-5 s). All persist to localStorage.
- Layout fix: canvas no longer squishes vertically when Tune is open; row pins to `min(70vh, 560px)`.
Preset management
- Install from URL: paste any HTTPS preset URL → fetch + validate + save, with path-traversal + extension + size + JSON-parse guards.
- Visualizer tab merges user + bundled presets: installed `.json` files appear with a ◯ prefix at the top of the dropdown. Rescan button reloads the folder without restart.
Startup behavior
- Launch on Windows startup: Settings toggle writes HKCU...\Run — no admin needed.
- Start minimized to tray: pairs with autostart for a silent login boot.
- Window state persistence: size + position restore on next launch.
Security
- Hardened CSP: `script-src 'self' 'unsafe-eval'` (Butterchurn's compiler needs eval), everything else locked — `object-src 'none'`, `frame-ancestors 'none'`, `base-uri 'self'`. Defense-in-depth against preset-injected XSS.
Fixes
- Visualizer crash: `sampleAudio` override is now Butterchurn-version-tolerant (iterates known stereo-split fields instead of hard-coding mono).
- Settings toggle: knob slides correctly between states now.
- Default window 960×640 → 1280×820.
Platform-side (music.blackpearl.gg)
Shipped alongside:
- Preset gallery (/visualizers): 1738 MIT-licensed presets, search / author filter / reactivity filter (bass / mid / treb / vol) / sort / paginate. Reactivity tags computed at build time by scanning each preset's compiled equations for `a.bass` / `a.mid` / `a.treb` / `a.vol` references.
- Offline fallback: streamer pages, overlay (opt-in `?offline=1`), and discover cards all show the last session's tracks when the stream is down.
Verify the binary
git clone https://github.com/ALunfb/tracklist-link.git
cd tracklist-link
git checkout v0.3.0
cd frontend && npm install && npm run build && cd ..
cargo build --release
sha256sum target/release/tracklist-link.exev0.2.0 — M2: Desktop GUI + MilkDrop visualizer + one-click preset install
Major release. The companion graduates from headless tray → full Windows desktop app with a purple audio-producer UI, a real-time Butterchurn MilkDrop 2 visualizer driven by your system audio, and one-click installs of 1738 MIT-licensed presets from music.blackpearl.gg/visualizers.
Install
- Download
tracklist-link.exebelow. - Double-click to run. A window + tray icon appear.
- From the tray → Pair dashboard, or copy the token manually from the Status tab.
- On the dashboard, paste it into OBS overlay → Reactive analyzer.
- Browse the preset gallery for more MilkDrop presets — click Install URL on any preset, paste into the companion's Presets tab → Install. It shows up in the Visualizer tab's dropdown immediately after a Rescan.
What's new since v0.1.0
Desktop GUI
- Sidebar navigation: Status / Visualizer / Presets / Settings / About
- Dark audio-producer theme (Ableton / FL / Reaper-inspired)
- System tray unchanged — X-to-close hides to tray, right-click menu same as before plus new actions
- Keyboard shortcuts in Visualizer:
N/P/arrows for prev/next,Rrandom,Cauto-cycle,Spacepause,Ffullscreen,?help
Butterchurn MilkDrop 2 visualizer
- Ships with 50 bundled Cream-of-the-Crop presets
- Driven by your real system audio, not a fake pulse — the WASAPI loopback FFT bridges directly into Butterchurn's render loop
- Auto-cycle (30s default), search filter, random shuffle
- Fullscreen ready for OBS Window Capture
Preset system
- 1738 MIT-licensed presets hosted on music.blackpearl.gg/visualizers — search by name/author, filter, sort
- One-click Install from URL in the Presets tab
- Path-traversal + symlink guards on the Rust side; 5 MB preset cap; JSON parse validation
- User presets merge with bundled in the Visualizer tab, marked with a
◯prefix
Pairing
- Tray → Pair dashboard opens the browser with your token pre-filled via URL fragment (never hits the server)
- Dashboard auto-applies pairing + flashes a green banner
Plan docs added
docs/PRESETS_PLATFORM.md— curation infra roadmapdocs/PROJECTM_MILKDROP3.md— Phase 5 architecture (sidecar projectM window)docs/SETTINGS_ROADMAP.md— full settings taxonomydocs/CS2_GSI_SAFETY.md+docs/CS2_GSI_ARCHITECTURE.md— CS2 Game State Integration design
Security
Unchanged from v0.1.0: binds 127.0.0.1 only, Origin allowlist, per-install 32-byte token, constant-time compared. MIT licensed. See SECURITY.md.
The internal UI uses Tauri IPC events for the audio data bridge (not the WS server), so the window never authenticates against the companion's own WS — that stays dedicated to external overlays.
Verify the binary
git clone https://github.com/ALunfb/tracklist-link.git
cd tracklist-link
git checkout v0.2.0
cd frontend && npm install && npm run build && cd ..
cargo build --release
sha256sum target/release/tracklist-link.exeCompare the hash with the attached asset; open an issue if they differ.
v0.1.0 — M1: Windows audio capture + FFT + WS pub/sub
First release of the Tracklist Link companion. Captures your default Windows audio output via WASAPI loopback, runs a 64-band real FFT + RMS/peak, and serves both over a localhost WebSocket to the Tracklist overlay.
Install
- Download
tracklist-link.exebelow. - Double-click to run — a tray icon appears.
- Right-click tray → Copy token.
- Open your Tracklist dashboard → OBS overlay card → Reactive analyzer — Tracklist Link companion → paste token → Save & test.
The peak meter lights up as soon as audio plays on your PC. Set Analyzer to `bars` or `wave` and the overlay pulses with real spectrum data.
What works
- Windows 10/11 WASAPI loopback capture (any default output device)
- 48 kHz, f32 samples verified
- 64-band log-spaced FFT @ ~50 Hz
- RMS + peak level stream
- Token + origin + host header auth (per-install secret, constant-time compared)
- Localhost-only bind, never accepts remote connections
- System tray: Copy token / Open config / Regenerate token / Quit
What's next
See ROADMAP.md.
- M1.1 — one-click pairing (skip the token copy-paste)
- M2 — Butterchurn (MilkDrop 2) overlay preset gallery driven by this FFT feed
- M3 — ProjectM / MilkDrop 3 window that OBS captures as a Window Source
- M4 — CS2 GSI + Dota 2 + Apex game-state events, same pub/sub pattern
- M5 — onset / beat / BPM detection
- M6 — cross-platform (macOS CoreAudio, Linux PulseAudio/PipeWire)
Security
See SECURITY.md for the full threat model.
Short version:
- Binds `127.0.0.1` only
- Origin allowlist (`https://music.blackpearl.gg\`, localhost dev)
- Per-install 32-byte secret, constant-time compared
- No outbound network (update checks deliberately deferred)
- Mic/camera/screen never accessed
- MIT-licensed, reproducible builds welcome
Verify the binary
# From source at the tagged commit:
git clone https://github.com/ALunfb/tracklist-link.git
cd tracklist-link
git checkout v0.1.0
cargo build --release
# Compare hashes with the attached binary:
sha256sum target/release/tracklist-link.exeIf your hash doesn't match the release asset, please open an issue.