Octo-Fiesta
A Subsonic API proxy server that transparently integrates Deezer as a music source. When a song is not available in your local Navidrome library, it is automatically fetched from Deezer, downloaded, and served to your Subsonic-compatible client.
Why "Octo-Fiesta"?
The name was randomly generated by GitHub when creating the repository. We found it amusing and somewhat fitting for a music application — after all, "fiesta" evokes a party atmosphere, which goes well with music streaming. So we kept it!
Features
- Transparent Proxy: Acts as a middleware between Subsonic clients (like Aonsoku, Sublime Music, etc.) and your Navidrome server
- Deezer Integration: Seamlessly searches and streams music from Deezer when not available locally
- Automatic Downloads: Songs are downloaded on-the-fly and cached for future use
- Full Metadata Embedding: Downloaded files include complete ID3 tags (title, artist, album, track number, year, genre, BPM, ISRC, etc.) and embedded cover art
- Organized Library: Downloads are saved in a clean
Artist/Album/Track.mp3folder structure - Artist Deduplication: Merges local and Deezer artists to avoid duplicates in search results
- Album Enrichment: Local albums are enriched with missing tracks from Deezer
- Cover Art Proxy: Serves cover art for external content transparently
Architecture
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Subsonic │────▶│ Octo-Fiesta │────▶│ Navidrome │
│ Client │◀────│ (Proxy) │◀────│ Server │
│ (Aonsoku) │ │ │ │ │
└─────────────────┘ └────────┬─────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ Deezer API │
│ (Metadata + │
│ Downloads) │
└─────────────────┘
Requirements
- .NET 9.0 SDK
- A running Navidrome server
- A Deezer ARL token (for downloading)
Installation
-
Clone the repository
git clone https://github.com/your-username/octo-fiesta.git cd octo-fiesta -
Restore dependencies
dotnet restore -
Configure the application
Edit
octo-fiesta/appsettings.json:{ "Subsonic": { "Url": "http://your-navidrome-server:4533" }, "Library": { "DownloadPath": "./downloads" }, "Deezer": { "Arl": "your-deezer-arl-token", "ArlFallback": "" } } -
Run the server
cd octo-fiesta dotnet runThe proxy will start on
http://localhost:5274by default. -
Configure your Subsonic client
Point your Subsonic client to
http://localhost:5274instead of your Navidrome server directly.
Configuration
Subsonic Settings
| Setting | Description |
|---|---|
Subsonic:Url |
URL of your Navidrome/Subsonic server |
Library Settings
| Setting | Description |
|---|---|
Library:DownloadPath |
Directory where downloaded songs are stored |
Deezer Settings
| Setting | Description |
|---|---|
Deezer:Arl |
Your Deezer ARL token (required for downloads) |
Deezer:ArlFallback |
Backup ARL token if primary fails |
Getting a Deezer ARL Token
- Log in to Deezer in your browser
- Open Developer Tools (F12)
- Go to Application > Cookies >
https://www.deezer.com - Find the
arlcookie and copy its value
Note
: ARL tokens expire periodically and need to be refreshed.
API Endpoints
The proxy implements the Subsonic API and adds transparent Deezer integration to:
| Endpoint | Description |
|---|---|
GET /rest/search3 |
Merged search results from Navidrome + Deezer |
GET /rest/stream |
Streams audio, downloading from Deezer if needed |
GET /rest/getSong |
Returns song details (local or Deezer) |
GET /rest/getAlbum |
Returns album with tracks from both sources |
GET /rest/getArtist |
Returns artist with albums from both sources |
GET /rest/getCoverArt |
Proxies cover art for external content |
All other Subsonic API endpoints are passed through to Navidrome unchanged.
External ID Format
External (Deezer) content uses typed IDs:
| Type | Format | Example |
|---|---|---|
| Song | ext-deezer-song-{id} |
ext-deezer-song-123456 |
| Album | ext-deezer-album-{id} |
ext-deezer-album-789012 |
| Artist | ext-deezer-artist-{id} |
ext-deezer-artist-259 |
Legacy format ext-deezer-{id} is also supported (assumes song type).
Download Folder Structure
Downloaded music is organized as:
downloads/
├── Artist Name/
│ ├── Album Title/
│ │ ├── 01 - Track One.mp3
│ │ ├── 02 - Track Two.mp3
│ │ └── ...
│ └── Another Album/
│ └── ...
└── Another Artist/
└── ...
Metadata Embedding
Downloaded files include:
- Basic: Title, Artist, Album, Album Artist
- Track Info: Track Number, Total Tracks, Disc Number
- Dates: Year, Release Date
- Audio: BPM, Duration
- Identifiers: ISRC (in comments)
- Credits: Contributors/Composers
- Visual: Embedded cover art (high resolution)
- Rights: Copyright, Label
Development
Build
dotnet build
Run Tests
dotnet test
Project Structure
octo-fiesta/
├── Controllers/
│ └── SubsonicController.cs # Main API controller
├── Models/
│ ├── MusicModels.cs # Song, Album, Artist, etc.
│ └── SubsonicSettings.cs # Configuration model
├── Services/
│ ├── DeezerDownloadService.cs # Deezer download & decryption
│ ├── DeezerMetadataService.cs # Deezer API integration
│ ├── IDownloadService.cs # Download interface
│ ├── IMusicMetadataService.cs # Metadata interface
│ └── LocalLibraryService.cs # Local file management
├── Program.cs # Application entry point
└── appsettings.json # Configuration
octo-fiesta.Tests/
├── DeezerDownloadServiceTests.cs
├── DeezerMetadataServiceTests.cs
└── LocalLibraryServiceTests.cs
Dependencies
- BouncyCastle.Cryptography - Blowfish decryption for Deezer streams
- TagLibSharp - ID3 tag and cover art embedding
- Swashbuckle.AspNetCore - Swagger/OpenAPI documentation
Limitations
- Playlist Search: Subsonic clients like Aonsoku filter playlists client-side from a cached
getPlaylistscall. Deezer playlists appear in global search (search3) but not in the Playlists tab filter. - Region Restrictions: Some Deezer tracks may be unavailable depending on your region.
- ARL Expiration: Deezer ARL tokens expire and need periodic refresh.
License
MIT
Acknowledgments
- Navidrome - The excellent self-hosted music server
- Deezer - Music streaming service
- Subsonic API - The API specification