Skip to content
RicherTunesPublic

About

High-performance Lidarr plugin for TIDAL — Hi-Res & lossless indexing and downloads, built on the RicherTunes Lidarr.Plugin.Common framework.

Topics

Resources

Security policy

Stars

5 stars

Watchers

0 watching

Forks

Latest commit

 

History

838 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tidalarr

Tidalarr is a Lidarr plugin that indexes and downloads lossless and hi-res audio from the Tidal streaming service. It ships as a single merged DLL (Lidarr.Plugin.Tidalarr.dll) targeting net8.0.

Who is this for? Lidarr users with a Tidal HiFi or HiFi Plus subscription who want automatic, high-quality audio imports. The plugin handles search, download, format conversion, metadata, and lyrics — all from within the Lidarr UI.

Key features

  • Search & index — Tidal albums and tracks appear as Lidarr search results via the indexer. Queries are sanitized by Common's SearchQuerySanitizer (special-character folding + combined → artist-only → album-only fallback tiers) and run through Common's SearchPlanExecutor (stop-after-first-tier-with-results) via the TidalSearchPlan request generator.
  • Chunked DASH downloads — Tidal's streaming manifest is parsed into chunks, downloaded in parallel, and assembled into M4A or FLAC.
  • Quality tiers — Low (AAC 96 kbps), High (AAC 320 kbps), Lossless (FLAC 16-bit/44.1 kHz), and Hi-Res (FLAC up to 24-bit/192 kHz).
  • FLAC extraction — optionally extracts FLAC from M4A containers (ExtractFlac, on by default).
  • Synced lyrics — best-effort .lrc fetch via LRCLIB (SaveSyncedLyrics / UseLRCLIB).
  • ISRC tag writing — writes ISRC tags on downloaded tracks to anchor Lidarr import matching when Tidal returns them.
  • Favorites import list — mirror your Tidal library (favorite albums and/or artists) into Lidarr as an import list. Reuses the indexer's OAuth session, so no separate login.
  • OAuth 2.0 + PKCE — secure, token-based authentication; no stored passwords.

Built on Lidarr.Plugin.Common

Tidalarr builds on the shared Lidarr.Plugin.Common library (vendored at ext/Lidarr.Plugin.Common). Foundation topics — architecture, extension points, shared helpers, and submodule versioning — are documented in Common's wiki, not duplicated here:

Common wiki page Why follow it
Home Overview of the shared library and the five-plugin ecosystem
Architecture Overview Base classes, DI container, and the plugin lifecycle that Tidalarr inherits
SDK and Extension Points How to extend BaseStreamingIndexer, BaseStreamingDownloadClient, and other service interfaces
Shared Helpers Catalog Ready-made utilities (caching, auth gates, health probes, lyrics enrichment) that Tidalarr consumes
Versioning and Submodule Pinning How ext-common-sha.txt and the gitlink stay in sync (re-pin manually; no scheduled auto-bump)

Ecosystem contract:

  • Common is vendored at ext/Lidarr.Plugin.Common; the exact pin is tracked by ext-common-sha.txt and must be committed with the submodule gitlink.
  • Gitea is the primary CI surface (.gitea/workflows/ci.yml): CI / secret-scan runs Gitleaks with checksum verification, CI / lint runs Common's shared plugin lint runner, and CI / verify runs scripts/verify-local.ps1, which delegates to ext/Lidarr.Plugin.Common/scripts/local-ci.ps1. The repo also carries .github/workflows/ci.yml as a guarded GitHub mirror; Gitea remains authoritative for merges.
  • Tidal album search uses Common's SearchQuerySanitizer and SearchPlanExecutor through the thin TidalSearchPlan / TidalAlbumSearch seam.

Installation

Prerequisites

  • Lidarr v3.1.2.4913 or higher on the plugins/nightly branch (.NET 8 image, e.g. pr-plugins-3.1.2.4913). The declared minimum is checked against the package's compiled host references.
  • A Tidal subscription (HiFi or HiFi Plus for lossless/hi-res quality).

Install via the Lidarr UI

  1. Settings → Plugins → paste https://github.com/RicherTunes/Tidalarr → Install → restart Lidarr.
  2. Add Tidalarr under Settings → Indexers and Settings → Download Clients.
  3. Complete the Tidal OAuth 2.0 PKCE sign-in from the plugin settings.

To build from source, see the Getting Started section below.

Configuration

Settings are available in the Lidarr UI under the plugin's Settings panel. Advanced items are hidden by default — click Show Advanced to reveal them.

Indexer settings

Setting Default Range Description
Config Path auto — Directory for Tidal OAuth tokens. Defaults to /config/Tidalarr (Docker) or ~/.config/Tidalarr (Linux).
OAuth Redirect URL — — Paste the redirect URL from your browser after OAuth sign-in. Overwrite if stale.
Market (adv) US US UK DE FR CA AU JP Tidal API market code.
Early Release Limit (adv) 14 0–365 days Skip pre-release downloads beyond this many days before release. 0 = include all.
Enable Cache (adv) on — Cache search results to reduce API calls.
Cache Duration (adv) 15 min 0–1440 min Cached search result lifetime.

OAuth Authorization URL is a read-only convenience field derived from Config Path — use it to copy the auth link without digging through logs.

Download client settings

