Aggiunta tab Video: YouTube, TikTok, Instagram, Facebook
- core/downloader.py: download_video() con format selector qualita (best / 1080p / 720p / 480p), merge MP4, tracking .downloaded_videos - api/bridge.py: start_video_download / stop_video_download / _video_worker. Guard _any_job_running() per evitare concorrenza tra audio e video (condividono lo stesso _stop_event) - webui: nuova nav item, view con hero rosa (gradient pink->black), selettore qualita, hint cookies per Instagram/Facebook privati - CSS: palette pink, .hero-pink, .btn-pink, .progress-fill.pink, componente .hint riusabile - JS: handlers tab Video, canale bridge video:progress/video:done Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
1 parent
c3f6088b58
commit
8d9c05b151
5 files changed
+455
-3
No files matched your search
+80
-1
@@ -10,9 +10,11 @@ const state = {
|
||||
urlList: [],
|
||||
dlOutputDir: "",
|
||||
upDir: "",
|
||||
videoOutputDir: "",
|
||||
showSecret: false,
|
||||
downloading: false,
|
||||
upgrading: false,
|
||||
videoDownloading: false,
|
||||
};
|
||||
|
||||
// Wait for pywebview ready
|
||||
@@ -80,12 +82,37 @@ const bridgeHandlers = {
|
||||
$("#upgradeBtn").disabled = false;
|
||||
$("#stopUpgradeBtn").disabled = true;
|
||||
},
|
||||
|
||||
"video:progress": (p) => {
|
||||
if (typeof p.overall === "number") {
|
||||
const pct = Math.round(p.overall * 100);
|
||||
$("#videoProgressFill").style.width = pct + "%";
|
||||
$("#videoPercent").textContent = pct + "%";
|
||||
}
|
||||
if (p.status === "downloading" && typeof p.idx === "number") {
|
||||
const prefix = p.url_total > 1 ? `[${(p.url_idx ?? 0) + 1}/${p.url_total}] ` : "";
|
||||
$("#videoCounter").textContent = `${prefix}Video ${p.idx + 1} di ${p.total}`;
|
||||
}
|
||||
if (p.status === "completed" && p.url_total > 1) {
|
||||
$("#videoCounter").textContent = `Completato: ${p.url_total} URL`;
|
||||
}
|
||||
},
|
||||
|
||||
"video:done": () => {
|
||||
state.videoDownloading = false;
|
||||
$("#videoDownloadBtn").disabled = false;
|
||||
$("#stopVideoBtn").disabled = true;
|
||||
},
|
||||
};
|
||||
|
||||
// ============================================================
|
||||
// Logging
|
||||
// ============================================================
|
||||
const logEls = { download: () => $("#dlLog"), upgrade: () => $("#upLog") };
|
||||
const logEls = {
|
||||
download: () => $("#dlLog"),
|
||||
upgrade: () => $("#upLog"),
|
||||
video: () => $("#videoLog"),
|
||||
};
|
||||
|
||||
function classifyLog(msg) {
|
||||
if (msg.startsWith("[ERRORE]")) return "l-err";
|
||||
@@ -159,6 +186,13 @@ async function init() {
|
||||
$("#dlPathDisplay").classList.remove("empty");
|
||||
}
|
||||
|
||||
// Video tab — usa output_dir come default
|
||||
state.videoOutputDir = state.config.output_dir || "";
|
||||
if (state.videoOutputDir) {
|
||||
$("#videoPathDisplay").textContent = state.videoOutputDir;
|
||||
$("#videoPathDisplay").classList.remove("empty");
|
||||
}
|
||||
|
||||
// Upgrade tab — default threshold
|
||||
$("#upThreshold").value = state.config.hq_threshold || 310;
|
||||
}
|
||||
@@ -235,6 +269,51 @@ $("#stopDownloadBtn").addEventListener("click", async () => {
|
||||
$("#stopDownloadBtn").disabled = true;
|
||||
});
|
||||
|
||||
// ============================================================
|
||||
// VIDEO tab
|
||||
// ============================================================
|
||||
$("#videoBrowseBtn").addEventListener("click", async () => {
|
||||
const path = await window.pywebview.api.browse_directory();
|
||||
if (path) {
|
||||
state.videoOutputDir = path;
|
||||
$("#videoPathDisplay").textContent = path;
|
||||
$("#videoPathDisplay").classList.remove("empty");
|
||||
}
|
||||
});
|
||||
|
||||
$("#videoDownloadBtn").addEventListener("click", async () => {
|
||||
const url = $("#videoUrlInput").value.trim();
|
||||
if (!url) {
|
||||
toast("Inserisci un URL", "error");
|
||||
return;
|
||||
}
|
||||
if (!state.videoOutputDir) {
|
||||
toast("Seleziona una cartella di destinazione", "error");
|
||||
return;
|
||||
}
|
||||
|
||||
state.videoDownloading = true;
|
||||
$("#videoDownloadBtn").disabled = true;
|
||||
$("#stopVideoBtn").disabled = false;
|
||||
$("#videoProgressFill").style.width = "0%";
|
||||
$("#videoPercent").textContent = "0%";
|
||||
|
||||
const res = await window.pywebview.api.start_video_download({
|
||||
urls: [url],
|
||||
output_dir: state.videoOutputDir,
|
||||
quality: $("#videoQuality").value,
|
||||
});
|
||||
if (!res.ok) {
|
||||
toast(res.error || "Errore", "error");
|
||||
bridgeHandlers["video:done"]();
|
||||
}
|
||||
});
|
||||
|
||||
$("#stopVideoBtn").addEventListener("click", async () => {
|
||||
await window.pywebview.api.stop_video_download();
|
||||
$("#stopVideoBtn").disabled = true;
|
||||
});
|
||||
|
||||
// ============================================================
|
||||
// UPGRADE tab
|
||||
// ============================================================
|
||||
|
||||
Reference in new issue
Block a user