Octo-Fiesta

A Subsonic API proxy server that transparently integrates multiple music streaming providers as sources. When a song is not available in your local Navidrome library, it is automatically fetched from your configured provider, downloaded, and served to your Subsonic-compatible client. The downloaded song is then added to your library, making it available locally for future listens.

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

  • Multi-Provider Architecture: Pluggable music service system supporting multiple streaming providers (Deezer, Qobuz, and more to come)
  • Transparent Proxy: Acts as a middleware between Subsonic clients (like Aonsoku, Sublime Music, etc.) and your Navidrome server
  • Seamless Integration: Automatically searches and streams music from your configured provider when not available locally
  • Automatic Downloads: Songs are downloaded on-the-fly and cached for future use
  • External Playlist Support: Search, discover, and download playlists from Deezer and Qobuz with automatic M3U generation
  • Hi-Res Audio Support: Qobuz provider supports up to 24-bit/192kHz FLAC quality
  • 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 folder structure
  • Artist Deduplication: Merges local and streaming provider artists to avoid duplicates in search results
  • Album Enrichment: Local albums are enriched with missing tracks from streaming providers
  • Cover Art Proxy: Serves cover art for external content transparently

Compatible Clients

PC

Android

iOS

Want to improve client compatibility? Pull requests are welcome!

Incompatible Clients

These clients are not compatible with octo-fiesta due to architectural limitations:

  • Symfonium - Uses offline-first architecture and never queries the server for searches, making streaming provider integration impossible. See details

Supported Music Providers

  • Deezer - Quality: FLAC, MP3_320, MP3_128
  • Qobuz - Quality: FLAC, FLAC_24_HIGH (Hi-Res 24-bit/192kHz), FLAC_24_LOW, FLAC_16, MP3_320

Choose your preferred provider via the MUSIC_SERVICE environment variable. Additional providers may be added in future releases.

Requirements

  • A running Subsonic-compatible server (developed and tested with Navidrome)
  • Credentials for at least one music provider:
    • Deezer: ARL token from browser cookies
    • Qobuz: User ID + User Auth Token from browser localStorage (see Wiki guide)
  • Docker and Docker Compose (recommended) or .NET 9.0 SDK for manual installation

Quick Start (Docker)

The easiest way to run Octo-Fiesta is with Docker Compose.

  1. Create your environment file

    cp .env.example .env
    
  2. Edit the .env file with your configuration:

    # Navidrome/Subsonic server URL
    SUBSONIC_URL=http://your-navidrome-server:4533
    
    # Path where downloaded songs will be stored on the host
    DOWNLOAD_PATH=./downloads
    
    # Music service provider (Deezer or Qobuz)
    MUSIC_SERVICE=Qobuz
    
    # === External Playlists (optional) ===
    ENABLE_EXTERNAL_PLAYLISTS=true  # Enable/disable playlist support (default: true)
    PLAYLISTS_DIRECTORY=playlists    # Directory name for M3U files (default: playlists)
    
    # === Qobuz Configuration (if using Qobuz) ===
    QOBUZ_USER_AUTH_TOKEN=your-qobuz-token
    QOBUZ_USER_ID=your-qobuz-user-id
    QOBUZ_QUALITY=FLAC  # FLAC, FLAC_24_HIGH, FLAC_24_LOW, FLAC_16, MP3_320
    
    # === Deezer Configuration (if using Deezer) ===
    DEEZER_ARL=your-deezer-arl-token
    DEEZER_QUALITY=FLAC  # FLAC, MP3_320, MP3_128
    
  3. Start the container

    docker-compose up -d
    

    The proxy will be available at http://localhost:5274.

  4. Configure your Subsonic client

    Point your Subsonic client to http://localhost:5274 instead of your Navidrome server directly.

Tip

: Make sure the DOWNLOAD_PATH points to a directory that Navidrome can scan, so downloaded songs appear in your library.

Configuration

General Settings

Setting Description
Subsonic:Url URL of your Navidrome/Subsonic server
Subsonic:MusicService Music provider to use: Deezer or Qobuz (default: Deezer)
Library:DownloadPath Directory where downloaded songs are stored

Deezer Settings

