feat(webui): concurrent downloading

This commit is contained in:
tretrauit 2024-03-22 22:12:17 +07:00
parent 51834cc7e6
commit c2203943e2

View File

@ -73,49 +73,53 @@ getLessonButton.addEventListener('click', async () => {
<br>`; <br>`;
} }
let videoDlResult = null; let videoDlResult = null;
const promises = [];
const downloadSelectedButton = document.createElement("button"); const downloadSelectedButton = document.createElement("button");
downloadSelectedButton.innerHTML = "Download Selected"; downloadSelectedButton.innerHTML = "Download Selected";
downloadSelectedButton.addEventListener('click', async () => { downloadSelectedButton.addEventListener('click', async () => {
for (const [id, video] of Object.entries(ids)) { for (const [id, video] of Object.entries(ids)) {
const checkbox = document.querySelector(`#${id}`); promises.push(async () => {
if (!checkbox.checked) { const checkbox = document.querySelector(`#${id}`);
continue; if (!checkbox.checked) {
} return;
const videoRsp = await fetch(`/api/v1/videos/${video.id}`); }
if (videoRsp.status !== 200) { const videoRsp = await fetch(`/api/v1/videos/${video.id}`);
console.error(`Failed to get video ${video.name}`); if (videoRsp.status !== 200) {
continue; console.error(`Failed to get video ${video.name}`);
} return;
const videoData = await videoRsp.json(); }
if (videoDlResult === null) { const videoData = await videoRsp.json();
result.appendChild(document.createElement("br")); if (videoDlResult === null) {
result.appendChild(document.createElement("br")); result.appendChild(document.createElement("br"));
videoDlResult = document.createElement("div"); result.appendChild(document.createElement("br"));
videoDlResult.className = "block"; videoDlResult = document.createElement("div");
result.appendChild(videoDlResult); videoDlResult.className = "block";
} result.appendChild(videoDlResult);
const progressId = randomString(15); }
const progressStrId = randomString(15); const progressId = randomString(15);
videoDlResult.innerHTML += `<span>${video.name}.mp4 <progress id="${progressId}" value="0" max="100"></progress> <span id="${progressStrId}">0%</span></span><br>` const progressStrId = randomString(15);
const rsp = await fetch(`/api/v1/download-video?${new URLSearchParams({ videoDlResult.innerHTML += `<span>${video.name}.mp4 <progress id="${progressId}" value="0" max="100"></progress> <span id="${progressStrId}">0%</span></span><br>`
url: encodeURIComponent(videoData.m3u8), const rsp = await fetch(`/api/v1/download-video?${new URLSearchParams({
output: encodeURIComponent(`videos/${video.name}.mp4`), url: encodeURIComponent(videoData.m3u8),
})}`); output: encodeURIComponent(`videos/${video.name}.mp4`),
const reader = rsp.body.getReader(); })}`);
while (true) { const reader = rsp.body.getReader();
// wait for next encoded chunk while (true) {
const { done, value } = await reader.read(); // wait for next encoded chunk
// check if stream is done const { done, value } = await reader.read();
if (done) break; // check if stream is done
// Decodes data chunk and yields it if (done) break;
const progress = Math.floor(Number.parseFloat(new TextDecoder().decode(value))); // Decodes data chunk and yields it
document.querySelector(`#${progressId}`).value = progress; const progress = Math.floor(Number.parseFloat(new TextDecoder().decode(value)));
document.querySelector(`#${progressStrId}`).innerText = `${progress}%`; document.querySelector(`#${progressId}`).value = progress;
} document.querySelector(`#${progressStrId}`).innerText = `${progress}%`;
if (rsp.status !== 200) { }
console.error(`Failed to download ${video.name}`); if (rsp.status !== 200) {
} console.error(`Failed to download ${video.name}`);
}
});
} }
await Promise.all(promises.map(p => p()));
}); });
result.appendChild(downloadSelectedButton); result.appendChild(downloadSelectedButton);
// result.innerHTML += "<button>Download All</button>"; // result.innerHTML += "<button>Download All</button>";