Spaces:
Runtime error
Runtime error
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>YouTube Music Downloader</title> | |
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"> | |
<style> | |
.download-card { | |
margin: 20px 0; | |
padding: 15px; | |
border-radius: 8px; | |
box-shadow: 0 2px 4px rgba(0,0,0,0.1); | |
} | |
.progress { | |
height: 25px; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container mt-5"> | |
<h1 class="text-center mb-4">YouTube Music Downloader</h1> | |
<div class="row justify-content-center"> | |
<div class="col-md-8"> | |
<div class="card"> | |
<div class="card-body"> | |
<form id="downloadForm"> | |
<div class="input-group mb-3"> | |
<input type="text" class="form-control" id="url" placeholder="Enter YouTube URL" required> | |
<button class="btn btn-primary" type="submit">Download</button> | |
</div> | |
</form> | |
</div> | |
</div> | |
<div id="downloads"></div> | |
</div> | |
</div> | |
</div> | |
<script> | |
document.getElementById('downloadForm').onsubmit = async (e) => { | |
e.preventDefault(); | |
const url = document.getElementById('url').value; | |
const response = await fetch('/download', { | |
method: 'POST', | |
headers: {'Content-Type': 'application/json'}, | |
body: JSON.stringify({url: url}) | |
}); | |
const data = await response.json(); | |
if (data.download_id) { | |
createDownloadCard(data.download_id); | |
document.getElementById('url').value = ''; | |
} | |
}; | |
function createDownloadCard(downloadId) { | |
const card = document.createElement('div'); | |
card.className = 'download-card bg-light'; | |
card.id = `download-${downloadId}`; | |
card.innerHTML = ` | |
<div class="progress mb-3"> | |
<div class="progress-bar progress-bar-striped progress-bar-animated" | |
role="progressbar" style="width: 0%">0%</div> | |
</div> | |
<div class="status">Downloading...</div> | |
`; | |
document.getElementById('downloads').prepend(card); | |
pollStatus(downloadId); | |
} | |
async function pollStatus(downloadId) { | |
while (true) { | |
const response = await fetch(`/status/${downloadId}`); | |
const data = await response.json(); | |
const card = document.getElementById(`download-${downloadId}`); | |
const progressBar = card.querySelector('.progress-bar'); | |
const statusDiv = card.querySelector('.status'); | |
progressBar.style.width = data.progress; | |
progressBar.textContent = data.progress; | |
if (data.status === 'completed') { | |
statusDiv.innerHTML = `Download complete! <a href="/download/${downloadId}" class="btn btn-success btn-sm">Download MP3</a>`; | |
break; | |
} else if (data.status === 'failed') { | |
statusDiv.innerHTML = `Error: ${data.error}`; | |
progressBar.className = 'progress-bar bg-danger'; | |
break; | |
} | |
await new Promise(resolve => setTimeout(resolve, 1000)); | |
} | |
} | |
</script> | |
</body> | |
</html> | |