Jellyfin expects playback endpoints to have bodies wrapped:
- /Sessions/Playing -> {"playbackStartInfo": {...}}
- /Sessions/Playing/Progress -> {"playbackProgressInfo": {...}}
- /Sessions/Playing/Stopped -> {"playbackStopInfo": {...}}
This fixes the 'field is required' validation errors.
Allstarr
A media server proxy that integrates music streaming providers with your local library. Works with Jellyfin and Subsonic-compatible servers (Navidrome). When a song isn't in your local library, it gets fetched from your configured provider, downloaded, and served to your client. The downloaded song then lives in your library for next time.
THIS IS UNDER ACTIVE DEVELOPMENT
Please report all bugs as soon as possible, as the Jellyfin addition is entirely a test at this point
Quick Start
# 1. Configure environment
cp .env.example .env
nano .env # Edit with your settings
# 2. Start services
docker-compose up -d --build
# 3. Check status
docker-compose ps
docker-compose logs -f
Nginx Proxy Setup (Required)
This service only exposes ports internally. You must use nginx to proxy to it:
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
# Security headers
add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-Content-Type-Options "nosniff" always;
# Streaming settings
proxy_buffering off;
proxy_request_buffering off;
proxy_read_timeout 600s;
location / {
proxy_pass http://allstarr:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Security: All authentication is forwarded to Jellyfin - this is as secure as Jellyfin itself. Always use HTTPS for public access.
Why "Allstarr"?
This project brings together all the music streaming providers into one unified library - making them all stars in your collection.
Features
- Dual Backend Support: Works with Jellyfin and Subsonic-compatible servers (Navidrome, Airsonic, etc.)
- Multi-Provider Architecture: Pluggable system for streaming providers (Deezer, Qobuz, SquidWTF)
- Transparent Proxy: Sits between your music clients and media server
- Automatic Search: Searches streaming providers when songs aren't local
- On-the-Fly Downloads: Songs download and cache for future use
- External Playlist Support: Search and download playlists from Deezer, Qobuz, and SquidWTF with M3U generation
- Hi-Res Audio: SquidWTF supports up to 24-bit/192kHz FLAC
- Full Metadata: Downloaded files include complete ID3 tags (title, artist, album, track number, year, genre, BPM, ISRC, etc.) and cover art
- Organized Library: Downloads save in
Artist/Album/Trackfolder structure - Artist Deduplication: Merges local and streaming artists to avoid duplicates
- Album Enrichment: Adds missing tracks to local albums from streaming providers
- Cover Art Proxy: Serves cover art for external content
Supported Backends
Jellyfin
Jellyfin is a free and open-source media server. Allstarr connects via the Jellyfin API using your Jellyfin user login. (I plan to move this to api key if possible)
Compatible Jellyfin clients:
Working on getting more currently
Subsonic/Navidrome
Navidrome and other Subsonic-compatible servers are supported via the Subsonic API.
Compatible Subsonic clients:
PC
Android
iOS
Want to improve client compatibility? Pull requests are welcome!
Incompatible Clients
These clients are not compatible with Allstarr 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
- SquidWTF - Quality: FLAC (Hi-Res 24-bit/192kHz & CD-Lossless 16-bit/44.1kHz), AAC
- 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 media server:
- Jellyfin: Any recent version with API access enabled
- Subsonic: Navidrome or other Subsonic-compatible server
- Credentials for at least one music provider (IF NOT USING SQUIDWTF):
- 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 Allstarr is with Docker Compose.
-
Create your environment file
cp .env.example .env -
Edit the
.envfile with your configuration:For Jellyfin backend:
# Backend selection BACKEND_TYPE=Jellyfin # Jellyfin server URL JELLYFIN_URL=http://localhost:8096 # API key (get from Jellyfin Dashboard > API Keys) JELLYFIN_API_KEY=your-api-key-here # User ID (from Jellyfin Dashboard > Users > click user > check URL) JELLYFIN_USER_ID=your-user-id-here # Music library ID (optional, auto-detected if not set) JELLYFIN_LIBRARY_ID=For Subsonic/Navidrome backend:
# Backend selection BACKEND_TYPE=Subsonic # Navidrome/Subsonic server URL SUBSONIC_URL=http://localhost:4533Common settings (both backends):
# Path where downloaded songs will be stored DOWNLOAD_PATH=./downloads # Music service to use: SquidWTF, Deezer, or Qobuz MUSIC_SERVICE=SquidWTF # Storage mode: Permanent or Cache STORAGE_MODE=PermanentSee the full
.env.examplefor all available options including Deezer/Qobuz credentials. -
Start the container
docker-compose up -dThe proxy will be available at
http://localhost:5274. -
Configure your client
Point your music client to
http://localhost:5274instead of your media server directly.
Tip
: Make sure the
DOWNLOAD_PATHpoints to a directory that your media server can scan, so downloaded songs appear in your library.
Configuration
Backend Selection
| Setting | Description |
|---|---|
Backend:Type |
Backend type: Subsonic or Jellyfin (default: Subsonic) |
Jellyfin Settings
| Setting | Description |
|---|---|
Jellyfin:Url |
URL of your Jellyfin server |
Jellyfin:ApiKey |
API key (get from Jellyfin Dashboard > API Keys) |
Jellyfin:UserId |
User ID for library access |
Jellyfin:LibraryId |
Music library ID (optional, auto-detected) |
Jellyfin:MusicService |
Music provider: SquidWTF, Deezer, or Qobuz |
Subsonic Settings
| Setting | Description |
|---|---|
Subsonic:Url |
URL of your Navidrome/Subsonic server |
Subsonic:MusicService |
Music provider: SquidWTF, Deezer, or Qobuz (default: SquidWTF) |
Shared Settings
| Setting | Description |
|---|---|
Library:DownloadPath |
Directory where downloaded songs are stored |
*:ExplicitFilter |
Content filter: All, ExplicitOnly, or CleanOnly |
*:DownloadMode |
Download mode: Track or Album |
*:StorageMode |
Storage mode: Permanent or Cache |
*:CacheDurationHours |
Cache expiration time in hours |
*:EnableExternalPlaylists |
Enable external playlist support |
SquidWTF Settings
| Setting | Description |
|---|---|
SquidWTF:Quality |
Preferred audio quality: FLAC, MP3_320, MP3_128. If not specified, the highest available quality for your account will be used |
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
Allstarr supports discovering and downloading playlists from your streaming providers (SquidWTF, 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:
- Search for playlists from an external provider using the global search in your Subsonic client
- When you "star" (favorite) a playlist, Allstarr automatically downloads all tracks
- An M3U playlist file is created in
{DownloadPath}/playlists/with relative paths to downloaded tracks - 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
getPlaylistscall. 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
┌─────────────────┐
┌───▶│ Jellyfin │
┌─────────────────┐ ┌──────────────────┐ │ │ Server │
│ Music Client │────▶│ Allstarr │───┤ └─────────────────┘
│ (Aonsoku, │◀────│ (Proxy) │◀──┤
│ Finamp, etc.) │ │ │ │ ┌─────────────────┐
└─────────────────┘ └────────┬─────────┘ └───▶│ Navidrome │
│ │ (Subsonic) │
▼ └─────────────────┘
┌─────────────────┐
│ Music Providers │
│ - SquidWTF │
│ - Deezer │
│ - Qobuz │
└─────────────────┘
The proxy intercepts requests from your music client and:
- Forwards library requests to your configured backend (Jellyfin or Subsonic)
- Merges results with content from your music provider
- Downloads and caches external tracks on-demand
- Serves audio streams transparently
Note: Only the controller matching your configured BACKEND_TYPE is registered at runtime, preventing route conflicts and ensuring clean API separation.
Manual Installation
If you prefer to run Allstarr without Docker:
-
Clone the repository
git clone https://github.com/your-username/allstarr.git cd allstarr -
Restore dependencies
dotnet restore -
Configure the application
Edit
allstarr/appsettings.json:For Jellyfin:
{ "Backend": { "Type": "Jellyfin" }, "Jellyfin": { "Url": "http://localhost:8096", "ApiKey": "your-api-key", "UserId": "your-user-id", "MusicService": "SquidWTF" }, "Library": { "DownloadPath": "./downloads" } }For Subsonic/Navidrome:
{ "Backend": { "Type": "Subsonic" }, "Subsonic": { "Url": "http://localhost:4533", "MusicService": "SquidWTF" }, "Library": { "DownloadPath": "./downloads" } } -
Run the server
cd allstarr dotnet runThe proxy will start on
http://localhost:5274by default. -
Configure your client
Point your music client to
http://localhost:5274instead of your media server directly.
API Endpoints
Subsonic Backend
The proxy implements the Subsonic API and adds transparent streaming provider integration:
| Endpoint | Description |
|---|---|
GET /rest/search3 |
Merged search results from Navidrome + streaming provider |
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.
Jellyfin Backend
The proxy implements a subset of the Jellyfin API:
| Endpoint | Description |
|---|---|
GET /Items |
Search and browse library items |
GET /Artists |
Browse artists with streaming provider results |
GET /Audio/{id}/stream |
Stream audio, downloading from provider if needed |
GET /Items/{id}/Images/{type} |
Proxy cover art for external content |
POST /UserFavoriteItems/{id} |
Favorite items; triggers playlist download |
All other Jellyfin API endpoints are passed through 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
allstarr/
├── Controllers/
│ ├── JellyfinController.cs # Jellyfin API controller (registered when Backend:Type=Jellyfin)
│ └── SubsonicController.cs # Subsonic API controller (registered when Backend:Type=Subsonic)
├── 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
allstarr.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