meine
meine 🌒 - A CLI file manager and system utility built with Textual. It combines intuitive command parsing with rich t…
Self-hosted YouTube Music downloader. Tags, organizes, and keeps playlists in sync.
git clone https://github.com/guillevc/yubal.gitguillevc/yubalSelf-hosted YouTube Music downloader. Paste a link, get a tagged, organized library.
Scheduled sync. Smart deduplication. Media server ready. Browser extension included.
Downloading music is easy. Organizing it is the hard part.
yubal takes a YouTube Music URL and produces a clean, tagged music library:
data/
├── Pink Floyd/
│ └── 1973 - The Dark Side of the Moon/
│ ├── 01 - Speak to Me.opus
│ ├── 01 - Speak to Me.lrc
│ ├── 02 - Breathe.opus
│ ├── 02 - Breathe.lrc
│ └── cover.jpg
│
├── Radiohead/
│ └── 1997 - OK Computer/
│ ├── 01 - Airbag.opus
│ ├── 01 - Airbag.lrc
│ ├── 02 - Paranoid Android.opus
│ ├── 02 - Paranoid Android.lrc
│ └── cover.jpg
│
└── _Playlists/
├── My Favorites [n2g-XhDv].m3u
└── My Favorites [n2g-XhDv].jpg
When downloading a playlist, each track lives in its album folder; the M3U file references it:
#EXTM3U #EXTINF:239,Pink Floyd - Breathe ../Pink Floyd/1973 - The Dark Side of the Moon/02 - Breathe.opus #EXTINF:386,Radiohead - Paranoid Android ../Radiohead/1997 - OK Computer/02 - Paranoid Android.opus
.lrc files for karaoke-style playback in supported playersopus (best quality/size), mp3, or m4a — direct download when available, transcoded otherwiseDownload tracks and subscribe to playlists directly from YouTube and YouTube Music without leaving the page.
More info in the extension's README.md.
# compose.yaml
services:
yubal:
image: ghcr.io/guillevc/yubal:latest
container_name: yubal
ports:
- 8000:8000
environment:
PUID: 1000
PGID: 1000
YUBAL_SCHEDULER_CRON: "0 0 * * *"
YUBAL_DOWNLOAD_UGC: false
YUBAL_TZ: UTC
volumes:
- ./data:/app/data
- ./config:/app/config
restart: unless-stopped
Tip
Volume permissions: Set PUID/PGID to match your host user (run id to check). This also ensures compatibility with podman rootless. If /app/data is an NFS/Unraid mount that does not allow chown, make sure it is already writable by the configured PUID/PGID.
docker compose up -d # Open http://localhost:8000
Unraid? Use the community Docker template by @SerpentDrago (unraid forum thread).
| Variable | Description | Default (Docker) |
|---|---|---|
PUID |
User ID for file ownership | 1000 |
PGID |
Group ID for file ownership | 1000 |
YUBAL_AUDIO_FORMAT |
opus, mp3, or m4a |
opus |
YUBAL_AUDIO_QUALITY |
Transcode quality (0=best, 10=worst) | 0 |
YUBAL_SCHEDULER_ENABLED |
Enable automatic scheduled sync | true |
YUBAL_SCHEDULER_CRON |
Cron schedule for auto-sync | 0 0 * * * |
YUBAL_FETCH_LYRICS |
Fetch lyrics from lrclib.net | true |
YUBAL_YTMUSIC_LYRICS_FALLBACK |
Fall back to YouTube Music lyrics on lrclib miss | true |
YUBAL_DOWNLOAD_UGC |
Download user-generated content to _Unofficial/ |
false |
YUBAL_REPLAYGAIN |
Apply track gain; album gain for complete albums | true |
YUBAL_JOB_TIMEOUT_SECONDS |
Job execution timeout in seconds | 1800 |
YUBAL_BASE_PATH |
URL base path for reverse proxy subfolder | — |
YUBAL_TZ |
Timezone (IANA format) | UTC |
| Variable | Description | Default (Docker) |
|---|---|---|
YUBAL_HOST |
Server bind address | 127.0.0.1 |
YUBAL_PORT |
Server port | 8000 |
YUBAL_DATA |
Music library output | /app/data |
YUBAL_CONFIG |
Config directory | /app/config |
YUBAL_LOG_LEVEL |
DEBUG, INFO, WARNING, ERROR |
INFO |
YUBAL_ASCII_FILENAMES |
Transliterate unicode to ASCII | false |
YUBAL_CORS_ORIGINS |
Allowed CORS origins | ["*"] |
YUBAL_TEMP |
Temp directory | System temp |
Tested with Navidrome, Jellyfin, and Gonic. Artists link correctly, even on tracks with multiple artists.
| Server | Artist linking | Playlists |
|---|---|---|
| Navidrome | ✅ Works out of the box | ✅ |
| Jellyfin | ⚙️ Enable "Use non-standard artists tags" in library settings | ✅ |
| Gonic | ⚙️ Set GONIC_MULTI_VALUE_ARTIST=multi |
❌ |
✅ Supported · ⚙️ Requires configuration · ❌ Not supported
Tip
Recommended stack: yubal + Navidrome gives you a self-hosted music streaming setup. Add a client like Symfonium (Android), Amperfy or Arpeggi (iOS), or Supersonic (desktop) to listen anywhere.
No configuration required. Optionally, make imported playlists public:
ND_DEFAULTPLAYLISTPUBLICVISIBILITY=true
See Navidrome docs.
For multi-artist support:
For artist linking:
GONIC_MULTI_VALUE_ARTIST=multi GONIC_MULTI_VALUE_ALBUM_ARTIST=multi
M3U playlists are not supported (pending PR).
Need age-restricted content, private playlists, your Liked Music (list=LM), or Premium quality? Add your cookies:
https://www.youtube.com/ cookies with a browser extension (yt-dlp guide)config/ytdlp/cookies.txt or upload via the web UICaution
Cookie usage may trigger stricter rate limiting and could put your account at risk. See #3 and yt-dlp wiki.
yubal is free, open-source, and built by one person. If it saves you time, consider supporting development:
A ⭐ also helps others find the project!
Built with yt-dlp and ytmusicapi.
Thanks to everyone who's starred, shared, reported bugs, suggested features, or supported the project 💝
For personal archiving only. Comply with YouTube's Terms of Service and applicable copyright laws.
more like this
meine 🌒 - A CLI file manager and system utility built with Textual. It combines intuitive command parsing with rich t…
Create and add progress bars, Office365 Files and Dropbox Paper papers by labels and link them to your Todoist tasks.
search projects, people, and tags