Setting Default Range Description
Config Path auto — Must match the indexer's Config Path to reuse the same OAuth tokens.
Download Path — — Destination folder for downloaded albums.
Preferred Quality Lossless Low / High / Lossless / HiRes Audio quality tier. Falls back to the highest your subscription allows; HiFi Plus required for Lossless+.
Extract FLAC (adv) on — Extract FLAC from M4A containers.
Chunk Delay (adv) 0 ms 0–60 000 ms Delay between chunk requests. Increase if rate-limited.
Max Concurrent Track Downloads (adv) 2 1–3 Parallel tracks per album.
Max Concurrent Chunk Downloads (adv) 2 1–8 Parallel chunk requests per track. Effective parallelism is capped so that tracks × chunks ≤ 6. Disabled when Chunk Delay > 0.
Save Synced Lyrics (adv) on — Save .lrc lyrics alongside downloaded tracks.
Use LRCLIB (adv) off — Fall back to lrclib.net for lyrics when Tidal has none. Sends artist/track/album names.

Import list settings (Tidalarr Favorites)

Add under Settings → Import Lists → Add → Tidalarr Favorites to mirror your Tidal favorites into Lidarr. Authentication is shared with the indexer — authenticate the Tidalarr indexer first, then this import list reuses the same session (no separate login).

Setting Default Range Description
Config Path auto — Directory holding the Tidal OAuth tokens. Point it at the same directory the indexer uses.
Favorites To Import Albums and artists Albums and artists / Albums only / Artists only Which slice of your Tidal library to mirror. Favorite albums become artist + album entries; favorite artists become artist entries.
Market (adv) US 2-letter ISO 3166-1 code Tidal API market code.

Lidarr resolves import-list entries by name (then MusicBrainz); Tidal favorites are matched by artist/album name rather than a Tidal catalog id.

Terminal release suppression

Some tracks are permanently unavailable on Tidal (rights removed / catalog delisting) even though they still appear on an album's tracklist. No quality tier of such an album can ever complete, and Lidarr's blocklist does not fire for this failure mode — so without intervention the same album would be re-grabbed on every scheduled search, forever.

Tidalarr suppresses these automatically:

  • When an album download fails because at least one track is permanently unavailable (an HTTP 404 from Tidal's playback-info endpoint — the only signal classified as permanent), the album is recorded in a bounded, disk-persisted suppression store with a 30-day TTL.
  • Suppressed albums are withheld from automatic/RSS search results, which stops the re-grab loop.
  • An interactive (user-initiated) search still offers suppressed albums, so you can recover an album immediately if it becomes available again — no need to wait out the TTL.
  • Transient failures (auth, region/tier restrictions, rate limits, server errors, network) are never suppressed — classification deliberately errs on the transient side so a recoverable album is never hidden.

Getting Started

# Clone with submodules
git clone --recursive https://github.com/RicherTunes/Tidalarr.git

# Restore and build
dotnet restore Tidalarr.sln
dotnet build Tidalarr.sln

# Run tests
pwsh scripts/test.ps1

Host vs. Core

  • Core plugin (src/Tidalarr): hostless runtime used by CLI and tests; no NzbDrone/Lidarr references. Ships in the plugin zip.
  • Host bridge (src/Tidalarr.HostBridge): host-only wrappers with NzbDrone annotations and pretty enum labels; translates host UI models to core settings via IHostSettingsMapper. Not shipped in the plugin zip.
  • See docs/hostbridge-integration.md for wiring details.
  • Framework rationale: docs/TFM_RATIONALE.md.

CLI tool

TidalCLI/ provides manual verification helpers and named-argument commands:

dotnet run --project TidalCLI -- search "Miles Davis Kind of Blue"
dotnet run --project TidalCLI -- download-album AlbumId=<id> OutputDir=<dir> Quality=HiRes

Project structure

src/Tidalarr/
├── Application/        # Application-level services
├── Core/               # Constants, exceptions, DTOs
├── Diagnostics/        # Diagnostic helpers
├── Domain/             # API clients, streaming, manifest parsing
├── Infrastructure/     # Caching, resilience, storage
├── Integration/        # Lidarr integration (indexer, download client, DI module)
└── Properties/         # Assembly metadata

Documentation

Wiki

Page Description
Home Plugin overview, navigation, and performance tuning
Authentication OAuth 2.0 + PKCE sign-in (UI & CLI), token refresh, region/market
Quality & Formats Quality tiers, chunked DASH/BTS assembly, FLAC extraction, ISRC tags, lyrics
Troubleshooting Typed errors mapped to cause + fix

Local docs

Document Description
CHANGELOG.md Release history (Keep a Changelog format)
CLAUDE.md Full development guide for contributors and automation
docs/hostbridge-integration.md Host bridge wiring guide
docs/TFM_RATIONALE.md Why the core plugin and CLI target net8.0
docs/packaging-closure.md Plugin packaging validation
docs/ci-gates-verification.md CI gate details
docs/SETTINGS-MIGRATION.md Settings migration notes
docs/operations/deployment-smoke-test.md Deployment and smoke-test playbook
docs/operations/multi-plugin-alignment.md Multi-plugin coexistence checklist
AGENTS.md Repository guidelines for coding, testing, and reviews

For the full docs index, see docs/README.md.

Disclaimer

Tidalarr is an independent, open-source project by RicherTunes for educational and research purposes — to study plugin architecture, streaming protocols, and the Lidarr ecosystem.

  • Not affiliated with, authorized, or endorsed by TIDAL. "TIDAL" and related marks are trademarks of their respective owners; used here descriptively only.
  • Intended for personal use with your own valid TIDAL subscription. You are solely responsible for complying with TIDAL's Terms of Service and all applicable laws.
  • Provided "as is", without warranty of any kind (see LICENSE). Report security issues via SECURITY.md.

Support

Open a GitHub issue with detailed logs and reproduction steps.

About

High-performance Lidarr plugin for TIDAL — Hi-Res & lossless indexing and downloads, built on the RicherTunes Lidarr.Plugin.Common framework.

Topics

Resources

Security policy

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages