English | 简体中文 | Cloud Server / Proxy Setup
Original script by Sorrow. Modified with fixes and improvements.
This command-line tool downloads albums, songs, playlists, stations and music videos from Apple Music, preserves or embeds metadata and lyrics, and supports ALAC, AAC and Dolby Atmos. Use it only with content you are entitled to access and in accordance with Apple's terms and applicable law.
- Features
- Supported formats
- Requirements
- Quick Start
- Docker
- Configuration
- Usage
- Upgrade
- For Developers
- Get media-user-token
- Lyrics options
- Credits
- Inline cover art and LRC lyrics.
- Word-by-word and unsynchronized lyrics.
- Artist album downloads.
- Streaming download and decryption for large files.
- Music-video downloads using in-process mp4ff decryption.
- Interactive search and track selection.
| Format | Description | Requires subscription |
|---|---|---|
alac |
audio-alac-stereo |
Yes |
ec3 |
audio-atmos / audio-ec3 |
Yes |
aac |
audio-stereo |
Yes |
aac-lc |
audio-stereo |
Yes |
aac-binaural |
audio-stereo-binaural |
Yes |
aac-downmix |
audio-stereo-downmix |
Yes |
MV |
Music video | Yes |
Stations require a valid media-user-token from an active subscription.
Install and prepare these before running the downloader:
- wrapper-lite: github.com/WorldObservationLog/wrapper/tree/lite. Required backend decryption service. Start it before using this downloader and set its HTTP endpoint in
lite-server, for examplehttp://127.0.0.1:12340. - ffmpeg (Optional): Required only for post-download conversion, animated artwork, or
ffmpeg-dependent features. See ffmpeg.org.
Note: If you are using the precompiled release binaries, Go is NOT required. Go (1.23.1+) is only needed if you build from source (see For Developers).
Download the precompiled binary for your operating system and architecture from the latest GitHub Releases:
| Platform | Architecture | Precompiled Binary |
|---|---|---|
| Windows | x86_64 (64-bit) | amdl_windows_amd64.exe |
| Windows | ARM64 | amdl_windows_arm64.exe |
| macOS | Apple Silicon (M1/M2/M3/M4) | amdl_darwin_arm64 |
| macOS | Intel (x86_64) | amdl_darwin_amd64 |
| Linux | x86_64 (amd64) | amdl_linux_amd64 |
| Linux | ARM64 (aarch64) | amdl_linux_arm64 |
| Android (Termux) | ARM64 (aarch64) | amdl_android_arm64 |
- Open PowerShell and run the following command to download the executable:
# Download precompiled binary (example for 64-bit Windows)
Invoke-WebRequest -Uri "https://github.com/zhaarey/apple-music-downloader/releases/latest/download/amdl_windows_amd64.exe" -OutFile "amdl.exe"- Run
amdl.exeonce to automatically generate the defaultconfig.yaml:
.\amdl.exe- Open and edit
config.yamlto set yourlite-serveraddress and destination paths. - Test running the downloader:
.\amdl.exe --helpExample:
.\amdl.exe "https://music.apple.com/us/album/whenever-you-need-somebody-2022-remaster/1624945511"- Download the precompiled binary:
# For Apple Silicon (M-series):
curl -L -o amdl https://github.com/zhaarey/apple-music-downloader/releases/latest/download/amdl_darwin_arm64
# For Intel Macs:
# curl -L -o amdl https://github.com/zhaarey/apple-music-downloader/releases/latest/download/amdl_darwin_amd64
# Grant execution permission
chmod +x amdlTip (macOS Gatekeeper): If macOS blocks running
amdlbecause it is from an unidentified developer, remove the quarantine attribute:xattr -d com.apple.quarantine amdl
- Run
amdlonce to automatically generate the defaultconfig.yaml:
./amdl- Edit
config.yamlwith your settings. - Run the downloader:
./amdl "https://music.apple.com/us/album/whenever-you-need-somebody-2022-remaster/1624945511"- Download the precompiled binary:
# For x86_64 / amd64:
curl -L -o amdl https://github.com/zhaarey/apple-music-downloader/releases/latest/download/amdl_linux_amd64
# For ARM64:
# curl -L -o amdl https://github.com/zhaarey/apple-music-downloader/releases/latest/download/amdl_linux_arm64
# Grant execution permission
chmod +x amdl- Run
amdlonce to automatically generate the defaultconfig.yaml:
./amdl- Edit
config.yamlwith your settings. - Run the downloader:
./amdl "https://music.apple.com/us/album/whenever-you-need-somebody-2022-remaster/1624945511"Install Termux from F-Droid or the official GitHub releases (do not use the obsolete Play Store version).
- Update packages and install curl (and optionally ffmpeg):
pkg update && pkg upgrade
pkg install -y curl ffmpeg- Grant access to shared Android storage (creates
~/storage/shared):
termux-setup-storage- Download precompiled binary:
curl -L -o amdl https://github.com/zhaarey/apple-music-downloader/releases/latest/download/amdl_android_arm64
chmod +x amdl- Run
amdlonce to automatically generate the defaultconfig.yaml:
./amdl- Edit
config.yaml. To save downloads into Android's shared Music directory, point the paths inconfig.yamlto the shared mount:
paths:
alac: "/sdcard/Music/amdl"
atmos: "/sdcard/Music/amdl-atmos"
aac: "/sdcard/Music/amdl-aac"
mv: "/sdcard/Music/amdl-mv"- Run:
./amdl "https://music.apple.com/us/album/whenever-you-need-somebody-2022-remaster/1624945511"Tips for Termux:
- For long downloads, prevent Android from sleeping with
termux-wake-lock(release withtermux-wake-unlockwhen done).- If wrapper-lite runs on another device on your network, point
lite-serverto that device's LAN IP, not127.0.0.1.- These instructions target current Android arm64 Termux environments; 32-bit Android is not a documented target.
- If self-update on an older version fails with
lookup api.github.com on [::1]:53 ... connection refused, re-download the binary once as in step 3; later versions update normally.
A multi-arch image (linux/amd64, linux/arm64, ffmpeg included) is published to GHCR on every release: ghcr.io/zhaarey/apple-music-downloader. Tags: latest, <major>.<minor>, and the exact version (prereleases only get the exact version).
/data is the working directory inside the container: config.yaml is created there on first run and all download folders (AM-Lossless, ...) end up there too.
wrapper-lite is not part of this image or compose file; run it separately (see Requirements). By default the container looks for it on the Docker host at port 12340.
cp .env.example .env # set AMDL_LITE_SERVER if wrapper-lite is elsewhere; set PUID / PGID
mkdir -p data # keep it user-owned instead of root-owned
docker compose run --rm amdl "https://music.apple.com/us/album/whenever-you-need-somebody-2022-remaster/1624945511"
docker compose run --rm amdl --atmos --select "https://music.apple.com/..."Downloads and config.yaml appear in ./data.
wrapper-lite listens on
127.0.0.1by default, which a container cannot reach. Start it with--host 0.0.0.0(and keep the port firewalled) or pointAMDL_LITE_SERVERat an address it does listen on.
If wrapper-lite already runs somewhere else:
docker run --rm -it --user "$(id -u):$(id -g)" \
-v "$PWD/data:/data" \
-e AMDL_LITE_SERVER=http://192.168.1.10:12340 \
ghcr.io/zhaarey/apple-music-downloader:latest \
"https://music.apple.com/us/album/..."AMDL_LITE_SERVERoverrideslite-serverfromconfig.yaml(the default127.0.0.1is the container itself). An explicit--lite-serverflag still takes precedence.- Keep
-itwhen you use--select, search, or anything else that prompts. - Update by pulling a newer image.
--updatewould only modify the container's own filesystem. - To build locally:
docker build -t amdl .
When amdl is run for the first time without an existing configuration file, it automatically creates config.yaml in the current directory from an embedded default template.
At minimum, review and set:
general:
# wrapper-lite HTTP API endpoint.
lite-server: "http://127.0.0.1:12340"
# Required for stations. See "Get media-user-token" below.
media-user-token: "your-media-user-token"
# Destination folders. Relative paths are resolved from the working directory.
paths:
alac: "AM-Lossless"
atmos: "AM-Atmos"
aac: "AM-AAC"
mv: "AM-MV"If wrapper-lite runs on another machine or container, replace 127.0.0.1 with that host's reachable LAN or public address.
Before running any command, make sure:
- wrapper-lite is running.
config.yamlexists and has the correctlite-servervalue.
./amdl "https://music.apple.com/us/album/whenever-you-need-somebody-2022-remaster/1624945511"On Windows:
.\amdl.exe "https://music.apple.com/us/album/whenever-you-need-somebody-2022-remaster/1624945511"./amdl "https://music.apple.com/us/album/never-gonna-give-you-up-2022-remaster/1624945511?i=1624945512"
./amdl "https://music.apple.com/us/song/you-move-me-2022-remaster/1624945520"./amdl --all-album "https://music.apple.com/us/artist/taylor-swift/159260351"./amdl "https://music.apple.com/us/playlist/taylor-swift-essentials/pl.3950454ced8c45a3b0cc693c2a7db97b"./amdl --select "https://music.apple.com/us/album/whenever-you-need-somebody-2022-remaster/1624945511"Enter track numbers separated by spaces.
./amdl --search album "never gonna give you up"
./amdl --search song "you move me"
./amdl --search artist "taylor swift"./amdl --atmos "https://music.apple.com/us/album/1989-taylors-version-deluxe/1713845538"./amdl --aac "https://music.apple.com/us/album/1989-taylors-version-deluxe/1713845538"./amdl --debug "https://music.apple.com/us/album/1989-taylors-version-deluxe/1713845538"--alac-max <sample-rate>
--atmos-max <bitrate>
--aac-type <aac|aac-lc|aac-binaural|aac-downmix>
--mv-max <resolution>
--mv-audio-type <atmos|ac3|aac>
--lite-server <wrapper-lite-url>
media-user-token is required for stations.
- Open Apple Music and sign in.
- Open browser developer tools with
F12. - Go to
Application>Storage>Cookies>https://music.apple.com. - Find the cookie named
media-user-tokenand copy its value. - Paste it into
general.media-user-tokeninconfig.yaml. - Restart the downloader.
Configure lyrics settings under metadata.lyrics in config.yaml:
metadata:
lyrics:
save-file: false # Save .lrc or .ttml file to disk
embed: true # Embed lyrics directly into audio container tags
type: "lyrics" # Lyrics type: "lyrics" (standard line-by-line) or "syllable-lyrics" (word-by-word)
format: "lrc" # Lyrics file format: "lrc" or "ttml"
extra: "" # Additional options: "" (default), "translation", or "pronunciation"Tips:
- Set
general.languageinconfig.yaml(e.g."en-US","zh-Hans-CN","ja") to control the target language for translated lyrics.extra: set to"translation"for translated lyrics or"pronunciation"for phonetic/romanized lyrics (when provided by Apple Music).
Upgrade to the latest official release with automatic checksum verification and interactive configuration migration:
# Check and perform self-update with interactive config migration
./amdl --update
# Shorthand flag
./amdl -U
# Check for updates without downloading
./amdl --check-update
# Automated / non-interactive mode (automatically accept new option defaults)
./amdl -U -yOn Windows PowerShell:
# Perform self-update
.\amdl.exe --update
# Shorthand flag
.\amdl.exe -UNote: Self-update automatically creates a timestamped
config.yaml.bak_...backup and safely guides the migration of new settings without overwriting your credentials, custom paths, or comments. If a proxy is configured inconfig.yaml, the updater automatically routes through it.
Download the latest precompiled executable from GitHub Releases and replace your current amdl / amdl.exe binary.
For developers building from source, see For Developers.
If you want to contribute, modify the code, or build the downloader from source:
- Go 1.23.1 or newer: go.dev/dl.
- Git: git-scm.com.
- ffmpeg: ffmpeg.org (optional for audio conversion or animated artwork).
macOS / Linux:
git clone https://github.com/zhaarey/apple-music-downloader.git
cd apple-music-downloader
cp config.yaml.example config.yaml
go build -o amdl .
./amdl --helpWindows (PowerShell):
git clone https://github.com/zhaarey/apple-music-downloader.git
cd apple-music-downloader
copy config.yaml.example config.yaml
go build -o amdl.exe .
.\amdl.exe --helpgo run . "https://music.apple.com/us/album/whenever-you-need-somebody-2022-remaster/1624945511"git pull
go build -o amdl .On Windows (PowerShell):
git pull
go build -o amdl.exe .Releases are driven by the VERSION file. When a push to main carries a VERSION whose v<VERSION> tag does not exist yet, the Release workflow builds every platform and publishes a GitHub Release with that tag. To cut a release, bump VERSION (e.g. 0.1.0 → 0.1.1) and merge it into main. A version with a suffix such as 0.2.0-beta.1 is published as a pre-release.
Release binaries self-update from the repository that built them, so a fork's releases update from the fork.
- Sorrow created the original script.
- WorldObservationLog created wrapper / wrapper-lite, used as the backend decryption service.
- Sendy McSenderson contributed the streaming download-and-decrypt implementation.
- go-mp4tag writes station MP4 metadata.
- FFmpeg supports optional conversion and animated-artwork features.