Track Enrichment & Album Art
When the mix processor emits an on-air track, the track object is not quite ready for display yet. The artist and title might contain feat. tags, the artwork might be a low-resolution thumbnail from a CDJ, and the album name might be missing. The enrichment pipeline cleans this up, fills in missing details, and pairs the track with a high-quality artwork URL before handing it off to your overlays.
The Pipeline
Section titled “The Pipeline”Each raw track passes through six stages:
- Validate — the incoming data is checked against the track schema. If required fields are missing or malformed, the track is rejected.
- Normalise — artist and title are standardised (consistent case, trimmed
whitespace,
feat.tags extracted into a separate field). - Deduplicate — if the same artist and title just went on air, the track is not sent through the rest of the pipeline.
- Enrich — external metadata and artwork are looked up.
- Transform — the internal track shape is converted to the publish format used by outputs.
- Persist — the final track is saved to your play history.
Where Enrichment Data Comes From
Section titled “Where Enrichment Data Comes From”Now Playing looks for enrichment data in a specific order, starting with the fastest, most-trusted sources and falling back to external APIs only when needed.
| Order | Source | What It Provides |
|---|---|---|
| 1 | Your own cache | Artwork seen for this exact track previously |
| 2 | Global cache | Artwork another Now Playing user has already uploaded |
| 3 | Track source payload | Embedded artwork from Rekordbox, Serato, djay, etc. |
| 4 | Beatport | Dance music metadata and cover art |
| 5 | Apple Music | Broad catalog coverage, high-resolution cover art |
| 6 | MusicBrainz / Cover Art Archive | Open catalog fallback |
Because so many tracks are seen globally across Now Playing users, the cache hit rate is high — most tracks you play have artwork ready within milliseconds. Only rare or unreleased tracks require a live API lookup.
Album Art Extraction
Section titled “Album Art Extraction”The desktop app tries to pull artwork straight from the source whenever it can:
- Local files (Rekordbox, Serato, djay, VirtualDJ) — the app reads embedded artwork directly from the MP3, FLAC, M4A, or AIFF file using a metadata library.
- Pioneer CDJs / XDJs over PRO DJ LINK — the app performs a partial NFS read against the CDJ’s USB or SD card, streaming only the first 1–2 MB of the audio file to extract the embedded artwork without downloading the full track.
- Spotify and URL-based sources — the app downloads the artwork URL directly.
- djay Pro streaming sources — no local extraction is possible, so enrichment falls back to the external API chain.
Once artwork is extracted, it is hashed. The hash becomes the artwork’s identifier so that identical images (the same release, the same cover) are stored only once across all users.
The Artwork Cache
Section titled “The Artwork Cache”Artwork is cached in two layers:
- Redis — fast in-memory cache keyed by track signature and content hash. This is the layer that keeps overlay updates under a second.
- Cloudflare R2 — permanent storage for the actual image bytes, served through the Cloudflare CDN.
Every artwork URL you see on your overlay is a CDN URL backed by R2. Even though the first user to ever play a particular track triggers a full extraction and upload, everyone else who plays that same track gets an instant cache hit.
Image Sizes
Section titled “Image Sizes”Each artwork is processed into multiple sizes for different use cases:
- Thumbnail — 64 × 64 pixels, used for compact overlay widgets.
- Small — 180 × 180 pixels.
- Medium — 300 × 300 pixels, the default for most overlays.
- Large — 500 × 500 pixels, used for full-screen and high-resolution themes.
Images are stored in WebP with JPEG fallback for older browser support.
What Gets Sent to Outputs
Section titled “What Gets Sent to Outputs”After enrichment, a track contains the cleaned-up metadata and a set of artwork URLs ready for consumption:
{ artist: "Artist Name", title: "Track Title", album: "Album Name", featuring: ["Guest Artist"], bpm: 128, key: "8A", artwork: { thumb: "https://cdn.nowplayingapp.com/...", small: "https://cdn.nowplayingapp.com/...", medium: "https://cdn.nowplayingapp.com/...", large: "https://cdn.nowplayingapp.com/..." }}The enriched track is what your output services receive — not the raw track from your DJ software.
Why Enrichment Matters
Section titled “Why Enrichment Matters”Raw metadata from DJ software is inconsistent. One track might read “Artist feat. Guest” while the same track on another source reads “Artist ft. Guest”. Rekordbox might include the key in one field; Serato might put it somewhere else. Enrichment smooths over these differences, so your overlays display a consistent, branded-looking track card regardless of which DJ software you used to load the track.