| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Suno AI Docker Studio</title> |
| <script src="https://cdn.socket.io/4.7.5/socket.io.min.js"></script> |
| <style> |
| :root { --primary: #6366f1; --bg: #0b0f1a; --card: #161e2d; --input: #242f41; } |
| body { background: var(--bg); color: #e2e8f0; font-family: sans-serif; padding: 20px; display: flex; justify-content: center; } |
| .container { width: 100%; max-width: 600px; background: var(--card); padding: 30px; border-radius: 12px; border: 1px solid #2d3748; } |
| label { display: block; margin: 15px 0 5px; font-size: 13px; color: #94a3b8; } |
| input, textarea, select { width: 100%; padding: 12px; background: var(--input); border: 1px solid #334155; border-radius: 8px; color: white; box-sizing: border-box; margin-bottom: 10px; } |
| button { width: 100%; padding: 15px; background: var(--primary); border: none; color: white; font-weight: bold; border-radius: 8px; cursor: pointer; } |
| #log { margin-top: 20px; background: #000; padding: 15px; height: 150px; overflow-y: auto; font-family: monospace; font-size: 12px; border-radius: 8px; color: #10b981; } |
| .dl-link { display: none; background: #059669; text-decoration: none; padding: 15px; text-align: center; border-radius: 8px; font-weight: bold; color: white; margin-top: 15px; } |
| .status-header { display: flex; justify-content: space-between; align-items: center; } |
| #status-indicator { font-size: 12px; padding: 4px 8px; border-radius: 4px; background: #ef4444; } |
| </style> |
| </head> |
| <body> |
|
|
| <div class="container"> |
| <div class="status-header"> |
| <h3>Suno Studio</h3> |
| <span id="status-indicator">OFFLINE</span> |
| </div> |
| |
| <label>API Token</label> |
| <div style="display:flex; gap:10px;"> |
| <input type="password" id="tk" placeholder="sk-..."> |
| <button onclick="saveTk()" style="width:auto;">Link</button> |
| </div> |
|
|
| <label>Source MP3 URL</label> |
| <input type="text" id="url" placeholder="Direct audio link"> |
|
|
| <label>Style & Genre</label> |
| <input type="text" id="style" placeholder="e.g. Hindi, slow"> |
|
|
| <label>Lyrics</label> |
| <textarea id="lyr" rows="4"></textarea> |
|
|
| <div style="margin-bottom:20px;"> |
| <input type="checkbox" id="instr" style="width:auto;"> <span>Instrumental Mode</span> |
| </div> |
|
|
| <button onclick="start()">Generate & Auto-Save</button> |
|
|
| <div id="log">Logs: Initialization...</div> |
| <a id="dl" href="#" class="dl-link">📥 Download From Docker</a> |
| </div> |
|
|
| <script> |
| |
| const socket = io({ |
| transports: ['websocket', 'polling'], |
| upgrade: true, |
| rememberUpgrade: true |
| }); |
| |
| const statusInd = document.getElementById('status-indicator'); |
| |
| socket.on('connect', () => { |
| statusInd.innerText = "ONLINE"; |
| statusInd.style.background = "#10b981"; |
| addLog("Connected to Docker container."); |
| }); |
| |
| socket.on('disconnect', () => { |
| statusInd.innerText = "OFFLINE"; |
| statusInd.style.background = "#ef4444"; |
| addLog("Connection lost."); |
| }); |
| |
| function saveTk() { |
| socket.emit('save_token', {token: document.getElementById('tk').value}); |
| } |
| |
| function start() { |
| const payload = { |
| uploadUrl: document.getElementById('url').value, |
| customMode: true, |
| model: "V5", |
| prompt: document.getElementById('lyr').value, |
| style: document.getElementById('style').value, |
| title: "Suno_Track", |
| instrumental: document.getElementById('instr').checked |
| }; |
| socket.emit('start_gen', payload); |
| document.getElementById('dl').style.display = 'none'; |
| addLog("🚀 Task submitted..."); |
| } |
| |
| function addLog(msg) { |
| const log = document.getElementById('log'); |
| log.innerHTML += `<div>[${new Date().toLocaleTimeString()}] ${msg}</div>`; |
| log.scrollTop = log.scrollHeight; |
| } |
| |
| socket.on('status', (d) => { |
| addLog(d.msg); |
| if(d.done) { |
| const btn = document.getElementById('dl'); |
| btn.href = `./get_music/${d.file_name}`; |
| btn.style.display = 'block'; |
| } |
| }); |
| </script> |
|
|
| </body> |
| </html> |