92 lines
2.3 KiB
JavaScript
Executable File
92 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)))
|
|
|
|
const out = sortedQueues[0].enqueue(videoID, quality)
|
|
// console.log(dlQueues)
|
|
return await out
|
|
}
|
|
|
|
module.exports = {
|
|
enqueue
|
|
}
|
|
|
|
const downloader = require("./downloader")
|