How I kinda Fixed Qobuz's Awful Music Recommendations with AI
Hey folks,
I’ve been using Qobuz since a long time now. For those who don’t know, Qobuz is a French music streaming provider. Unlike Deezer (also French), Spotify, Apple Music and many others, it’s less known but I’ve been subscribed to their service yearly since 2017. So yeah, quite loyal.
Why Qobuz?
What I love:
- Hi-Res audio quality (that’s the main reason I stayed)
- Works well on Android, iOS, and desktop (Windows/Mac)
About That Hi-Res Audio
This is really the killer feature. Qobuz streams in FLAC up to 24-bit/192kHz - that’s studio master quality. To put this in perspective:
| Quality | Format | Bitrate |
|---|---|---|
| MP3 (Spotify, etc.) | Lossy | 320 kbps |
| CD Quality | FLAC 16-bit/44.1kHz | ~1,411 kbps |
| Hi-Res | FLAC 24-bit/96kHz | ~4,608 kbps |
| Hi-Res Max | FLAC 24-bit/192kHz | ~9,216 kbps |
That’s almost 30x more data than Spotify’s maximum quality. You actually hear the difference, especially on good headphones or a proper Hi-Fi setup. The dynamic range, the detail, the separation between instruments - it’s just not the same in lossy formats.
Qobuz offers over 100 million tracks in lossless quality, and they support multiple download formats too: FLAC, ALAC, WAV, AIFF, and even MP3 if you need smaller files. All DRM-free, which I really appreciate.
What drives me crazy:
- Music suggestion algorithm is absolutely awful
- No native Linux desktop app (it’s an Electron app, could have been ported easily imho)
- No fading between tracks (as far as I know)
That’s a lot of cons right? But you know how it goes, each year it renews and you just accept it because what you really care about is listening to music.
The Breaking Point
This year I was about to cancel my subscription and switch to Deezer. They probably have everything I miss at Qobuz. But then I thought… why not fix it myself? The nerd way. With AI (yeah, the hype).
The Idea
What if I could:
- Fetch data from my Qobuz account
- Leverage Last.fm for music discovery
- Use Claude AI for smart curation
- And push tailored playlists directly into my Qobuz account on a weekly basis?
That way I’d get personalized playlists without relying on their crappy algorithm.
Spoiler: it works marvelously. I’m super happy I was able to achieve that in basically an evening.
How It Works
All of this is orchestrated through my self-hosted n8n instance. Here’s the technical breakdown.
Architecture Overview
Step 1: Library Sync
First, I fetch all my favorites from Qobuz and cache them locally in SQLite.
Step 2: Discovery Pipeline
This is where Last.fm comes in. For each artist in my library, I fetch similar artists and their top tracks. This gives me a pool of candidates.
Step 3: Content Filtering
I have kids, so I built in a filter to separate regular content from kids content. Keywords like “relaxation”, “meditation”, “baby”, “enfants”, “comptine”, “lullaby” get filtered into a separate kids playlist.
Step 4: Scoring Algorithm
Not all tracks are equal. I built a weighted scoring system to rank candidates based on how likely I am to enjoy them.
| Factor | Weight | Source |
|---|---|---|
| Artist Similarity | 0.30 | Last.fm match score |
| Genre Overlap | 0.25 | Jaccard index |
| Label Affinity | 0.20 | Same label bonus |
| Year Proximity | 0.15 | Release date closeness |
| Inverse Popularity | 0.10 | Hidden gems bonus |
Example scoring:
| Factor | Raw | Weighted |
|---|---|---|
| Similarity | 0.85 | 0.255 |
| Genre | 0.70 | 0.175 |
| Label | 1.00 | 0.200 |
| Year | 0.90 | 0.135 |
| Popularity | 0.40 | 0.040 |
| Total | 0.805 |
The “Inverse Popularity” factor is interesting - it helps surface hidden gems instead of just recommending mainstream tracks.
Step 5: AI Curation
Here’s where Claude AI comes in. I feed it the top 200 scored candidates along with my user profile (top genres, favorite labels, year preferences, favorite artists). Claude then picks 20 tracks with variety in mind and explains why each one was selected.
Rules for Claude:
- Only select from provided candidates (no hallucination)
- Ensure variety (different artists, labels, years)
- Explain each selection in context of user taste
Step 6: Push to Qobuz
Finally, each curated track is searched on Qobuz, matched by track ID, and pushed to a new playlist.
Bonus: Trending Hits Pipeline
I also built a separate pipeline that fetches trending tracks from Last.fm (both global and France charts), filters out what I already have, and creates a “Les Hits du Moment” playlist.
Weekly Automation with n8n
Everything runs automatically every Sunday morning at 9:00. I get a Telegram notification when the playlists are ready.
Sun 09:00 → Execute Commands →
Error Handling
Since this runs automatically, I built proper error handling with specific error codes that trigger appropriate alerts:
| Error Code | Meaning | Action |
|---|---|---|
QOBUZ_AUTH_FAILED | Token expired | Alert: Refresh token |
ANTHROPIC_NO_CREDITS | Billing needed | Alert: Add API credits |
NO_LIBRARY_DATA | Cache empty | Run sync first |
NO_CANDIDATES_FOUND | Not enough artists | Increase artist count |
Tech Stack
| Component | Technology |
|---|---|
| Runtime | Bun (TypeScript) |
| Architecture | Hexagonal (Ports & Adapters) |
| Database | SQLite (bun:sqlite) |
| Validation | Zod schemas |
| AI | Claude API (Anthropic) |
| HTTP | Custom client with rate limiting |
| Logging | Pino |
| Automation | n8n compatible (JSON output) |
CLI Commands
# Sync your Qobuz library to local cache
bun run start sync
# Preview discovered tracks (no AI, no push)
bun run start discover --artists 20
# Full pipeline: discover + AI curate + push
bun run start generate --artists 20 --tracks 25
# Trending hits playlist (France + Global)
bun run start hits --tracks 25
# JSON output for automation
bun run start generate --json
bun run start hits --json
The Results: Actual Surprises
So what kind of suggestions do I actually get? That’s the real test right?
Well, here’s the thing - the system doesn’t just recommend more of the same. It actually surprised me. One recommendation that genuinely astonished me was:
Experience - Angèle Dubeau Ludovico Einaudi: Portrait (Deluxe Edition)
Classical violin. And you know what? It’s beautiful. I would never have found this on my own, and Qobuz’s algorithm would certainly never have suggested it.
That’s exactly what I wanted: not an echo chamber of similar tracks, but genuine musical discoveries that still somehow connect to my tastes through the scoring algorithm and AI curation.
Wrapping Up
Instead of switching providers, I ended up building something that actually works better than any streaming service’s built-in recommendations. The combination of Last.fm’s data and Claude’s curation gives me genuinely personalized playlists every week.
Was it overkill? Probably. But sometimes the nerd solution is the right solution.
Thanks for reading!
Built with Bun, TypeScript, and Claude AI
Get notified when I publish something new. No spam, unsubscribe anytime.