const constants = require("../utils/constants") const cacheManager = require("./cache-manager") const cacheReaper = require("../background/cache-reaper") const lowQualityLimit = 480 let dlQueues = [] const isLowQuality = q => Number(q.split("p")[0]) <= lowQualityLimit class DlQueue { constructor() { this.lq = [] this.hq = [] this.downloadCount = 0 // Ticks up to 3 then downloads an HQ if available this.lastOutput = null this.updating = false } async enqueue(videoID, quality) { quality = quality ?? "360p" let fname = `${videoID}-${quality}` // Same download can't be started multiple times const existingData = cacheManager.read("download")[fname] if ((!existingData || existingData.status != 2) && !downloader.videoExists(fname)) { // Sets to queued cacheManager.write("download", fname, { status: 1 }) // Adds to queue if (isLowQuality(quality)) this.lq.push({videoID, quality}) else this.hq.push({videoID, quality}) if (!this.updating) this.update() } await downloader.waitForDownload(fname) return this.lastOutput } async startDownload(dl) { this.lastOutput = await downloader.saveMp4Android(dl.videoID, dl.quality) } update() { this.updating = true // Scan caches just before downloading cacheReaper.scanCaches() this.downloadCount++ if (this.lq.length > 0 && (this.downloadCount < 3 || this.hq.length == 0)) this.startDownload(this.lq.pop()).then(() => { this.updating = false this.update() }) else if (this.hq.length > 0) { this.startDownload(this.hq.pop()).then(() => { this.updating = false this.update() }) } else this.updating = false if (this.downloadCount == 3) this.downloadCount = 0 } } for (let i = 0; i < constants.server_setup.download_queue_threads; i++) dlQueues.push(new DlQueue()) async function enqueue(videoID, quality) { // Pick the first empty/near-empty download queue const isLQ = quality == undefined || isLowQuality(quality) let sortedQueues if (isLQ) sortedQueues = dlQueues.sort((a, b) => a.lq.length - b.lq.length) else sortedQueues = dlQueues.sort((a, b) => (a.hq.length + (2 - a.downloadCount)) - (b.hq.length + (2 - b.downloadCount))) return await sortedQueues[0].enqueue(videoID, quality) } module.exports = { enqueue } const downloader = require("./downloader")