eirtube/eirtubeMods/dl-queue.js
2024-12-19 18:49:09 -06:00

90 lines
2.3 KiB
JavaScript
Executable File

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")