Apple Music Lossless Audio Service — an HTTP API and pipeline for downloading Apple Music tracks in AAC 256k and Hi-Res ALAC (24-bit / 48kHz+).
aria is a self-hosted service that downloads Apple Music tracks in lossless quality. Give it a song ID or album ID, and it returns a fully tagged .m4a file — with cover art, metadata, and bit-perfect audio.
It supports two quality tiers:
Lossy, compact. Uses Widevine CDM + mp4decrypt. ~5 MB per track. Good for casual listening.
Lossless, Hi-Res. Uses FairPlay via sidecar. ~50 MB per track. Bit-for-bit identical to the studio master.
If you're new to lossless audio, here's what the terms mean:
| Format | Type | Bitrate | Quality | File Size (4 min) |
|---|---|---|---|---|
| MP3 320k | Lossy | 320 kbps | Good | ~10 MB |
| AAC 256k | Lossy | 256 kbps | Very Good (better than MP3 at same rate) | ~8 MB |
| ALAC 16/44.1 | Lossless | ~900 kbps | CD Quality | ~27 MB |
| ALAC 24/48 | Lossless | ~2500 kbps | Hi-Res (studio master) | ~50 MB |
| ALAC 24/192 | Lossless | ~9200 kbps | Ultra Hi-Res | ~180 MB |
ALAC (Apple Lossless Audio Codec) compresses audio without losing any data. When you decompress it, you get back the exact same samples the studio recorded. This is different from AAC/MP3, which permanently discard sounds your brain is less likely to notice (psychoacoustic masking).
Bit depth (16 vs 24) determines dynamic range — 24-bit can represent quieter details. Sample rate (44.1 vs 48 vs 192 kHz) determines the highest frequency that can be captured — 48kHz covers well beyond human hearing (20kHz).
When you request a track, aria goes through 9 steps to deliver a playable file:
e.g. python aria_lite.py 1615585008 --fmt alac
Calls the Apple Music catalog API to get the song's name, artist, album, artwork URL, and HLS playlist URL.
A .m3u8 file listing all available quality variants (AAC, ALAC at various sample rates).
m3u8_select.py chooses the highest-quality ALAC stream (24-bit, up to 192kHz).
The stream is a fragmented MP4 file (50+ MB) containing encrypted ALAC samples. Downloaded from Apple's CDN.
Samples are sent over TCP to the sidecar service, which decrypts them one by one using FairPlay. Pipelined for speed (15 MB/s).
m4a_writer.py patches the MP4: renames enca (encrypted) to alac in all sample descriptions, and neutralizes encryption metadata boxes.
Uses mutagen to embed title, artist, album, track number, cover art (1200x1200 JPEG) into the .m4a iTunes atoms.
24-bit / 48kHz ALAC, fully tagged, ready for any player.
Apple Music delivers audio as fragmented MP4 (fMP4). Understanding its structure is key to the container repair step.
The decrypt step uses a pipelined TCP protocol. Instead of send-wait-recv per sample (serial), aria uses two threads that run simultaneously:
$ python aria_lite.py 1615585008
┌─────────────────────────────────────────────┐
│ aria_lite — Apple Music Audio Pipeline │
└─────────────────────────────────────────────┘
remote http://your-server via proxy
aria connected via LAN direct
09:12:30 [ init] song_id=1615585008
09:12:30 [ key] key=7c9cd95cb929... cached=True stream=yes
09:12:31 [ fetch] ██████████████████████████████ 100% 5718/5718 KB
09:12:31 [ decrypt] mp4decrypt done
09:12:31 [ verify] valid audio — 167.4s
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Result
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1 downloaded
duration 2:47 · size 5.5 MB · elapsed 1.2s$ python aria_lite.py 1850496033 --fmt alac
09:14:22 [ aria] downloading ALAC via aria service
09:14:35 [ aria] 48861 KB downloaded
09:14:35 [ verify] valid ALAC — 226.1s (2650 packets, 48000Hz, 24bit)
09:14:36 [ tag] tagged: The Fate of Ophelia — Taylor Swift
1 downloaded · duration 3:46 · size 47.7 MB · elapsed 13.2s$ python aria_lite.py --album 1850496031 --fmt alac -j 2
09:20:10 [ album] The Life of a Showgirl — Taylor Swift — 19 tracks
09:20:10 [ album] output: output/album.1850496031.Taylor Swift - .../
09:20:22 [ verify] valid ALAC — 226.1s The Fate of Ophelia
09:20:38 [ verify] valid ALAC — 208.3s Elizabeth Taylor
09:20:55 [ verify] valid ALAC — 235.4s Opalite
...
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
The Life of a Showgirl + Acoustic Collection
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
19 downloaded
duration 68:58 · size 849.7 MB · elapsed 347.9s$ python aria_lite.py 1615585008 --info
As It Was
──────────────────────────────────────────
artist Harry Styles
album Harry's House
duration 2:47
id 1615585008
isrc USSM12200612
genre Pop, Music
quality atmos, lossless, lossy-stereo, spatialAll endpoints except / and /health require Authorization: Bearer TOKEN.
| Method | Endpoint | Description |
|---|---|---|
| GET | /health | Service health (no auth) |
| GET | /search?q=term&type=songs | Search songs, albums, artists |
| GET | /song/<id> | Song metadata |
| GET | /album/<id> | Album + track list |
| GET | /artist/<id> | Artist + albums |
| GET | /download/<id>?fmt=alac | Download (default AAC; ?fmt=alac for Hi-Res) |
| GET | /album/<id>/download | Download album as ZIP |
| POST | /batch | Batch download: {"ids":[...],"fmt":"alac"} |
| Phase | Time | Share |
|---|---|---|
| m3u8 resolve | 0.44s | 5% |
| CDN download | 1.80s | 22% |
| fMP4 parse | 45ms | 1% |
| Decrypt (pipelined) | 3.12s | 38% |
| m4a write | ~100ms | 1% |
| Audio verify | ~0.5s | 6% |
| Total | ~8.3s | 100% |
| Metric | wrapper | wrapper-v2 | sidecar v4 |
|---|---|---|---|
| Cold startup | 2338 ms | ~5000 ms (est.) | 2163 ms |
| Decrypt | 15.0 MB/s | ~15 MB/s | 15.3 MB/s |
| Memory | 53.8 MB | ~150 MB (est.) | 52.3 MB |
| Container | No | Docker | No |
| Source | Closed | Rust (open) | C 935 lines |
| Optimization | Before | After | Impact |
|---|---|---|---|
| TCP_NODELAY | Connection reset | 4.36s | Required |
| Pipelining | 4.36s | 3.12s | 1.4x |
| Streaming BMFF | 179 MB peak | 11 MB | 94% memory |
| Namespace reduction | USER+NS+PID | USER+PID | 7.5% startup |
| Environment Variable | Default | Description |
|---|---|---|
API_TOKEN | (required) | Auth token for protected endpoints |
ARIA_INSTANCES | 1 | Number of sidecar decrypt instances |
STOREFRONT | us | Apple Music region |
CACHE_DIR | /tmp/am_cache | Decrypted file cache |
ARIA_HOST | 127.0.0.1 | sidecar host |
ARIA_DECRYPT_PORT | 47010 | sidecar decrypt port |
ARIA_M3U8_PORT | 47020 | sidecar m3u8 port |