84 lines
3.0 KiB
JavaScript
84 lines
3.0 KiB
JavaScript
const wget = require('wget-improved')
|
|
const DOMPurify = require('isomorphic-dompurify')
|
|
const metadata = require('./metadata.js')
|
|
const hr = require('@tsmx/human-readable')
|
|
|
|
async function downloadVideo(url, ws, id) {
|
|
return new Promise(async (resolve, reject) => {
|
|
let quality = '720'
|
|
const video = await metadata.getVideoMetadata(id)
|
|
if (video.error) {
|
|
return resolve({
|
|
message: `Failed to request Youtube with error ${video.error}. Please retry...`,
|
|
fail: true
|
|
})
|
|
}
|
|
if (video.basic_info.duration >= 900) quality = '360' // 15 minutes
|
|
|
|
const downloadJson = await metadata.getVideoDownload(url, quality)
|
|
if (downloadJson.status == 'error') {
|
|
return resolve({
|
|
message: `Failed to request Youtube with error ${downloadJson.text}. Please retry...`,
|
|
fail: true
|
|
})
|
|
}
|
|
|
|
let size = ''
|
|
let startTime = Date.now()
|
|
let prevBytes = 0
|
|
let speed = 0
|
|
const alreadyPrecentages = []
|
|
const download = wget.download(downloadJson.url, `./videos/${id}.mp4`, {
|
|
proxy: 'http://gluetun:8888'
|
|
})
|
|
|
|
download.on('start', fileSize => {
|
|
size = fileSize
|
|
if (ws) ws.send(`DATA - Download has started in ${quality}p`)
|
|
})
|
|
|
|
download.on('progress', progress => {
|
|
if (alreadyPrecentages.includes((progress*100).toFixed(0))) return
|
|
alreadyPrecentages.push((progress*100).toFixed(0))
|
|
|
|
const currentTime = Date.now()
|
|
const elapsedTime = (currentTime - startTime) / 1000
|
|
const currentBytes = progress * size
|
|
const bytesDownloaded = currentBytes - prevBytes
|
|
speed = bytesDownloaded / elapsedTime
|
|
prevBytes = currentBytes
|
|
|
|
const speedInMBps = speed / 1048576
|
|
const remainingBytes = size - currentBytes
|
|
const remainingTime = remainingBytes / speed
|
|
|
|
if (ws) ws.send(`DATA - [download] ${(progress*100).toFixed(2)}% of ${hr.fromBytes(size)} at ${speedInMBps.toFixed(2)} MB/s ETA ${secondsToTime(remainingTime.toFixed(0))}`)
|
|
})
|
|
|
|
download.on('error', err => {
|
|
if (ws) ws.send(`DATA - ${DOMPurify.sanitize(err)}`)
|
|
})
|
|
|
|
download.on('end', output => {
|
|
if (output == 'Finished writing to disk') {
|
|
ws.send(`DATA - Download has finished`)
|
|
return resolve({
|
|
fail: false
|
|
})
|
|
} else {
|
|
return resolve({
|
|
fail: true
|
|
})
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
function secondsToTime(seconds) {
|
|
const minutes = Math.floor(seconds / 60);
|
|
const remainingSeconds = seconds % 60;
|
|
const formattedSeconds = remainingSeconds < 10 ? '0' + remainingSeconds : remainingSeconds;
|
|
return `${minutes}:${formattedSeconds}`;
|
|
}
|
|
|
|
module.exports = { downloadVideo } |