Spaces:
Sleeping
Sleeping
| # Step 3 β Frontend | |
| **Status: TODO** | |
| ## Goal | |
| A simple webpage where the user uploads an audio file, waits while Demucs processes it, then plays back both the original and the cleaned vocal track side by side. | |
| --- | |
| ## Files to create | |
| ``` | |
| frontend/ | |
| βββ index.html # Upload form + audio players | |
| βββ style.css # Basic layout and styling | |
| βββ app.js # Handles upload, polling, and playback | |
| ``` | |
| --- | |
| ## How to build it | |
| ### 1. Create `frontend/index.html` | |
| ```html | |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>Voice Isolation</title> | |
| <link rel="stylesheet" href="style.css"> | |
| </head> | |
| <body> | |
| <div class="card"> | |
| <h1>Voice Isolation</h1> | |
| <p>Upload an audio file to remove background noise.</p> | |
| <input type="file" id="fileInput" accept="audio/*"> | |
| <button id="uploadBtn">Upload & Clean</button> | |
| <div id="status"></div> | |
| <div class="players" id="players" hidden> | |
| <div> | |
| <p>Original</p> | |
| <audio id="originalPlayer" controls></audio> | |
| </div> | |
| <div> | |
| <p>Cleaned</p> | |
| <audio id="cleanedPlayer" controls></audio> | |
| </div> | |
| </div> | |
| </div> | |
| <script src="app.js"></script> | |
| </body> | |
| </html> | |
| ``` | |
| ### 2. Create `frontend/app.js` | |
| ```javascript | |
| const uploadBtn = document.getElementById('uploadBtn'); | |
| const fileInput = document.getElementById('fileInput'); | |
| const status = document.getElementById('status'); | |
| const players = document.getElementById('players'); | |
| const originalPlayer = document.getElementById('originalPlayer'); | |
| const cleanedPlayer = document.getElementById('cleanedPlayer'); | |
| uploadBtn.addEventListener('click', async () => { | |
| const file = fileInput.files[0]; | |
| if (!file) { | |
| status.textContent = 'Please select a file first.'; | |
| return; | |
| } | |
| status.textContent = 'Uploading and processing... this takes 1-3 minutes.'; | |
| players.hidden = true; | |
| const formData = new FormData(); | |
| formData.append('file', file); | |
| const response = await fetch('http://localhost:8000/upload', { | |
| method: 'POST', | |
| body: formData, | |
| }); | |
| const data = await response.json(); | |
| originalPlayer.src = URL.createObjectURL(file); | |
| cleanedPlayer.src = `http://localhost:8000${data.download_url}`; | |
| players.hidden = false; | |
| status.textContent = 'Done!'; | |
| }); | |
| ``` | |
| ### 3. Create `frontend/style.css` | |
| ```css | |
| body { | |
| font-family: sans-serif; | |
| background: #f4f4f4; | |
| display: flex; | |
| justify-content: center; | |
| padding: 40px 20px; | |
| } | |
| .card { | |
| background: white; | |
| padding: 32px; | |
| border-radius: 12px; | |
| box-shadow: 0 2px 12px rgba(0,0,0,0.1); | |
| max-width: 560px; | |
| width: 100%; | |
| } | |
| h1 { margin-top: 0; } | |
| input[type="file"] { display: block; margin: 16px 0; } | |
| button { | |
| background: #2563eb; | |
| color: white; | |
| border: none; | |
| padding: 10px 20px; | |
| border-radius: 6px; | |
| cursor: pointer; | |
| font-size: 16px; | |
| } | |
| button:hover { background: #1d4ed8; } | |
| #status { margin: 16px 0; color: #555; } | |
| .players { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 16px; | |
| margin-top: 16px; | |
| } | |
| ``` | |
| --- | |
| ## How to open it | |
| Just open the HTML file directly in the browser β no server needed for the frontend: | |
| ```bash | |
| xdg-open frontend/index.html # Linux | |
| ``` | |
| Make sure the FastAPI backend is running first: | |
| ```bash | |
| source venv/bin/activate | |
| uvicorn backend.main:app --reload | |
| ``` | |
| --- | |
| ## What the user sees | |
| 1. Opens the page β sees a clean upload card | |
| 2. Selects an audio file | |
| 3. Clicks "Upload & Clean" | |
| 4. Status shows "Processing..." while Demucs runs | |
| 5. Two audio players appear: original and cleaned | |
| 6. User hits play on both to compare | |
| --- | |
| ## Notes | |
| - The backend URL is hardcoded to `localhost:8000` β update this to the live Hugging Face URL after deployment | |
| - No file type validation on the frontend yet β the backend will reject non-audio files anyway | |
| - Processing takes 1β3 minutes on CPU β the status message sets that expectation for the user | |