Setting Description
Deezer:Arl Your Deezer ARL token (required if using Deezer)
Deezer:ArlFallback Backup ARL token if primary fails
Deezer:Quality Preferred audio quality: FLAC, MP3_320, MP3_128. If not specified, the highest available quality for your account will be used

Qobuz Settings

Setting Description
Qobuz:UserAuthToken Your Qobuz User Auth Token (required if using Qobuz) - How to get it
Qobuz:UserId Your Qobuz User ID (required if using Qobuz)
Qobuz:Quality Preferred audio quality: FLAC, FLAC_24_HIGH, FLAC_24_LOW, FLAC_16, MP3_320. If not specified, the highest available quality will be used

External Playlists

Octo-Fiesta supports discovering and downloading playlists from your streaming providers (Deezer and Qobuz).

Setting Description
Subsonic:EnableExternalPlaylists Enable/disable external playlist support (default: true)
Subsonic:PlaylistsDirectory Directory name where M3U playlist files are created (default: playlists)

How it works:

  1. Search for playlists from Deezer or Qobuz using the global search in your Subsonic client
  2. When you "star" (favorite) a playlist, Octo-Fiesta automatically downloads all tracks
  3. An M3U playlist file is created in {DownloadPath}/playlists/ with relative paths to downloaded tracks
  4. Individual tracks are added to the M3U as they are played or downloaded

Environment variable:

# To disable playlists
Subsonic__EnableExternalPlaylists=false

Note

: Due to client-side filtering, playlists from streaming providers may not appear in the "Playlists" tab of some clients, but will show up in global search results.

Getting Credentials

Deezer ARL Token

See the Wiki guide for detailed instructions on obtaining your Deezer ARL token.

Qobuz Credentials

See the Wiki guide for detailed instructions on obtaining your Qobuz User ID and User Auth Token.

Limitations

  • Playlist Search: Subsonic clients like Aonsoku filter playlists client-side from a cached getPlaylists call. Streaming provider playlists appear in global search (search3) but not in the Playlists tab filter.
  • Region Restrictions: Some tracks may be unavailable depending on your region and provider.
  • Token Expiration: Provider authentication tokens expire and need periodic refresh.

Architecture

┌─────────────────┐     ┌──────────────────┐     ┌─────────────────┐
│  Subsonic       │────▶│   Octo-Fiesta    │────▶│   Navidrome     │
│  Client         │◀────│   (Proxy)        │◀────│   Server        │
│  (Aonsoku)      │     │                  │     │                 │
└─────────────────┘     └────────┬─────────┘     └─────────────────┘
                                 │
                                 ▼
                        ┌─────────────────┐
                        │ Music Providers │
                        │  - Deezer       │
                        │  - Qobuz        │
                        │  - (more...)    │
                        └─────────────────┘

Manual Installation

If you prefer to run Octo-Fiesta without Docker:

  1. Clone the repository

    git clone https://github.com/your-username/octo-fiesta.git
    cd octo-fiesta
    
  2. Restore dependencies

    dotnet restore
    
  3. Configure the application

    Edit octo-fiesta/appsettings.json:

    {
      "Subsonic": {
        "Url": "http://your-navidrome-server:4533",
        "MusicService": "Qobuz"
      },
      "Library": {
        "DownloadPath": "./downloads"
      },
      "Qobuz": {
        "UserAuthToken": "your-qobuz-token",
        "UserId": "your-qobuz-user-id",
        "Quality": "FLAC"
      },
      "Deezer": {
        "Arl": "your-deezer-arl-token",
        "ArlFallback": "",
        "Quality": "FLAC"
      }
    }
    
  4. Run the server

    cd octo-fiesta
    dotnet run
    

    The proxy will start on http://localhost:5274 by default.

  5. Configure your Subsonic client

    Point your Subsonic client to http://localhost:5274 instead of your Navidrome server directly.

API Endpoints

The proxy implements the Subsonic API and adds transparent streaming provider integration to:

Endpoint Description
GET /rest/search3 Merged search results from Navidrome + streaming provider (including playlists)
GET /rest/stream Streams audio, downloading from provider if needed
GET /rest/getSong Returns song details (local or from provider)
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
GET /rest/star Stars items; triggers automatic playlist download for external playlists

All other Subsonic API endpoints are passed through to Navidrome unchanged.

External ID Format

External (streaming provider) content uses typed IDs:

