Spaces:
Running
Running
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_ |