Primo Caricamento

This commit is contained in:
2026-01-10 13:21:36 +01:00
commit a36973ae12
10 changed files with 630 additions and 0 deletions

118
frontend/main.js Normal file
View File

@@ -0,0 +1,118 @@
const urlInput = document.getElementById('url');
const fetchInfoBtn = document.getElementById('fetchInfo');
const downloadBtn = document.getElementById('download');
const statusEl = document.getElementById('status');
const resultEl = document.getElementById('result');
const modeSelect = document.getElementById('mode');
const videoSelect = document.getElementById('videoFormat');
const audioSelect = document.getElementById('audioFormat');
const audioExt = document.getElementById('audioExt');
let lastFormats = { video: [], audio: [] };
function setStatus(text) {
statusEl.textContent = text || '';
}
function showResult(html) {
if (!html) {
resultEl.classList.add('hidden');
resultEl.innerHTML = '';
return;
}
resultEl.classList.remove('hidden');
resultEl.innerHTML = html;
}
function fillSelect(select, items, formatter) {
select.innerHTML = '<option value="">Best disponibile</option>';
items.forEach(item => {
const opt = document.createElement('option');
opt.value = item.id;
opt.textContent = formatter(item);
select.appendChild(opt);
});
select.disabled = items.length === 0;
}
async function fetchInfo() {
const url = urlInput.value.trim();
if (!url) {
showResult('Inserisci un URL.');
return;
}
setStatus('Recupero formati...');
showResult('');
try {
const res = await fetch('/api/info', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url })
});
const data = await res.json();
if (!res.ok) throw new Error(data.error || 'Errore');
lastFormats.video = data.video_formats || [];
lastFormats.audio = data.audio_formats || [];
fillSelect(videoSelect, lastFormats.video, (f) => {
const reso = f.resolution ? `${f.resolution}` : 'Auto';
const fps = f.fps ? `${f.fps}fps` : '';
const size = f.size ? ` · ${f.size}` : '';
return `${reso} ${fps}${size} (${f.ext})`;
});
fillSelect(audioSelect, lastFormats.audio, (f) => {
const abr = f.abr ? `${f.abr}kbps` : 'bitrate auto';
const size = f.size ? ` · ${f.size}` : '';
return `${f.ext} ${abr}${size}`;
});
audioExt.disabled = false;
const minutes = data.duration ? Math.round(data.duration / 60) : '?';
showResult(`Titolo: <strong>${data.title || 'sconosciuto'}</strong><br/>Durata: ${minutes} min`);
setStatus('Pronto al download');
} catch (err) {
showResult(`Errore: ${err.message}`);
setStatus('');
}
}
async function startDownload() {
const url = urlInput.value.trim();
if (!url) {
showResult('Inserisci un URL.');
return;
}
setStatus('Scarico...');
showResult('');
const mode = modeSelect.value;
const payload = {
url,
mode,
format_id: mode === 'video' ? videoSelect.value : audioSelect.value,
audio_ext: mode === 'audio' ? audioExt.value : undefined,
};
try {
const res = await fetch('/api/download', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
const data = await res.json();
if (!res.ok) throw new Error(data.error || 'Errore');
const link = `<a href="${data.url}" download>${data.file}</a>`;
showResult(`File pronto: ${link}`);
setStatus('Completo');
} catch (err) {
showResult(`Errore: ${err.message}`);
setStatus('');
}
}
fetchInfoBtn.addEventListener('click', fetchInfo);
downloadBtn.addEventListener('click', startDownload);