Type Format Example
Song ext-{provider}-song-{id} ext-deezer-song-123456, ext-qobuz-song-789012
Album ext-{provider}-album-{id} ext-deezer-album-789012, ext-qobuz-album-456789
Artist ext-{provider}-artist-{id} ext-deezer-artist-259, ext-qobuz-artist-123

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/
│   └── ...
└── playlists/
    ├── My Favorite Songs.m3u
    ├── Chill Vibes.m3u
    └── ...

Playlists are stored as M3U files with relative paths to downloaded tracks, making them portable and compatible with most music players.

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
├── Middleware/
│   └── GlobalExceptionHandler.cs          # Global error handling
├── Models/
│   ├── Domain/                            # Domain entities
│   │   ├── Song.cs
│   │   ├── Album.cs
│   │   └── Artist.cs
│   ├── Settings/                          # Configuration models
│   │   ├── SubsonicSettings.cs
│   │   ├── DeezerSettings.cs
│   │   └── QobuzSettings.cs
│   ├── Download/                          # Download-related models
│   │   ├── DownloadInfo.cs
│   │   └── DownloadStatus.cs
│   ├── Search/
│   │   └── SearchResult.cs
│   └── Subsonic/
│       └── ScanStatus.cs
├── Services/
│   ├── Common/                            # Shared services
│   │   ├── BaseDownloadService.cs         # Template method base class
│   │   ├── PathHelper.cs                  # Path utilities
│   │   ├── Result.cs                      # Result<T> pattern
│   │   └── Error.cs                       # Error types
│   ├── Deezer/                            # Deezer provider
│   │   ├── DeezerDownloadService.cs
│   │   ├── DeezerMetadataService.cs
│   │   └── DeezerStartupValidator.cs
│   ├── Qobuz/                             # Qobuz provider
│   │   ├── QobuzDownloadService.cs
│   │   ├── QobuzMetadataService.cs
│   │   ├── QobuzBundleService.cs
│   │   └── QobuzStartupValidator.cs
│   ├── Local/                             # Local library
│   │   ├── ILocalLibraryService.cs
│   │   └── LocalLibraryService.cs
│   ├── Subsonic/                          # Subsonic API logic
│   │   ├── SubsonicProxyService.cs        # Request proxying
│   │   ├── SubsonicModelMapper.cs         # Model mapping
│   │   ├── SubsonicRequestParser.cs       # Request parsing
│   │   └── SubsonicResponseBuilder.cs     # Response building
│   ├── Validation/                        # Startup validation
│   │   ├── IStartupValidator.cs
│   │   ├── BaseStartupValidator.cs
│   │   ├── SubsonicStartupValidator.cs
│   │   ├── StartupValidationOrchestrator.cs
│   │   └── ValidationResult.cs
│   ├── IDownloadService.cs                # Download interface
│   ├── IMusicMetadataService.cs           # Metadata interface
│   └── StartupValidationService.cs
├── Program.cs                             # Application entry point
└── appsettings.json                       # Configuration

octo-fiesta.Tests/
├── DeezerDownloadServiceTests.cs          # Deezer download tests
├── DeezerMetadataServiceTests.cs          # Deezer metadata tests
├── QobuzDownloadServiceTests.cs           # Qobuz download tests (127 tests)
├── LocalLibraryServiceTests.cs            # Local library tests
├── SubsonicModelMapperTests.cs            # Model mapping tests
├── SubsonicProxyServiceTests.cs           # Proxy service tests
├── SubsonicRequestParserTests.cs          # Request parser tests
└── SubsonicResponseBuilderTests.cs        # Response builder tests

Dependencies

  • BouncyCastle.Cryptography - Blowfish decryption for Deezer streams
  • TagLibSharp - ID3 tag and cover art embedding
  • Swashbuckle.AspNetCore - Swagger/OpenAPI documentation
  • xUnit - Unit testing framework
  • Moq - Mocking library for tests
  • FluentAssertions - Fluent assertion library for tests

License

GPL-3.0

Acknowledgments

  • Navidrome - The excellent self-hosted music server
  • Deezer - Music streaming service
  • Qobuz - Hi-Res music streaming service
  • Subsonic API - The API specification
Description
No description provided
Readme GPL-3.0 7.6 MiB
Languages
C# 90.1%
HTML 9.9%