9.4 KiB
Architecture
This document describes the technical architecture of Allstarr.
System 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.
API Endpoints
Jellyfin Backend (Primary Focus)
The proxy provides comprehensive Jellyfin API support with streaming provider integration:
| Endpoint | Description |
|---|---|
GET /Items |
Search and browse library items (local + streaming providers) |
GET /Artists |
Browse artists with merged results from local + streaming |
GET /Artists/AlbumArtists |
Album artists with streaming provider results |
GET /Users/{userId}/Items |
User library items with external content |
GET /Audio/{id}/stream |
Stream audio, downloading from provider on-demand |
GET /Audio/{id}/Lyrics |
Lyrics from Jellyfin, Spotify, or LRCLib |
GET /Items/{id}/Images/{type} |
Proxy cover art for external content |
GET /Playlists/{id}/Items |
Playlist items (Spotify Import integration) |
POST /UserFavoriteItems/{id} |
Favorite items; copies external tracks to kept folder |
DELETE /UserFavoriteItems/{id} |
Unfavorite items |
POST /Sessions/Playing |
Playback reporting for external tracks |
POST /Sessions/Playing/Progress |
Playback progress tracking |
POST /Sessions/Playing/Stopped |
Playback stopped reporting |
WebSocket /socket |
Real-time session management and remote control |
Admin API (Port 5275):
| Endpoint | Description |
|---|---|
GET /api/admin/health |
Health check endpoint |
GET /api/admin/config |
Get current configuration |
POST /api/admin/config |
Update configuration |
POST /api/admin/cache/clear |
Clear cache |
GET /api/admin/status |
Get system status |
GET /api/admin/memory-stats |
Get memory usage statistics |
POST /api/admin/force-gc |
Force garbage collection |
GET /api/admin/sessions |
Get active sessions |
GET /api/admin/debug/endpoint-usage |
Get endpoint usage statistics |
DELETE /api/admin/debug/endpoint-usage |
Clear endpoint usage log |
GET /api/admin/squidwtf-base-url |
Get SquidWTF base URL |
GET /api/admin/playlists |
List all playlists with status |
GET /api/admin/playlists/{name}/tracks |
Get tracks for playlist |
POST /api/admin/playlists/refresh |
Refresh all playlists |
POST /api/admin/playlists/{name}/match |
Match tracks for playlist |
POST /api/admin/playlists/{name}/clear-cache |
Clear playlist cache |
POST /api/admin/playlists/match-all |
Match all playlists |
POST /api/admin/playlists |
Add new playlist |
DELETE /api/admin/playlists/{name} |
Remove playlist |
POST /api/admin/playlists/{name}/map |
Save manual track mapping |
GET /api/admin/jellyfin/search |
Search Jellyfin library |
GET /api/admin/jellyfin/track/{id} |
Get Jellyfin track details |
GET /api/admin/jellyfin/users |
List Jellyfin users |
GET /api/admin/jellyfin/libraries |
List Jellyfin libraries |
GET /api/admin/jellyfin/playlists |
List Jellyfin playlists |
POST /api/admin/jellyfin/playlists/{id}/link |
Link Jellyfin playlist to Spotify |
DELETE /api/admin/jellyfin/playlists/{name}/unlink |
Unlink playlist |
PUT /api/admin/playlists/{name}/schedule |
Update playlist sync schedule |
GET /api/admin/spotify/user-playlists |
Get Spotify user playlists |
GET /api/admin/spotify/sync |
Trigger Spotify sync |
GET /api/admin/spotify/match |
Trigger Spotify track matching |
POST /api/admin/spotify/clear-cache |
Clear Spotify cache |
GET /api/admin/spotify/mappings |
Get Spotify track mappings (paginated) |
GET /api/admin/spotify/mappings/{spotifyId} |
Get specific Spotify mapping |
POST /api/admin/spotify/mappings |
Save Spotify track mapping |
DELETE /api/admin/spotify/mappings/{spotifyId} |
Delete Spotify mapping |
GET /api/admin/spotify/mappings/stats |
Get Spotify mapping statistics |
GET /api/admin/downloads |
List kept downloads |
DELETE /api/admin/downloads |
Delete kept file |
GET /api/admin/downloads/file |
Download specific file |
GET /api/admin/downloads/all |
Download all files as zip |
GET /api/admin/scrobbling/status |
Get scrobbling status |
POST /api/admin/scrobbling/lastfm/authenticate |
Authenticate Last.fm |
GET /api/admin/scrobbling/lastfm/auth-url |
Get Last.fm auth URL |
POST /api/admin/scrobbling/lastfm/get-session |
Get Last.fm session key |
POST /api/admin/scrobbling/lastfm/test |
Test Last.fm connection |
POST /api/admin/scrobbling/lastfm/debug-auth |
Debug Last.fm auth |
POST /api/admin/scrobbling/listenbrainz/validate |
Validate ListenBrainz token |
POST /api/admin/scrobbling/listenbrainz/test |
Test ListenBrainz connection |
All other Jellyfin API endpoints are passed through unchanged.
Subsonic Backend
The proxy implements the Subsonic API with 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.
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
All downloads are organized under a single base directory (default: ./downloads):
downloads/
├── permanent/ # Permanent downloads (STORAGE_MODE=Permanent)
│ ├── Artist Name/
│ │ ├── Album Title/
│ │ │ ├── 01 - Track One.flac
│ │ │ ├── 02 - Track Two.flac
│ │ │ └── ...
│ │ └── Another Album/
│ │ └── ...
│ └── playlists/
│ ├── My Favorite Songs.m3u
│ └── Chill Vibes.m3u
├── cache/ # Temporary cache (STORAGE_MODE=Cache)
│ └── Artist Name/
│ └── Album Title/
│ └── Track.flac
└── kept/ # Favorited external tracks (always permanent)
└── Artist Name/
└── Album Title/
└── Track.flac
Storage modes:
- Permanent (
downloads/permanent/): Files saved permanently and registered in your media server - Cache (
downloads/cache/): Temporary files, auto-cleaned afterCACHE_DURATION_HOURS - Kept (
downloads/kept/): External tracks you've favorited - always permanent, separate from cache
Playlists are stored as M3U files with relative paths, 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