From c2203943e292f6e4ac4e0485da522231bfc5067f Mon Sep 17 00:00:00 2001 From: tretrauit Date: Fri, 22 Mar 2024 22:12:17 +0700 Subject: [PATCH] feat(webui): concurrent downloading --- web/assets/index.js | 80 ++++++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/web/assets/index.js b/web/assets/index.js index 109566b..bf1d77a 100644 --- a/web/assets/index.js +++ b/web/assets/index.js @@ -73,49 +73,53 @@ getLessonButton.addEventListener('click', async () => {
`; } let videoDlResult = null; + const promises = []; const downloadSelectedButton = document.createElement("button"); downloadSelectedButton.innerHTML = "Download Selected"; downloadSelectedButton.addEventListener('click', async () => { for (const [id, video] of Object.entries(ids)) { - const checkbox = document.querySelector(`#${id}`); - if (!checkbox.checked) { - continue; - } - const videoRsp = await fetch(`/api/v1/videos/${video.id}`); - if (videoRsp.status !== 200) { - console.error(`Failed to get video ${video.name}`); - continue; - } - const videoData = await videoRsp.json(); - if (videoDlResult === null) { - result.appendChild(document.createElement("br")); - result.appendChild(document.createElement("br")); - videoDlResult = document.createElement("div"); - videoDlResult.className = "block"; - result.appendChild(videoDlResult); - } - const progressId = randomString(15); - const progressStrId = randomString(15); - videoDlResult.innerHTML += `${video.name}.mp4 0%
` - const rsp = await fetch(`/api/v1/download-video?${new URLSearchParams({ - url: encodeURIComponent(videoData.m3u8), - output: encodeURIComponent(`videos/${video.name}.mp4`), - })}`); - const reader = rsp.body.getReader(); - while (true) { - // wait for next encoded chunk - const { done, value } = await reader.read(); - // check if stream is done - if (done) break; - // Decodes data chunk and yields it - const progress = Math.floor(Number.parseFloat(new TextDecoder().decode(value))); - document.querySelector(`#${progressId}`).value = progress; - document.querySelector(`#${progressStrId}`).innerText = `${progress}%`; - } - if (rsp.status !== 200) { - console.error(`Failed to download ${video.name}`); - } + promises.push(async () => { + const checkbox = document.querySelector(`#${id}`); + if (!checkbox.checked) { + return; + } + const videoRsp = await fetch(`/api/v1/videos/${video.id}`); + if (videoRsp.status !== 200) { + console.error(`Failed to get video ${video.name}`); + return; + } + const videoData = await videoRsp.json(); + if (videoDlResult === null) { + result.appendChild(document.createElement("br")); + result.appendChild(document.createElement("br")); + videoDlResult = document.createElement("div"); + videoDlResult.className = "block"; + result.appendChild(videoDlResult); + } + const progressId = randomString(15); + const progressStrId = randomString(15); + videoDlResult.innerHTML += `${video.name}.mp4 0%
` + const rsp = await fetch(`/api/v1/download-video?${new URLSearchParams({ + url: encodeURIComponent(videoData.m3u8), + output: encodeURIComponent(`videos/${video.name}.mp4`), + })}`); + const reader = rsp.body.getReader(); + while (true) { + // wait for next encoded chunk + const { done, value } = await reader.read(); + // check if stream is done + if (done) break; + // Decodes data chunk and yields it + const progress = Math.floor(Number.parseFloat(new TextDecoder().decode(value))); + document.querySelector(`#${progressId}`).value = progress; + document.querySelector(`#${progressStrId}`).innerText = `${progress}%`; + } + if (rsp.status !== 200) { + console.error(`Failed to download ${video.name}`); + } + }); } + await Promise.all(promises.map(p => p())); }); result.appendChild(downloadSelectedButton); // result.innerHTML += "";