Projektüberblick
Quelldateien
Diese Seite wurde aus den folgenden Quelldateien erstellt:
Apple Music ALAC / Dolby Atmos Downloader ist ein in Go geschriebenes Kommandozeilen-Werkzeug zum Herunterladen von Musikinhalten aus Apple Music in verlustfreien Audioformaten. Das Projekt, ursprünglich von Sorrow entwickelt und später erweitert, ermöglicht den Download von ALAC (Apple Lossless Audio Codec), Dolby Atmos und AAC-Formaten sowie Musikvideos. Die Implementierung nutzt Frida-basierte Agent-Skripte zur FairPlay-DRM-Entschlüsselung und unterstützt erweiterte Funktionen wie eingebettete Cover, LRC-Lyrics und automatische Album-Erkennung für Künstler (README.md:1-28, README-CN.md:1-28).
Projektübersicht und Kernfunktionalität
Das Projekt adressiert die Anforderung, Apple Music Inhalte in hoher Audioqualität lokal zu archivieren. Die Kernfunktionalität umfasst:
- Verlustfreie Audioformate: Unterstützung für ALAC, Dolby Atmos (EC3), AAC-Varianten (LC, Binaural, Downmix)
- Musikvideo-Download: Integration mit mp4decrypt für MV-Entschlüsselung
- Metadaten-Verarbeitung: Eingebettete Cover, Lyrics (LRC/TTML), Wort-für-Wort-Synchronisation
- Künstler-Alben-Download: Automatische Auswahl aller Alben eines Interpreten via
--all-albumFlag - Interaktive Suche: Pfeiltasten-Navigation für Song-/Album-/Künstler-Suche
- Speicheroptimierte Entschlüsselung: On-the-fly Entschlüsselung während des Downloads zur Vermeidung von Speicherüberlauf bei großen Dateien
Die Architektur trennt Konfiguration, Download-Logik und DRM-Behandlung in unterschiedliche Module. Die Konfiguration erfolgt zentral über config.yaml, während die Download-Verarbeitung in utils/runv2/runv2.go implementiert ist (README.md:1-28, README-CN.md:1-28).
Technologie-Stack
| Komponente | Technologie | Version | Zweck |
|---|---|---|---|
| Kernsprache | Go | 1.23.1 | Hauptimplementierung |
| MP4-Manipulation | mp4ff | 0.50.0 | ISO-BMFF/MP4-Verarbeitung |
| HTTP-Client | go-resty | 2.16.5 | API-Kommunikation |
| M3U8-Parser | grafov/m3u8 | 0.11.1 | HLS-Playlist-Verarbeitung |
| DRM-Entschlüsselung | Frida Agent | - | FairPlay Key Extraction |
| Containerisierung | Docker | Multi-Stage | Deployment-Umgebung |
| Externe Tools | MP4Box, mp4decrypt, FFmpeg | - | Medienverarbeitung |
Die Abhängigkeiten sind in go.mod definiert und umfassen kritische Bibliotheken wie github.com/Eyevinn/mp4ff für MP4-Container-Manipulation und github.com/grafov/m3u8 für HLS-Playlist-Parsing (go.mod:1-45).
Verzeichnisstruktur
apple-music-downloader/
├── main.go # Einstiegspunkt, CLI-Handling
├── config.yaml # Zentrale Konfiguration
├── go.mod # Go-Modul-Definition
├── Dockerfile # Multi-Stage Container-Build
├── agent.js # Frida Agent (x86_64)
├── agent-arm64.js # Frida Agent (ARM64)
└── utils/
├── runv2/
│ └── runv2.go # Download- und Entschlüsselungslogik
└── task/
└── album.go # Album-Verarbeitung
Die Struktur folgt einer funktionalen Trennung: main.go behandelt CLI-Argumente und URL-Parsing, während utils/runv2/runv2.go den komplexen Download- und Entschlüsselungsprozess kapselt (main.go:67-128, utils/runv2/runv2.go:33-207).
Systemarchitektur und Modulübersicht
Die Architektur besteht aus vier Hauptschichten: CLI-Eingabe, Konfigurationsverwaltung, Download-Engine und DRM-Entschlüsselung. Die folgende Grafik zeigt die Modulabhängigkeiten und Datenflüsse:
正在加载图表渲染器...
Architektur-Erklärung:
- CLI & Eingabe:
main.goparst Kommandozeilenargumente und validiert Apple Music URLs mittels Regex-Patterns für Alben (checkUrl) und Musikvideos (checkUrlMv) (main.go:109-128) - Konfiguration: Die YAML-Konfiguration wird in eine
ConfigSet-Struktur geladen, die alle Laufzeitparameter wie Token, Pfade und Formate enthält (main.go:67-81) - Download-Engine:
runv2.goimplementiert den Streaming-Download mit adaptivem Speichermanagement, das zwischen In-Memory- und Datei-basierter Pufferung wählt (utils/runv2/runv2.go:169-184) - DRM-Entschlüsselung: Der Frida-Agent extrahiert FairPlay-Schlüssel aus der Android-App-Laufzeitumgebung und stellt sie dem Download-Prozess zur Verfügung (agent.js:1-216)
Kernmodule im Detail
Modul 1: Konfigurationsverwaltung (main.go)
Verantwortung: Laden und Validieren der YAML-Konfiguration, Bereitstellen von Laufzeitparametern.
Eintrittspunkte:
loadConfig() error— Liestconfig.yamlund deserialisiert in globaleConfig-Variable (main.go:68-81)
Schlüsseldatenstrukturen:
go1// ConfigSet enthält alle Konfigurationsparameter 2type ConfigSet struct { 3 MediaUserToken string 4 AuthorizationToken string 5 Storefront string 6 LrcType string // "lyrics" oder "syllable-lyrics" 7 EmbedLrc bool 8 CoverSize string // z.B. "5000x5000" 9 AlacSaveFolder string 10 MaxMemoryLimit int // MB 11 // ... weitere Felder 12}
Fehlerbehandlung:
- Datei nicht gefunden: Rückgabe von
os.ReadFile-Fehler - YAML-Parse-Fehler: Rückgabe von
yaml.Unmarshal-Fehler - Storefront-Validierung: Standardwert "us" bei ungültiger Länge (main.go:77-79)
Modul 2: URL-Validierung (main.go)
Verantwortung: Extrahieren von Storefront und ID aus Apple Music URLs.
Eintrittspunkte:
checkUrl(url string) (string, string)— Für Alben-URLs (main.go:109-118)checkUrlMv(url string) (string, string)— Für Musikvideo-URLs (main.go:119-128)
Regex-Pattern:
go1// Album-Pattern 2^(?:https:\/\/(?:beta\.music|music|classical\.music)\.apple\.com\/(\w{2})(?:\/album|\/album\/.+))\/(?:id)?(\d[^\D]+)(?:$|\?) 3 4// MV-Pattern 5^(?:https:\/\/(?:beta\.music|music)\.apple\.com\/(\w{2})(?:\/music-video|\/music-video\/.+))\/(?:id)?(\d[^\D]+)(?:$|\?)
Rückgabewerte: (storefront, id) oder ("", "") bei ungültiger URL.
Modul 3: Download-Engine (utils/runv2/runv2.go)
Verantwortung: Streaming-Download, M3U8-Parsing, On-the-fly Entschlüsselung.
Eintrittspunkte:
Run(adamId string, playlistUrl string, outfile string, Config structs.ConfigSet) error(utils/runv2/runv2.go:47-84)
Schlüsseldatenstrukturen:
go1type TimedResponseBody struct { 2 body io.Reader 3 timer *time.Timer 4 timeout time.Duration 5 threshold int 6}
Kritische Aufrufkette:
- HTTP-Request für M3U8-Playlist (utils/runv2/runv2.go:55-64)
- Parsing der Media-Segmente (utils/runv2/runv2.go:67-77)
- Download und Entschlüsselung via
downloadAndDecryptFile(utils/runv2/runv2.go:169-207)
Speichermanagement-Strategie:
go1MaxMemorySize := int64(Config.MaxMemoryLimit * 1024 * 1024) 2if totalLen <= MaxMemorySize { 3 outBuf = bufio.NewWriter(&buffer) // In-Memory 4} else { 5 ofh, _ := os.Create(outfile) // Datei-basiert 6 outBuf = bufio.NewWriter(ofh) 7}
Die Entscheidung basiert auf konfigurierbarem max-memory-limit (Standard: 256 MB) und der Gesamtdateigröße (utils/runv2/runv2.go:173-184).
Modul 4: DRM-Entschlüsselung (agent.js)
Verantwortung: Extraktion von FairPlay-Entschlüsselungsschlüsseln aus der Android-App.
Technische Basis: Frida-Instrumentierung der nativen Bibliothek libandroidappmusic.so.
Schlüsselfunktionen:
getPersistentKey— Ruft den persistenten Schlüssel vom Server ab (agent.js:40-41)decryptContext— Erstellt den Entschlüsselungskontext (agent.js:43-44)decryptSample— Entschlüsselt einzelne Audio-Samples (agent.js:46-47)
FairPlay-Zertifikat: Das Zertifikat ist fest im Agent kodiert und wird für die Schlüsselanforderung verwendet (agent.js:3).
Download- und Entschlüsselungsprozess
Der Kernprozess kombiniert Streaming-Download mit paralleler Entschlüsselung, um Speichereffizienz zu gewährleisten. Die folgende Sequenzdiagramm zeigt den detaillierten Ablauf:
正在加载图表渲染器...
Prozess-Erklärung:
- Konfigurationsladung: Die
loadConfig()-Funktion liestconfig.yamlund validiert kritische Parameter wie Storefront (main.go:68-81) - M3U8-Verarbeitung: Die M3U8-Playlist wird geparst, um Segment-URIs und Byte-Ranges zu extrahieren. Nicht-Byte-Range-Playlists werden explizit abgelehnt (utils/runv2/runv2.go:75-77)
- Schlüsselextraktion: Der Frida-Agent kommuniziert mit
libandroidappmusic.so, um FairPlay-Schlüssel zur Laufzeit zu extrahieren (agent.js:51-79) - Streaming-Entschlüsselung: Jedes Segment wird einzeln heruntergeladen und entschlüsselt, wobei die Entscheidung über In-Memory- oder Datei-Pufferung dynamisch getroffen wird (utils/runv2/runv2.go:169-207)
Adaptive Speicherverwaltung
Die TimedResponseBody-Struktur implementiert einen Timeout-Mechanismus für langsame Downloads:
go1func (b *TimedResponseBody) Read(p []byte) (int, error) { 2 n, err := b.body.Read(p) 3 if n >= b.threshold { 4 b.timer.Reset(b.timeout) // Reset bei Fortschritt 5 } 6 return n, err 7}
Dies verhindert Hängbleiben bei Netzwerkproblemen und ermöglicht zuverlässige Timeout-Behandlung (utils/runv2/runv2.go:34-44).
Konfiguration und Anpassbarkeit
Die config.yaml-Datei bietet umfangreiche Konfigurationsmöglichkeiten für Download-Verhalten, Formate und Metadaten:
Kernkonfigurationsbereiche
| Bereich | Parameter | Beschreibung |
|---|---|---|
| Authentifizierung | media-user-token, authorization-token | Zugriff auf geschützte Inhalte |
| Audioformate | alac-max, atmos-max, aac-type | Qualitätsstufen und Codec-Auswahl |
| Speicherpfade | alac-save-folder, atmos-save-folder, aac-save-folder, mv-save-folder | Zielverzeichnisse pro Format |
| Metadaten | embed-lrc, embed-cover, cover-size, cover-format | Tags und Cover-Einbettung |
| Konvertierung | convert-after-download, convert-format, ffmpeg-path | Post-Processing mit FFmpeg |
| Netzwerk | decrypt-m3u8-port, get-m3u8-port, get-m3u8-from-device | Ports und Geräte-Kommunikation |
Formatierungs-Templates
Die Konfiguration unterstützt Template-Platzhalter für Ordner- und Dateinamen:
yaml1album-folder-format: "{AlbumName}" 2song-file-format: "{SongNumer}. {SongName}" 3artist-folder-format: "{UrlArtistName}"
Verfügbare Platzhalter umfassen: {AlbumId}, {AlbumName}, {ArtistName}, {ReleaseDate}, {ReleaseYear}, {UPC}, {Copyright}, {Quality}, {Codec}, {Tag}, {RecordLabel} (config.yaml:28-38).
FFmpeg-Integration
Die optionale Konvertierungsfunktion unterstützt mehrere Zielformate:
yaml1convert-after-download: false 2convert-format: "flac" # flac | mp3 | opus | wav | copy 3convert-keep-original: false 4convert-with-metadata: true
Warnmechanismen verhindern qualitätsmindernde Konvertierungen (z.B. Lossy-to-Lossless) (config.yaml:54-66).
Deployment und Betriebsumgebung
Docker-Containerisierung
Das Projekt bietet einen Multi-Stage Docker-Build für isolierte Deployment-Umgebungen:
dockerfile1# Stage 1: Build 2FROM golang:1.25.5-alpine AS builder 3WORKDIR /app 4RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ 5 go build -o /bin/apple-music-dl main.go 6 7# Stage 2: Runtime 8FROM gpac/ubuntu 9RUN apt-get install -y ffmpeg 10COPY /bin/apple-music-dl /usr/local/bin/
Die Laufzeitumgebung basiert auf gpac/ubuntu, das MP4Box vorinstalliert enthält, und fügt FFmpeg für Konvertierungen hinzu (Dockerfile:1-22).
Voraussetzungen
| Komponente | Zweck | Installationshinweis |
|---|---|---|
| MP4Box | MP4-Container-Manipulation | Muss in PATH verfügbar sein |
| mp4decrypt | MV-Entschlüsselung | Von Bento4-Projekt |
| FFmpeg | Konvertierung, animierte Artworks | Optional für Post-Processing |
| Frida | DRM-Agent-Injection | Erfordert gerootetes Android-Gerät |
Speicherstruktur im Container
Die Docker-Konfiguration erstellt separate Verzeichnisse für jedes Audioformat:
yaml1alac-save-folder: "/downloads/ALAC" 2atmos-save-folder: "/downloads/Atmos" 3aac-save-folder: "/downloads/AAC"
Dies ermöglicht saubere Trennung und einfaches Volume-Mapping für persistente Speicherung (Dockerfile:19-21).
Quantifizierte Projektkennzahlen
| Metrik | Wert | Quelle |
|---|---|---|
| Unterstützte Audioformate | 6 (ALAC, EC3, AAC, AAC-LC, AAC-Binaural, AAC-Downmix) | README.md:18-24 |
| Konfigurationsparameter | 50+ | config.yaml:1-66 |
| Go-Abhängigkeiten | 12 direkte, 23 indirekte | go.mod:1-45 |
| Unterstützte Plattformen | 2 (Android x86_64, ARM64) | agent.js, agent-arm64.js |
| Lyrics-Formate | 2 (LRC, TTML) | config.yaml:4-5 |
| Cover-Formate | 3 (JPG, PNG, Original) | config.yaml:13 |
| Maximale Cover-Auflösung | 5000x5000 Pixel | config.yaml:12 |
| Standard-Speicherlimit | 256 MB | config.yaml:18 |
Bericht-Lesereihenfolge
Die folgende Grafik zeigt die empfohlene Reihenfolge für die technische Dokumentation:
正在加载图表渲染器...
Empfohlene Lesereihenfolge:
- Projektüberblick (aktuelle Seite) — Architektur, Module, Technologie-Stack
- Konfiguration — Detaillierte Parameter-Erklärung und Template-Syntax
- Download-Engine — Implementierungsdetails von
runv2.gound M3U8-Verarbeitung - DRM-Entschlüsselung — Frida-Agent-Interna und FairPlay-Mechanismen
- Deployment — Docker-Konfiguration und Produktions-Setup
