A beautiful terminal music visualizer with pixelated album art and synchronized lyrics
- 🎵 Universal Player Support - Works with YouTube, Spotify, Tidal, VLC, and any MPRIS2-compatible player
- 🎨 Pixelated Album Art - 30x30 pixel art rendered with ANSI escape sequences (including YouTube video thumbnails!)
- 🌈 Dynamic Color Theming - Extracts colors from album art for UI elements
- 📝 Synchronized Lyrics - Auto-scrolling lyrics with LRC format support
- 💾 Smart Caching - Caches processed images and lyrics for performance
- ⚡ Real-time Updates - Live progress tracking and metadata updates
- Rust 1.70+
playerctl
(for media player detection)- Terminal with 256 color support
- Tidal API credentials (optional, for enhanced metadata)
# Clone the repository
git clone https://github.com/estevaom/trackwatch
cd trackwatch
# Build and run
cargo build --release
./target/release/trackwatch
For richer album metadata and high-quality cover art, you can optionally configure Tidal API credentials:
-
Get Tidal API credentials from https://developer.tidal.com/dashboard/create
-
Set the credentials using one of these methods:
Option A: Environment Variables (Recommended for production)
export TIDAL_CLIENT_ID=your_client_id export TIDAL_CLIENT_SECRET=your_client_secret trackwatch
Or run directly:
TIDAL_CLIENT_ID=your_client_id TIDAL_CLIENT_SECRET=your_client_secret trackwatch
Option B: .env File (Convenient for development)
cp .env.example .env # Edit .env with your credentials
Note: Tidal integration is entirely optional. trackwatch works perfectly fine without it, using metadata and album art from your media player (playerctl).
q
orEsc
- Quit the application
- Player Detection: Uses
playerctl
to monitor any MPRIS2-compatible media player - Metadata Enrichment: Fetches additional data from Tidal API when configured (optional)
- Album Art Processing: Downloads and converts images to 30x30 pixelated format
- Color Extraction: Uses k-means clustering in LAB color space for palette generation
- Lyrics Fetching: Downloads from LRCLIB API with intelligent caching
- UI Rendering: Updates every 500ms with smooth animations and color transitions
- Two-thread model: Main thread for UI, background thread for data fetching
- Shared state: Thread-safe communication via
Arc<Mutex<App>>
- Hybrid async/sync: Synchronous playerctl polling with async API calls
- Graceful degradation: Falls back to basic metadata when services unavailable
# Development build
cargo build
# Run with debug output
RUST_LOG=debug cargo run
# Run tests
cargo test
# Generate documentation
cargo doc --open
This project uses GitHub Actions for continuous integration and deployment:
- Code Formatting: Enforces consistent style with
cargo fmt
- Linting: Catches common mistakes with
cargo clippy
- Testing: Runs the full test suite (65+ tests)
- Code Coverage: Tracks test coverage with Codecov
- Cross-platform Builds: Builds for x86_64 and aarch64 Linux
The CI pipeline automatically:
- Runs all quality checks on every push/PR
- Generates code coverage reports
- Creates release artifacts for multiple architectures
- Caches dependencies for faster builds
You can run the same checks locally before pushing:
# Format code
cargo fmt
# Run linter
cargo clippy -- -D warnings
# Run tests with coverage
cargo install cargo-tarpaulin
cargo tarpaulin --out Xml
# Build release binary
cargo build --release
- Images:
~/.cache/trackwatch/
- Lyrics:
~/.cache/trackwatch/lyrics/
MIT
- Ashish Kumar (@ash1sh0kumar) for creating mufetch, the incredible terminal music visualizer that inspired this project. His work sparked the idea to build trackwatch and explore terminal-based media visualization.
- The Tidal API for media metadata
- The ratatui community for excellent TUI examples
- playerctl for universal media player support
Made by Estevao Machado