File size: 8,132 Bytes
2a59b87
 
 
 
 
 
 
 
800e1bb
2a59b87
 
 
8ee6409
5c81fbf
 
 
 
 
 
 
8b2a9bc
5c81fbf
 
8b2a9bc
 
5c81fbf
 
 
 
 
 
 
 
 
 
 
 
 
8b2a9bc
5c81fbf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8b2a9bc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5c81fbf
 
 
466bb96
8ee6409
 
 
466bb96
5c81fbf
8b2a9bc
 
5c81fbf
 
8b2a9bc
 
 
 
 
 
 
 
 
 
5c81fbf
8b2a9bc
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
---
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_