music-player / README.md
prasanth.thangavel
Improve documentation
8b2a9bc
---
title: Music Player
emoji: πŸ’»
colorFrom: indigo
colorTo: blue
sdk: docker
pinned: false
license: mit
short_description: My personal music player
---
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
# Music Player with Supabase Integration
A modern music player with persistent playlist storage using Supabase client API.
## Features
- 🎡 Play local audio files (MP3, WAV)
- 🎚️ Advanced playback controls
- πŸ“ Create and manage playlists
- πŸ”„ Loop and shuffle functionality
- βž• Queue songs to play next and reorder them
- πŸ“€ Upload new songs to the music library
- πŸ’Ύ Persistent storage with Supabase
- πŸ“± Responsive design
- 🎨 Modern UI with Material Design
- πŸ” Secure API-based storage
## Setup Instructions
### 1. Supabase Project Setup
1. Create a free account at [Supabase](https://supabase.com)
2. Create a new project
3. Go to **Settings** β†’ **API** and copy your credentials:
- **Project URL** (starts with `https://`)
- **service_role [secret]** key (starts with `eyJ...`)
### 2. Database Schema
Run this SQL in your Supabase SQL Editor to create the required tables:
```sql
-- Create playlists table
CREATE TABLE playlists (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Create playlist_songs table
CREATE TABLE playlist_songs (
id SERIAL PRIMARY KEY,
playlist_id INTEGER REFERENCES playlists(id) ON DELETE CASCADE,
song_name VARCHAR(500) NOT NULL,
song_order INTEGER DEFAULT 0,
added_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Create user_preferences table
CREATE TABLE user_preferences (
id SERIAL PRIMARY KEY,
preference_key VARCHAR(100) UNIQUE NOT NULL,
preference_value TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Insert default preferences
INSERT INTO user_preferences (preference_key, preference_value) VALUES
('is_looping', 'false'),
('is_shuffling', 'false'),
('volume', '1.0'),
('current_playlist', 'all')
ON CONFLICT (preference_key) DO NOTHING;
```
### 3. Environment Variables
Set these environment variables in your Hugging Face Space settings:
- **SUPABASE_URL**: Your Supabase project URL
- **SUPABASE_KEY**: Your Supabase anon public key
### 4. Local Development
1. Clone the repository
2. Install dependencies: `pip install -r requirements.txt`
3. Create a `.env` file:
```
SUPABASE_URL=your_supabase_project_url
SUPABASE_KEY=your_supabase_anon_key
FLASK_ENV=development
```
4. Run the application: `python app.py`
### 5. Testing
Test your Supabase connection:
```bash
python test_supabase_client.py
```
### 6. Docker Deployment
```bash
# Build and run locally
docker build -t musicplayer .
docker run -p 7860:7860 -e SUPABASE_URL=your_url -e SUPABASE_KEY=your_key musicplayer
# Or use docker-compose
docker-compose up --build
```
## API Endpoints
- `GET /api/playlists` - Get all playlists
- `POST /api/playlists` - Create a new playlist
- `GET /api/playlists/<id>/songs` - Get songs in a playlist
- `DELETE /api/playlists/<id>` - Delete a playlist
- `GET /api/preferences/<key>` - Get user preference
- `POST /api/preferences/<key>` - Set user preference
## Architecture
This application uses:
- **Flask** for the web server
- **Supabase Client** for database operations
- **JavaScript** for frontend functionality
- **Docker** for containerization
### System Architecture Diagram
```mermaid
graph TB
subgraph "Frontend Layer"
UI[🎡 Web Interface<br/>HTML/CSS/JavaScript]
Player[🎧 Audio Player<br/>HTML5 Audio API]
FileUpload[πŸ“€ File Upload<br/>Drag & Drop]
end
subgraph "Backend Layer"
Flask[🐍 Flask Server<br/>Port 7860]
API[πŸ”— REST API<br/>Endpoints]
FileHandler[πŸ“ File Handler<br/>Upload Management]
Logger[πŸ“‹ Logging System<br/>app.log]
end
subgraph "Database Layer"
Supabase[πŸ—„οΈ Supabase Database<br/>PostgreSQL]
PlaylistsTable[(πŸ“‹ playlists<br/>id, name, timestamps)]
SongsTable[(🎡 playlist_songs<br/>id, playlist_id, song_name, order)]
PrefsTable[(βš™οΈ user_preferences<br/>key, value, timestamps)]
end
subgraph "Storage Layer"
AudioFiles[🎡 Audio Files<br/>static/audio/]
StaticFiles[πŸ“‚ Static Assets<br/>CSS, JS, Images]
end
subgraph "Deployment Layer"
Docker[🐳 Docker Container<br/>Containerized App]
HF[πŸ€— Hugging Face Space<br/>Cloud Deployment]
end
subgraph "API Endpoints"
GET_Playlists[GET /api/playlists]
POST_Playlists[POST /api/playlists]
GET_Songs[GET /api/playlists/:id/songs]
DELETE_Playlist[DELETE /api/playlists/:id]
GET_Prefs[GET /api/preferences/:key]
POST_Prefs[POST /api/preferences/:key]
POST_Upload[POST /api/upload]
GET_Debug[GET /api/debug/logs]
end
%% Frontend to Backend
UI -->|HTTP Requests| Flask
Player -->|Play Audio| AudioFiles
FileUpload -->|Upload Files| FileHandler
%% Backend Internal
Flask --> API
API --> FileHandler
Flask --> Logger
%% API to Database
GET_Playlists --> PlaylistsTable
POST_Playlists --> PlaylistsTable
GET_Songs --> SongsTable
DELETE_Playlist --> PlaylistsTable
GET_Prefs --> PrefsTable
POST_Prefs --> PrefsTable
POST_Upload --> AudioFiles
GET_Debug --> Logger
%% Database Connections
API -->|Supabase Client| Supabase
Supabase --> PlaylistsTable
Supabase --> SongsTable
Supabase --> PrefsTable
%% File System
FileHandler --> AudioFiles
Flask --> StaticFiles
%% Deployment
Flask --> Docker
Docker --> HF
%% Styling
classDef frontend fill:#e1f5fe,stroke:#01579b,stroke-width:2px,color:#000000
classDef backend fill:#f3e5f5,stroke:#4a148c,stroke-width:2px,color:#000000
classDef database fill:#e8f5e8,stroke:#1b5e20,stroke-width:2px,color:#000000
classDef storage fill:#fff3e0,stroke:#e65100,stroke-width:2px,color:#000000
classDef deployment fill:#fce4ec,stroke:#880e4f,stroke-width:2px,color:#000000
classDef api fill:#fff8e1,stroke:#f57f17,stroke-width:2px,color:#000000
class UI,Player,FileUpload frontend
class Flask,API,FileHandler,Logger backend
class Supabase,PlaylistsTable,SongsTable,PrefsTable database
class AudioFiles,StaticFiles storage
class Docker,HF deployment
class GET_Playlists,POST_Playlists,GET_Songs,DELETE_Playlist,GET_Prefs,POST_Prefs,POST_Upload,GET_Debug api
```
### Data Flow
1. **User Interaction**: User interacts with the web interface to play music, create playlists, upload files
2. **API Communication**: Frontend sends HTTP requests to Flask backend API endpoints
3. **Database Operations**: Backend performs CRUD operations on Supabase PostgreSQL database
4. **File Management**: Audio files are stored locally and served through Flask static file handling
5. **Persistence**: User preferences and playlist data are stored in Supabase for persistence across sessions
## Todo
### Testing
- [ ] Test docker locally for faster iterative testing.
```
docker build -t musicplayer .
docker run -p 7860:7860 musicplayer
```
### Enhancements
#### Completed
- [x] Add persistent storage with Supabase
- [x] Fix loop functionality
- [x] Add search functionality
- [x] Add file upload functionality
#### Ongoing and Future works*
- [ ] Improve the UI/UX
- [ ] [Missing feature] No button to pause/resume playing
- [ ] Implement YouTube Music-inspired UI
- [ ] Add a aesthetically beautiful background theme/color/design
- [ ] Improve the icons/buttons and overall design
- [ ] Make it very mobile responsive
- [ ] Add audio visualization
- [ ] Add equalizer
- [ ] Add lyrics display feature (with syncronised scrolling)
- [ ] Add user authentication
- [ ] Add offline capabilities
*_in the order or priority_