mirror of
https://github.com/MrUnknownDE/sptify2yt.git
synced 2026-04-24 17:23:50 +02:00
169 lines
5.8 KiB
Markdown
169 lines
5.8 KiB
Markdown
# Spotify to YouTube Music Migration Tool
|
|
|
|
[](https://github.com/MrUnknownDE/sptify2yt)
|
|
|
|
A Node.js web application that migrates your Spotify playlists to YouTube Music with a preview and review workflow.
|
|
|
|
## ✨ Features
|
|
|
|
- 🔐 **OAuth Login** - Secure authentication for Spotify and YouTube
|
|
- 📋 **Playlist Browser** - View and select your Spotify playlists
|
|
- 🔍 **Analysis Queue** - Pre-analyze tracks before migration with rate limiting
|
|
- 👀 **Review & Edit** - Side-by-side comparison of matches, add manual links for missing tracks
|
|
- 🔄 **Real-time Progress** - Live updates via Server-Sent Events
|
|
- 💾 **Persistent Cache** - Search results cached to disk, survives restarts
|
|
- 📊 **Quota Optimization** - Rate limiting and caching to preserve YouTube API quota
|
|
- 🎨 **Modern UI** - Dark theme with glassmorphism design
|
|
- 🐳 **Docker Ready** - Easy deployment with Docker Compose
|
|
|
|
## 📋 Prerequisites
|
|
|
|
### 1. Spotify API Credentials
|
|
|
|
1. Go to [Spotify Developer Dashboard](https://developer.spotify.com/dashboard/)
|
|
2. Create a new application
|
|
3. Add `http://localhost:3000/auth/spotify/callback` to Redirect URIs
|
|
4. Copy your **Client ID** and **Client Secret**
|
|
|
|
### 2. YouTube/Google API Credentials
|
|
|
|
1. Go to [Google Cloud Console](https://console.cloud.google.com/)
|
|
2. Create a new project (or select existing)
|
|
3. Enable **YouTube Data API v3**
|
|
4. Go to **Credentials** → **Create Credentials** → **OAuth 2.0 Client ID**
|
|
5. Configure OAuth consent screen (External, add your email as test user)
|
|
6. Create OAuth client ID (Web application)
|
|
7. Add `http://localhost:3000/auth/youtube/callback` to Authorized redirect URIs
|
|
8. Copy your **Client ID** and **Client Secret**
|
|
|
|
## 🚀 Setup
|
|
|
|
### Option 1: Local Development
|
|
|
|
```bash
|
|
# Clone the repository
|
|
git clone https://github.com/MrUnknownDE/sptify2yt.git
|
|
cd sptify2yt
|
|
|
|
# Install dependencies
|
|
npm install
|
|
|
|
# Copy environment template and add your API credentials
|
|
cp .env.example .env
|
|
nano .env # or use your preferred editor
|
|
|
|
# Start the server
|
|
npm start
|
|
```
|
|
|
|
Open http://localhost:3000 in your browser.
|
|
|
|
### Option 2: Docker
|
|
|
|
```bash
|
|
# Clone the repository
|
|
git clone https://github.com/MrUnknownDE/sptify2yt.git
|
|
cd sptify2yt
|
|
|
|
# Copy and configure environment
|
|
cp .env.example .env
|
|
nano .env
|
|
|
|
# Build and run
|
|
docker compose up -d
|
|
|
|
# View logs (optional)
|
|
docker compose logs -f
|
|
```
|
|
|
|
Open http://localhost:3000 in your browser.
|
|
|
|
To stop: `docker compose down`
|
|
|
|
|
|
## ⚙️ Configuration
|
|
|
|
All settings are configured via environment variables (`.env` file):
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `SPOTIFY_CLIENT_ID` | - | Spotify OAuth Client ID |
|
|
| `SPOTIFY_CLIENT_SECRET` | - | Spotify OAuth Client Secret |
|
|
| `YOUTUBE_CLIENT_ID` | - | Google OAuth Client ID |
|
|
| `YOUTUBE_CLIENT_SECRET` | - | Google OAuth Client Secret |
|
|
| `SESSION_SECRET` | - | Random string for session encryption |
|
|
| `PORT` | `3000` | Server port |
|
|
| `BASE_URL` | `http://localhost:3000` | Base URL for OAuth callbacks |
|
|
| `CACHE_PATH` | `./cache` | Directory for persistent cache |
|
|
| `MAX_PLAYLIST_SIZE` | `500` | Maximum tracks per playlist |
|
|
| `RATE_LIMIT_DELAY_MS` | `2000` | Delay between YouTube API calls (ms) |
|
|
|
|
## 📖 Usage
|
|
|
|
### Workflow
|
|
|
|
1. **Login** - Connect your Spotify and YouTube accounts
|
|
2. **Select Playlist** - Choose a Spotify playlist to migrate
|
|
3. **Analyze** - Click "Analyze Playlist" to search for YouTube matches
|
|
4. **Review** - View side-by-side comparison:
|
|
- ✅ **Found** - Track matched on YouTube
|
|
- ❌ **Not found** - Add a manual YouTube link
|
|
5. **Migrate** - Start the migration to create the YouTube playlist
|
|
|
|
### Caching
|
|
|
|
The app uses two levels of caching:
|
|
|
|
1. **Analysis Jobs** - Complete analysis results saved to `./cache/job_*.json`
|
|
2. **Search Cache** - Individual YouTube search results saved to `./cache/search_cache.json`
|
|
|
|
Search results are cached for 30 days. If you analyze the same track again (even in a different playlist), it uses the cached result without making a new API call.
|
|
|
|
## 📊 YouTube API Quota
|
|
|
|
YouTube Data API has a daily quota of **10,000 units**. Each search costs ~100 units, allowing approximately **100 searches per day**.
|
|
|
|
### How this app optimizes quota:
|
|
|
|
| Feature | Savings |
|
|
|---------|---------|
|
|
| **Search Cache** | Reuses results for duplicate tracks |
|
|
| **Rate Limiting** | 2s delay prevents burst usage |
|
|
| **Pre-Analysis** | Only searches once, migration uses cached data |
|
|
| **Manual Links** | Skip API calls for unknown tracks |
|
|
|
|
## 🗂️ Project Structure
|
|
|
|
```
|
|
sptify2yt/
|
|
├── src/
|
|
│ ├── server.js # Express server with SSE
|
|
│ ├── routes/
|
|
│ │ ├── auth.js # OAuth routes
|
|
│ │ ├── spotify.js # Spotify API routes
|
|
│ │ └── youtube.js # YouTube API + migration
|
|
│ ├── services/
|
|
│ │ ├── analysisQueue.js # Job queue with persistence
|
|
│ │ └── searchCache.js # YouTube search cache
|
|
│ └── public/
|
|
│ ├── index.html # SPA frontend
|
|
│ ├── styles.css # Dark theme styles
|
|
│ └── app.js # Frontend logic
|
|
├── cache/ # Persistent cache (auto-created)
|
|
├── .env.example # Environment template
|
|
├── Dockerfile
|
|
├── docker-compose.yml
|
|
└── package.json
|
|
```
|
|
|
|
## ⚠️ Notes
|
|
|
|
- **YouTube Music Playlists** - YouTube and YouTube Music share playlists, so migrated playlists appear in both
|
|
- **Track Matching** - Searches for "Artist - Track Name" in YouTube's Music category
|
|
- **Manual Links** - For rare/unavailable tracks, paste any YouTube video URL
|
|
- **Cache Cleanup** - Jobs older than 7 days and search results older than 30 days are automatically cleaned up
|
|
|
|
## 📄 License
|
|
|
|
MIT
|