A full-stack web application for downloading high-quality music from Tidal with intelligent playlist generation via ListenBrainz/Troi integration. Features automatic metadata tagging, lyrics fetching, and organized file management.
- Tidal Music Downloads: Download tracks in FLAC (lossless/hi-res) or AAC (320kbps/96kbps) formats
- Smart Playlist Generation: Generate personalized playlists using ListenBrainz listening history via Troi
- Automatic Organization: Files organized by Artist/Album with proper track numbering
- Rich Metadata: Automatic ID3 tags, album artwork, and MusicBrainz IDs
- Lyrics Integration: Synced (.lrc) and plain text (.txt) lyrics via LrcLib API
- Download Queue Management: Concurrent downloads with progress tracking
- Endpoint Failover: Automatic rotation across multiple Tidal API endpoints
- Modern Web UI: Clean, responsive Preact-based interface
- Real-time Progress: Live download progress with percentage indicators
- Search Capabilities: Search tracks, albums, and artists
- Batch Operations: Download entire albums or artist discographies
- Quality Selection: Choose audio quality per download
- Authentication: Secure login with credential management
tidaloader/
├── backend/
│ ├── api/
│ │ ├── __init__.py
│ │ ├── auth.py # Authentication middleware
│ │ └── main.py # FastAPI application
│ ├── downloads/ # Downloaded music files
│ ├── .env # Environment configuration
│ ├── .env.example # Example configuration
│ ├── config.py # Configuration loader
│ ├── lyrics_client.py # LrcLib API client
│ ├── requirements.txt # Python dependencies
│ ├── tidal_client.py # Tidal API client
│ └── troi_integration.py # Troi playlist generator
├── frontend/
│ ├── public/
│ ├── src/
│ │ ├── api/ # API client
│ │ ├── components/ # UI components
│ │ ├── stores/ # State management (Zustand)
│ │ ├── utils/ # Utilities
│ │ ├── app.jsx # Main app component
│ │ ├── main.jsx # Entry point
│ │ └── style.css # Tailwind styles
│ ├── index.html
│ ├── package.json
│ ├── tailwind.config.js
│ └── vite.config.js
├── automate-troi-download.py # Standalone CLI tool
└── api_endpoints.json # Tidal API endpoint list
- Python 3.8+
- Node.js 16+ and npm
- Git
- PowerShell or Command Prompt
- Windows 10/11
- Bash shell
- systemd (optional, for service management)
- Termux app from F-Droid
- Termux:Boot (optional, for auto-start)
The easiest way to run Tidaloader is using Docker. This works on Windows, macOS, and Linux.
- Docker Desktop (Windows/Mac) or Docker Engine (Linux)
- Docker Compose (included with Docker Desktop)
-
Clone the repository
git clone https://github.com/RayZ3R0/tidaloader.git cd tidaloader -
Create environment file
cp .env.example .env
Edit
.envand set your credentials and music directory:Windows:
AUTH_USERNAME=admin AUTH_PASSWORD=your-secure-password MUSIC_DIR=/music MUSIC_DIR_HOST=C:/Users/YourName/Music
Linux/Mac:
AUTH_USERNAME=admin AUTH_PASSWORD=your-secure-password MUSIC_DIR=/music MUSIC_DIR_HOST=/home/yourname/Music
Default (uses project folder):
AUTH_USERNAME=admin AUTH_PASSWORD=your-secure-password MUSIC_DIR=/music MUSIC_DIR_HOST=./music
-
Start the application
docker-compose up -d
First run will take a few minutes to build the image.
-
Access the application
Open your browser to
http://localhost:8001
View logs:
docker-compose logs -fStop the application:
docker-compose downRestart the application:
docker-compose restartRebuild after code changes:
docker-compose up -d --buildUpdate to latest version:
git pull
docker-compose up -d --buildBy default, music is downloaded to ./music in your project folder. To use a custom location:
-
Edit
.env:MUSIC_DIR_HOST=/your/custom/path
-
Restart the container:
docker-compose up -d
The music directory is automatically created if it doesn't exist.
Change port:
Edit docker-compose.yml:
ports:
- "8080:8001" # Access on port 8080 insteadEnvironment variables:
All configuration is done via .env file in the project root:
AUTH_USERNAME=myusername
AUTH_PASSWORD=mypassword
MUSIC_DIR=/music
MUSIC_DIR_HOST=./musicContainer won't start:
docker-compose logsPermission issues with music directory (Linux/Mac):
sudo chown -R $(id -u):$(id -g) ./music
# or
chmod -R 777 ./musicPermission issues (Windows):
# Run in PowerShell as Administrator
icacls .\music /grant Everyone:F /TMusic directory not found:
The container automatically creates /music inside. Make sure MUSIC_DIR_HOST in .env points to a valid location on your host machine.
Reset everything:
docker-compose down -v
docker-compose up -d --buildIf you want to customize Tidal API endpoints, create api_endpoints.json in the project root:
{
"endpoints": [
{
"name": "custom-endpoint",
"url": "https://your-endpoint.example.com",
"priority": 1
}
]
}The application works fine without this file using built-in defaults.
-
Clone the repository
git clone https://github.com/RayZ3R0/tidaloader.git cd tidaloader
-
Backend setup
cd backend python -m venv venv .\venv\Scripts\Activate.ps1 pip install -r requirements.txt
-
Configure environment
cp .env.example .env
Edit .env and set your configuration:
MUSIC_DIR=C:\Users\YourName\Music AUTH_USERNAME=your_username AUTH_PASSWORD=your_secure_password
-
Frontend setup
cd ..\frontend npm install npm run build
-
Start the server
cd ..\backend .\start.ps1
-
Access the application
Open your browser to
http://localhost:8001
-
Clone the repository
git clone https://github.com/RayZ3R0/tidaloader.git cd tidaloader -
Backend setup
cd backend python3 -m venv venv source venv/bin/activate pip install -r requirements.txt
-
Configure environment
cp .env.example .env nano .env # or use your preferred editorEdit .env:
MUSIC_DIR=/home/yourname/Music AUTH_USERNAME=your_username AUTH_PASSWORD=your_secure_password
-
Frontend setup
cd ../frontend npm install npm run build -
Start the server
cd ../backend source venv/bin/activate python -m uvicorn api.main:app --host 0.0.0.0 --port 8001
-
Access the application
Open your browser to
http://localhost:8001
-
Install Termux
Download from F-Droid: https://f-droid.org/en/packages/com.termux/
-
Run setup script
curl -O https://raw.githubusercontent.com/RayZ3R0/tidaloader/main/backend/termux-setup.sh bash termux-setup.sh
-
Configure environment
cd ~/tidaloader/backend nano .env
The default configuration uses:
MUSIC_DIR=/data/data/com.termux/files/home/music/tidal-downloads
-
Start the service
cd ~/tidaloader ./start-service.sh
-
Optional: Auto-start on boot
./install-termux-service.sh
-
Access the application
On your device:
http://localhost:8001From network:
http://[device-ip]:8001
All configuration is done via .env:
# Music directory - where files will be downloaded
MUSIC_DIR=/path/to/music
# Authentication credentials
AUTH_USERNAME=admin
AUTH_PASSWORD=your-secure-password-hereFiles are automatically organized in the following structure:
MUSIC_DIR/
└── Artist Name/
└── Album Name/
├── 01 - Track Title.flac
├── 01 - Track Title.lrc (synced lyrics if available)
├── 02 - Track Title.flac
├── 02 - Track Title.txt (plain lyrics if available)
└── ...
Available quality options (configurable per download):
HI_RES_LOSSLESS: Up to 24-bit/192kHz FLACLOSSLESS: 16-bit/44.1kHz FLAC (default)HIGH: 320kbps AACLOW: 96kbps AAC
-
Login
Use the credentials you set in .env
-
Search for Music
- Switch to "Search" tab
- Search by track, album, or artist
- Select tracks to download
- Add to queue
-
Generate Troi Playlists
- Switch to "Troi Playlist" tab
- Enter your ListenBrainz username
- Choose "Daily Jams" or "Periodic Jams"
- Review generated tracks
- Download selected tracks
-
Manage Downloads
- View queue in the download popout (bottom-right)
- Start/pause downloads
- Monitor progress
- Review completed and failed downloads
The standalone CLI tool automate-troi-download.py can be used independently:
# Activate backend virtual environment
cd backend
source venv/bin/activate # Linux/Mac
# or
.\venv\Scripts\Activate.ps1 # Windows
# Run the tool
cd ..
python automate-troi-download.py your-listenbrainz-username
# Options
python automate-troi-download.py --helpOptions:
--download-dir PATH: Specify download directory (default: ./downloads)--no-debug: Disable debug output--no-test-mode: Download all tracks (default: first 5 only)
The backend provides a REST API documented at http://localhost:8001/docs (FastAPI Swagger UI).
GET /api: API statusGET /api/health: Health check
POST /api/troi/generate: Generate Troi playlistGET /api/search/tracks: Search tracksGET /api/search/albums: Search albumsGET /api/search/artists: Search artistsGET /api/album/{album_id}/tracks: Get album tracksGET /api/artist/{artist_id}: Get artist detailsPOST /api/download/track: Download a trackGET /api/download/progress/{track_id}: Stream download progress
Backend:
cd backend
source venv/bin/activate
python -m uvicorn api.main:app --reload --host 0.0.0.0 --port 8001Frontend:
cd frontend
npm run devThe frontend dev server runs on http://localhost:5173 and proxies API requests to the backend.
Backend (backend/requirements.txt):
- fastapi: Web framework
- uvicorn: ASGI server
- aiohttp: Async HTTP client
- mutagen: Audio metadata handling
- lrclibapi: Lyrics fetching
- python-jose: JWT authentication
- passlib: Password hashing
- pydantic: Data validation
Frontend (frontend/package.json):
- preact: Lightweight React alternative
- zustand: State management
- tailwindcss: Utility-first CSS
- vite: Build tool
- Ensure Python virtual environment is activated
- Check .env file exists and is properly configured
- Verify all dependencies are installed:
pip install -r requirements.txt
- Delete
node_modulesandpackage-lock.json - Run
npm installagain - Ensure Node.js version is 16+
- Check internet connection
- Verify Tidal API endpoints are accessible
- Review backend logs for specific errors
- Try different quality settings
- Verify
AUTH_USERNAMEandAUTH_PASSWORDin .env - Clear browser cache and cookies
- Check backend logs for authentication failures
- LrcLib API may not have lyrics for all tracks
- Some tracks may have incomplete Tidal metadata
- Album artwork requires internet access during download
Edit api_endpoints.json:
{
"endpoints": [
{
"name": "custom-endpoint",
"url": "https://your-endpoint.example.com",
"priority": 1
}
]
}Lower priority numbers are tried first.
Create systemd service at /etc/systemd/system/tidaloader.service:
[Unit]
Description=Tidaloader Tidal Downloader
After=network.target
[Service]
Type=simple
User=youruser
WorkingDirectory=/path/to/tidaloader/backend
Environment="PATH=/path/to/tidaloader/backend/venv/bin"
ExecStart=/path/to/tidaloader/backend/venv/bin/python -m uvicorn api.main:app --host 0.0.0.0 --port 8001
[Install]
WantedBy=multi-user.targetEnable and start:
sudo systemctl enable tidaloader
sudo systemctl start tidaloader- Tidal API endpoints via community projects
- Lyrics from LrcLib API
- Troi playlist generation via ListenBrainz
- MusicBrainz metadata integration
This project is for educational purposes only. Ensure you comply with Tidal's Terms of Service and respect copyright laws in your jurisdiction.
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
For issues, questions, or feature requests, please open an issue on GitHub.