Skip to content

Repository files navigation

MuSync 2.0

License: GPL v3 Docker React Flask PostgreSQL Redis Celery

MuSync is a self-hosted, enterprise-ready playlist synchronization engine that bridges Spotify and YouTube Music. You provide your own API keys, and everything runs locally or within your private cluster.

Features

  • Self-Hosted: No external services, no cloud dependencies. Runs entirely on your machine.
  • Bidirectional Sync: Transfer playlists both ways (Spotify ↔ YouTube Music).
  • Hybrid Smart Matcher: Combined textual scoring (fuzzy matching on name, artist, and duration) and visual-similarity checks of album cover art using Pillow average-hashing (aHash).
  • Celery & Redis Worker: Asynchronous, non-blocking sync task execution processed by detached background workers.
  • Coordinated Rate Limiting: Coordinated Redis sorted-set sliding-window rate limiter with an in-memory thread-locked fallback to avoid API throttling.
  • Secret Key Rotation: Secure integration with HashiCorp Vault for token/AppRole credential encryption key rotation.
  • Alembic Migrations: Structured database schema evolution.
  • Resumable Syncs: Checkpoint system to resume failed syncs from where they stopped.
  • Real-Time Dashboard: Live sync progress, track-by-track status updates, and history.
  • Neo Design: Minimalist, high-end dark UI with true black backgrounds, custom HSL styling, Inter typography, and micro-animations.

Prerequisites

  • Docker & Docker Compose
  • Spotify Developer Account (free)
  • Google Cloud / YouTube Developer Account (free)
  • Redis (required for background tasks and sliding window rate limiting)
  • Optional: HashiCorp Vault instance (for secure master key storage and rotation)

Quick Start

1. Get API Credentials

Spotify:

  1. Go to the Spotify Developer Dashboard
  2. Create an application.
  3. Add the redirect URI: http://localhost:5001/auth/spotify/callback
  4. Copy the Client ID and Client Secret.

Google / YouTube:

  1. Go to the Google Cloud Console
  2. Enable the YouTube Data API v3.
  3. Create OAuth 2.0 Credentials (Web application).
  4. Add the redirect URI: http://localhost:5001/auth/ytmusic/callback
  5. Copy the Client ID and Client Secret.

2. Clone & Configure

git clone https://github.com/naveenchander30/MuSync.git
cd MuSync
cp .env.example .env

Edit .env with your settings:

AUTH_BASE_URL=http://localhost:5001
SPOTIFY_CLIENT_ID=your_spotify_client_id
SPOTIFY_CLIENT_SECRET=your_spotify_client_secret
GOOGLE_OAUTH_CLIENT_ID=your_google_client_id.apps.googleusercontent.com
GOOGLE_OAUTH_CLIENT_SECRET=your_google_client_secret
DATABASE_URL=postgresql+psycopg://postgres:postgres@localhost:5432/musync
MASTER_PASSWORD=your_secure_password

# Redis & Celery
CELERY_BROKER_URL=redis://localhost:6379/0
CELERY_RESULT_BACKEND=redis://localhost:6379/0
REDIS_URL=redis://localhost:6379/0

# Optional: HashiCorp Vault Secret Management
# VAULT_ADDR=http://127.0.0.1:8200
# VAULT_TOKEN=your_vault_token

3. Start the Stack

docker-compose up -d

This commands spins up the Flask API backend, Celery worker, Redis instance, PostgreSQL database, and frontend web application. Schema migrations will run automatically on startup.

Open http://localhost:5001 in your browser and connect your music accounts.

For detailed local configuration and production SaaS cloud deployment guidelines (Vercel + Render + Neon + Upstash), see SETUP.md.

Architecture

┌────────────────────────────────────────────────────────┐
│                      Your Browser                      │
│                 http://localhost:5001                  │
└───────────────────────────┬────────────────────────────┘
                            │ (JSON REST API & Frontend)
                            v
┌────────────────────────────────────────────────────────┐
│                     Flask Backend                      │
│ - OAuth Handling         - REST API Routing            │
│ - State Checkpointing    - Rate Limiting Fallback      │
└─────────────────────┬──────────────┬───────────────────┘
                      │              │
    (Queue Job)       v              v (Read/Write)
  ┌───────────────────────┐      ┌───────────────────────┐
  │     Redis Broker      │      │ PostgreSQL DB (Vault  │
  │  & Sliding Window Rate│      │ encrypted tokens &    │
  │      Limiter State    │      │ Alembic migrations)   │
  └───────────┬───────────┘      └───────────────────────┘
              │                              ^
              v (Consume Job)                │ (Store/Load)
  ┌───────────────────────┐                  │
  │    Celery Workers     │                  │
  │ - Image aHash Matcher │──────────────────┘
  │ - Spotify / YT Sync   │
  └───────────┬───────────┘
              │ (HTTPS APIs)
              v
  ┌──────────────────────────────────────────────────────┐
  │                    External APIs                     │
  │           Spotify   ↔   YouTube Music                │
  └──────────────────────────────────────────────────────┘

The frontend is a single-page React app served by the Flask backend. Long-running sync jobs are offloaded to background Celery workers, ensuring the Flask application remains responsive under load.

Project Structure

MuSync/
├── backend/
│   ├── app.py                 # Flask application entry & startup checks
│   ├── celery_app.py          # Celery configuration & factory
│   ├── tasks.py               # Celery task definitions for async sync jobs
│   ├── config.py              # Application settings and environment variables
│   ├── requirements.txt       # Python dependencies (hvac, celery, redis, Pillow)
│   ├── auth/                  
│   │   ├── encryption.py      # AES-256 token encryption with optional Vault integration
│   │   └── oauth.py           # Spotify & Google OAuth handshakes
│   ├── database/              
│   │   └── connection.py      # SQLAlchemy connection setup & session factory
│   ├── sync/                  
│   │   ├── matcher.py         # Fuzzy textual matcher & Pillow average-hashing visual similarity
│   │   ├── rate_limiter.py    # Redis-coordinated sliding window rate limiter
│   │   └── orchestrator.py    # Multi-stage playlist sync logic
│   ├── api/                   # REST API routes (sync, dashboard status, health checks)
│   └── tests/                 # Comprehensive Pytest suite (Vault mocks, Hashing tests)
├── migrations/                # Alembic database migration scripts
├── alembic.ini                # Alembic configuration
├── frontend/
│   ├── src/
│   │   ├── components/        # React components (Neo true-black UI design)
│   │   ├── test/              # Vitest test suite
│   │   ├── App.jsx            # Application routing & dashboard view
│   │   ├── api.js             # Client-side API interactions
│   │   └── index.css          # Styling tokens
│   └── tailwind.config.js     # Tailwind configurations
├── docker-compose.yml         # Container orchestration definitions
├── Dockerfile.backend         # Production Docker setup for Python service & Celery
├── Dockerfile.frontend        # Production Docker setup for React build
├── SETUP.md                   # Complete developer & deployment guide
└── .env.example               # Configuration template

Testing

# Backend Test Suite (inc. Vault & Image Hashing mocks)
cd backend
pip install -r requirements.txt
pytest tests/ -v

# Frontend Test Suite
cd frontend
npm install
npx vitest run

License

GNU GPLv3 License - see the LICENSE file for details.

About

Cross-platform music syncing service for Spotify and YTMusic

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages