Preise

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-album Flag
  • 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

KomponenteTechnologieVersionZweck
KernspracheGo1.23.1Hauptimplementierung
MP4-Manipulationmp4ff0.50.0ISO-BMFF/MP4-Verarbeitung
HTTP-Clientgo-resty2.16.5API-Kommunikation
M3U8-Parsergrafov/m3u80.11.1HLS-Playlist-Verarbeitung
DRM-EntschlüsselungFrida Agent-FairPlay Key Extraction
ContainerisierungDockerMulti-StageDeployment-Umgebung
Externe ToolsMP4Box, 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:

  1. CLI & Eingabe: main.go parst Kommandozeilenargumente und validiert Apple Music URLs mittels Regex-Patterns für Alben (checkUrl) und Musikvideos (checkUrlMv) (main.go:109-128)
  2. Konfiguration: Die YAML-Konfiguration wird in eine ConfigSet-Struktur geladen, die alle Laufzeitparameter wie Token, Pfade und Formate enthält (main.go:67-81)
  3. Download-Engine: runv2.go implementiert den Streaming-Download mit adaptivem Speichermanagement, das zwischen In-Memory- und Datei-basierter Pufferung wählt (utils/runv2/runv2.go:169-184)
  4. 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 — Liest config.yaml und deserialisiert in globale Config-Variable (main.go:68-81)

Schlüsseldatenstrukturen:

go
1// 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:

go
1// 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:

Schlüsseldatenstrukturen:

go
1type TimedResponseBody struct {
2    body      io.Reader
3    timer     *time.Timer
4    timeout   time.Duration
5    threshold int
6}

Kritische Aufrufkette:

  1. HTTP-Request für M3U8-Playlist (utils/runv2/runv2.go:55-64)
  2. Parsing der Media-Segmente (utils/runv2/runv2.go:67-77)
  3. Download und Entschlüsselung via downloadAndDecryptFile (utils/runv2/runv2.go:169-207)

Speichermanagement-Strategie:

go
1MaxMemorySize := 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:

  1. Konfigurationsladung: Die loadConfig()-Funktion liest config.yaml und validiert kritische Parameter wie Storefront (main.go:68-81)
  2. 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)
  3. Schlüsselextraktion: Der Frida-Agent kommuniziert mit libandroidappmusic.so, um FairPlay-Schlüssel zur Laufzeit zu extrahieren (agent.js:51-79)
  4. 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:

go
1func (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

BereichParameterBeschreibung
Authentifizierungmedia-user-token, authorization-tokenZugriff auf geschützte Inhalte
Audioformatealac-max, atmos-max, aac-typeQualitätsstufen und Codec-Auswahl
Speicherpfadealac-save-folder, atmos-save-folder, aac-save-folder, mv-save-folderZielverzeichnisse pro Format
Metadatenembed-lrc, embed-cover, cover-size, cover-formatTags und Cover-Einbettung
Konvertierungconvert-after-download, convert-format, ffmpeg-pathPost-Processing mit FFmpeg
Netzwerkdecrypt-m3u8-port, get-m3u8-port, get-m3u8-from-devicePorts und Geräte-Kommunikation

Formatierungs-Templates

Die Konfiguration unterstützt Template-Platzhalter für Ordner- und Dateinamen:

yaml
1album-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:

yaml
1convert-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:

dockerfile
1# 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 --from=builder /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

KomponenteZweckInstallationshinweis
MP4BoxMP4-Container-ManipulationMuss in PATH verfügbar sein
mp4decryptMV-EntschlüsselungVon Bento4-Projekt
FFmpegKonvertierung, animierte ArtworksOptional für Post-Processing
FridaDRM-Agent-InjectionErfordert gerootetes Android-Gerät

Speicherstruktur im Container

Die Docker-Konfiguration erstellt separate Verzeichnisse für jedes Audioformat:

yaml
1alac-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

MetrikWertQuelle
Unterstützte Audioformate6 (ALAC, EC3, AAC, AAC-LC, AAC-Binaural, AAC-Downmix)README.md:18-24
Konfigurationsparameter50+config.yaml:1-66
Go-Abhängigkeiten12 direkte, 23 indirektego.mod:1-45
Unterstützte Plattformen2 (Android x86_64, ARM64)agent.js, agent-arm64.js
Lyrics-Formate2 (LRC, TTML)config.yaml:4-5
Cover-Formate3 (JPG, PNG, Original)config.yaml:13
Maximale Cover-Auflösung5000x5000 Pixelconfig.yaml:12
Standard-Speicherlimit256 MBconfig.yaml:18

Bericht-Lesereihenfolge

Die folgende Grafik zeigt die empfohlene Reihenfolge für die technische Dokumentation:

正在加载图表渲染器...

Empfohlene Lesereihenfolge:

  1. Projektüberblick (aktuelle Seite) — Architektur, Module, Technologie-Stack
  2. Konfiguration — Detaillierte Parameter-Erklärung und Template-Syntax
  3. Download-Engine — Implementierungsdetails von runv2.go und M3U8-Verarbeitung
  4. DRM-Entschlüsselung — Frida-Agent-Interna und FairPlay-Mechanismen
  5. Deployment — Docker-Konfiguration und Produktions-Setup