4e6bef40e38500ebe4b6f180c9860f38c88a61db
The new library version uses models.JSONID (custom string type) for ID fields instead of plain string. Convert to string where IDs are passed to functions expecting string or compared with string values. Affected: client.go (GetTrackInfoWithPosition), downloader.go (track.ID usage), monitor.go (track.ID, album.ID usage), storage.go (album/track ID assignment).
ym-dl
Yandex Music downloader — Go service for monitoring and downloading tracks/albums from Yandex Music for configured artists.
Features
- Token-only authentication via Yandex Music OAuth token
- Artist monitoring — periodic check for new tracks and albums
- Track & album download with direct URL signing
- SQLite storage index with migration from legacy JSON index
- Rich ID3 tags — genre, comment, lyrics, publisher, ISRC, copyright, original year, encoded by
- High-resolution covers (1000×1000) embedded in MP3 tags and saved as
cover.jpg - Idempotent downloads — tracks are not re-downloaded
- Structured JSON logging for Docker environments
Project structure
ym-dl/
├── cmd/ym-dl/ # Main entry point
├── internal/
│ ├── config/ # Configuration loading (artist IDs, API credentials)
│ ├── downloader/ # Download orchestration
│ ├── monitor/ # Periodic check logic for new releases
│ ├── storage/ # SQLite storage for downloaded tracks/albums
│ └── yandex/ # Yandex Music API client wrapper
├── Dockerfile # Multi-stage build
├── docker-compose.yml # Service definition
├── config.yaml.example # Sample configuration
├── docs/yandex-music.yaml # Yandex Music OpenAPI spec
└── README.md
Configuration
Create config.yaml based on config.yaml.example:
yandex:
token: "oauth_token" # Yandex Music OAuth token (required)
artists:
- id: 12345 # Artist ID from Yandex Music
- id: 67890
storage:
path: "/data/music" # Local path for downloads
organize: true # Organize into Artist/Album/Track structure
monitor:
interval: "24h" # Check interval (duration string, e.g. "24h", "6h30m")
Authentication
Only OAuth token is supported. Obtain a token from Yandex OAuth and set it in yandex.token.
Build & Run
Locally
go build -o bin/ym-dl ./cmd/ym-dl
go run ./cmd/ym-dl --config config.yaml
Docker Compose
docker compose up --build
Mount your config at /config.yaml and storage at /data:
# docker-compose.yml override
volumes:
- ./config.yaml:/config.yaml
- ./data:/data
Development
# Run tests
go test ./...
# Run single test
go test -v -run TestName ./internal/...
# Lint
golangci-lint run
# Build
go build -o bin/ym-dl ./cmd/ym-dl
Storage
The download index is stored in SQLite (index.db inside the storage path). On first launch, an existing legacy .index.json is automatically migrated to SQLite and removed.
Albums are considered fully downloaded only when all expected tracks (per track_count from Yandex API) are present in the index. Compilation albums where the artist appears on only some tracks are downloaded completely.
ID3 Tags
MP3 files are tagged with:
| Frame | Field | Source |
|---|---|---|
| TIT2 | Title | track title |
| TPE1 | Artist | all track artists |
| TPE2 | Album Artist | album artist |
| TALB | Album | album title |
| TYER | Year | release year |
| TCON | Genre | track/album genre |
| TRCK | Track number | position in album |
| TPOS | Disc number | volume in album |
| TCOM | Composer | (reserved) |
| TPUB | Publisher | album label |
| TENC | Encoded by | "ym-dl" |
| TCOP | Copyright | album catalog number |
| TORY | Original year | release date year |
| TSRC | ISRC | (reserved) |
| COMM | Comment | album description |
| USLT | Lyrics | track lyrics |
| APIC | Cover art | 1000×1000 JPEG |
| TXXX | Yandex IDs | track/album/artist IDs |
License
Private project.
Languages
Go
98.8%
Dockerfile
1.2%