A free, open-source bridge between Lidarr and YouTube that fills the gaps in your self-hosted music library. Powered by yt-dlp, MusicBrainz, iTunes, and AcoustID, it searches YouTube for your missing albums, scores the best audio match, downloads it at up to 320 kbps, writes complete ID3 metadata with embedded artwork, and triggers a Lidarr import β all from a clean web UI that runs on any Docker host (NAS, Synology, Unraid, Raspberry Pi, VPS).
Quick Start Β· Features Β· How It Works Β· Configuration Β· Screenshots Β· FAQ
- π Smart YouTube matching β searches up to 15 candidates per track and scores them by title similarity, duration window, official-channel boost, and forbidden-word filtering (remix, live, cover, karaokeβ¦)
- π― AcoustID fingerprinting β optional chromaprint verification rejects mismatched audio before import
- π·οΈ Full metadata tagging β MP3 / M4A / Opus with MusicBrainz IDs, iTunes 3000Γ3000 cover art, year, track numbers, and optional XML sidecars for Lidarr re-import
- π¦ Native Lidarr integration β copies tagged files into your Lidarr library path and triggers
RefreshArtist; background paginated sync ofwanted/missingfor instant UI - π Lidarr download client β optionally registers in Lidarr as a Newznab indexer + SABnzbd download client, so Lidarr searches, grabs and imports automatically (see Use as a Lidarr download client)
- β‘ Parallel downloads β configurable concurrent tracks (1β5) with mid-download skip, per-track progress, speed, and ETA
- π« Banned URLs & candidate retries β per-track YouTube blacklist; tries up to 15 candidates before giving up
- π₯ Manual YouTube URL & playlist import β paste any YouTube or YouTube Music URL (single track or full playlist) with album-art preview
- π΅ Audio streaming preview β listen to candidates and playlist items in the browser before queuing
- β±οΈ Built-in scheduler β auto-discover and auto-download new missing albums at a configurable interval with per-run album limits
- π Telegram & Discord notifications β per-channel filters for success, partial success, errors, and manual events
- π οΈ yt-dlp tuning UI β cookies file, player client, retries, sleep intervals, IPv4 force, one-click yt-dlp upgrade, loudness normalization, and automatic PO tokens via a bundled bgutil provider sidecar (fixes "Sign in to confirm you're not a bot")
- π Stats dashboard & logs β success rate, average match score, total downloaded size, per-album logs with retry
- π Modern dark/light web UI β responsive design, drag-to-reorder queue, structured logs
- π³ Docker-first β single container, Compose-ready, works on NAS, home server, Unraid, Synology, or any VPS
- Sync β A background job paginates Lidarr's
/wanted/missingendpoint into a local SQLite cache so the dashboard loads instantly. - Search β For each track,
yt-dlpqueries YouTube and returns the top 15 candidates. - Score β Candidates are ranked by title similarity (50%), duration match (25%), official-channel bonus (15%), and view-count weight, with forbidden-word filtering.
- Verify β If AcoustID is enabled, the downloaded file is fingerprinted with
fpcalcand matched against the expected MusicBrainz recording ID before acceptance. - Tag β Mutagen writes ID3 tags (title, artist, album, track #, year, MusicBrainz IDs) and embeds an iTunes 3000Γ3000 cover.
- Import β Files are copied into your Lidarr music path, then a
RefreshArtistcommand is sent so Lidarr scans and picks up the new tracks.
Instead of pushing finished files into Lidarr, you can register this app inside Lidarr as a native download path. Lidarr then drives the whole flow β search, grab, monitor and import β exactly like it would with a real Usenet indexer + SABnzbd client.
It works by exposing two emulated protocols:
| Surface | Emulates | Endpoint |
|---|---|---|
| Indexer | Newznab | /api/newznab/api |
| Download client | SABnzbd | /api/sabnzbd |
When Lidarr searches for a wanted album, the indexer matches it against the locally-synced missing-albums cache and returns one "release" pointing back at this app. Lidarr grabs it and hands it to the SABnzbd client, which enqueues the album in the normal download engine, downloads from YouTube into the download folder, and reports completion so Lidarr imports the files itself.
- In this app β Settings β Lidarr Download Client, toggle Enable Download Client, click Generate to create an API key, set a Category (default
music), and Save. - In Lidarr β Settings β Indexers β β β Newznab (custom):
- URL:
http://<this-app-host>:<port>(e.g.http://192.168.1.x:5005) - API Path:
/api/newznab/api - API Key: the key generated above
- Test β Save.
- URL:
- In Lidarr β Settings β Download Clients β β β SABnzbd:
- Host / Port: this app's host and port
- URL Base:
/api/sabnzbd - API Key: the same key
- Category: the same category (
music) - Test β Save.
- In Lidarr β Settings β Media Management, enable Completed Download Handling so Lidarr imports finished downloads.
Note: In this mode the app leaves downloaded files in the download folder (under the category) for Lidarr to import β it does not copy to the Lidarr music path or send
RefreshArtistitself. Make sure the download folder is visible to Lidarr at the same path (or via a remote path mapping). Job state is kept in memory, so a restart mid-download will look "removed" to Lidarr, which will simply re-search.
Indexer feed & RSS: When Lidarr queries the indexer with no search terms (its connection Test and periodic RSS sync), the feed returns your currently-synced missing albums (newest first). This is what makes the indexer Test pass β so let the missing-albums sync finish first (the dashboard should list missing albums). With RSS sync enabled, Lidarr will then grab missing albums automatically; the feed shrinks as albums stop being missing. If you only want downloads on explicit/automatic search, disable Enable RSS on the indexer in Lidarr.
No retry loops: An album that was just attempted (and a download currently in progress) is held back from the indexer feed and from new grabs for a cooldown window β controlled by
scheduler_retry_after_hours(default 24h) β so a failing album is not re-grabbed and re-downloaded endlessly. After the cooldown it is offered again (with a fresh release id) so transient failures still get retried. Set the value to0only if you want no cooldown.
services:
lidarr-downloader:
image: angrido/lidarr-downloader:latest
container_name: lidarr-downloader
ports:
- "5005:5000"
volumes:
- ./config:/config
- /DATA/Downloads:/DATA/Downloads
- /DATA/Media/Music:/music
environment:
- LIDARR_URL=http://192.168.1.XXX:8686
- LIDARR_API_KEY=your_api_key_here
- DOWNLOAD_PATH=/DATA/Downloads
- LIDARR_PATH=/music
- PUID=1000
- PGID=1000
- UMASK=002
restart: unless-stoppedOpen the web UI at http://localhost:5005 and configure the rest from the Settings page.
| Variable | Example | Description |
|---|---|---|
LIDARR_URL |
http://192.168.1.10:8686 |
Lidarr base URL (use LAN IP) |
LIDARR_API_KEY |
abc123β¦ |
Lidarr β Settings β General |
DOWNLOAD_PATH |
/DATA/Downloads |
Where new tracks are saved |
LIDARR_PATH |
/music |
Final music library path |
Most other settings (audio format, concurrent tracks, match score threshold, forbidden words, scheduler, notifications, AcoustID, yt-dlp tuning) live in the Settings page of the web UI.
If YouTube returns "Sign in to confirm you're not a bot", supply a cookies file:
- Install the Get cookies.txt LOCALLY browser extension
- Open a private window and sign in to a throwaway Google account
- Export cookies in Netscape format as
cookies.txt - Mount it and set
YT_COOKIES_FILE:
volumes:
- ./cookies.txt:/cookies/cookies.txt
environment:
- YT_COOKIES_FILE=/cookies/cookies.txt
β οΈ Never use your main Google account β cookies expire and accounts can be flagged.
Enable in the Settings page and provide an AcoustID API key. The container already ships with fpcalc (chromaprint).
Is this a replacement for a real music indexer?
No β it's a fallback when albums are unavailable through standard Lidarr indexers. Audio quality is limited to YouTube's source.
Does it work with Plex, Jellyfin, or Navidrome?
Yes. Files are imported into Lidarr's library, which any music server can then index.
What audio formats are supported?
MP3 (default, up to 320 kbps), M4A, and Opus β selectable in Settings.
Will it download playlists or single YouTube videos?
Yes. The YouTube page accepts any YouTube or YouTube Music URL, including full playlists, with metadata preview before queuing.
Does it run on Synology / Unraid / Raspberry Pi?
Yes β any platform that runs Docker. The image is multi-arch.
Is yt-dlp kept up to date?
You can upgrade yt-dlp from the Settings page with a single click; the UI shows the installed and latest PyPI versions.
Versions before SQLite stored state in JSON files. Migrate with:
docker exec -it lidarr-downloader python3 tools/migrate_json_to_db.py --config-dir /configThe originals are renamed to *.json.migrated.
git clone https://github.com/Angrido/Lidarr-YouTube-Downloader.git
cd Lidarr-YouTube-Downloader
pip install -r requirements.txt
python app.py # http://localhost:5000
# Run tests:
source .venv/bin/activate && python -m pytest tests/ -vThis project is provided for personal, educational use to manage your own music library. Users are solely responsible for complying with copyright laws and YouTube's Terms of Service.
Made with β€οΈ for the self-hosted music community

