sigma patch
This commit is contained in:
parent
7a0089d3e6
commit
858091eb60
|
@ -23,7 +23,8 @@
|
||||||
"readable-to-ms": "^1.0.3",
|
"readable-to-ms": "^1.0.3",
|
||||||
"rolling-rate-limiter": "^0.4.2",
|
"rolling-rate-limiter": "^0.4.2",
|
||||||
"wget-improved": "^3.4.0",
|
"wget-improved": "^3.4.0",
|
||||||
"winston": "^3.8.2"
|
"winston": "^3.8.2",
|
||||||
|
"ws": "^8.17.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prisma": "4.9.0"
|
"prisma": "4.9.0"
|
||||||
|
|
153
utils/ytdlp.js
153
utils/ytdlp.js
|
@ -1,13 +1,5 @@
|
||||||
const wget = require('wget-improved')
|
const WebSocket = require('ws')
|
||||||
const DOMPurify = require('isomorphic-dompurify')
|
|
||||||
const metadata = require('./metadata.js')
|
const metadata = require('./metadata.js')
|
||||||
const hr = require('@tsmx/human-readable')
|
|
||||||
|
|
||||||
const ffmpeg = require('fluent-ffmpeg')
|
|
||||||
const ffmpegStatic = require('ffmpeg-static')
|
|
||||||
const fs = require('node:fs')
|
|
||||||
|
|
||||||
ffmpeg.setFfmpegPath(ffmpegStatic)
|
|
||||||
|
|
||||||
async function downloadVideo(url, ws, id) {
|
async function downloadVideo(url, ws, id) {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
|
@ -21,138 +13,29 @@ async function downloadVideo(url, ws, id) {
|
||||||
}
|
}
|
||||||
if (video.basic_info.duration >= 900) quality = '360' // 15 minutes
|
if (video.basic_info.duration >= 900) quality = '360' // 15 minutes
|
||||||
|
|
||||||
const downloadJson = await metadata.getVideoDownload(video, quality)
|
let isDownloading = true
|
||||||
|
const downloader = new WebSocket(`ws://${process.env.METADATA.replace('http://', '')}/download/${id}/${quality}p`)
|
||||||
let size = ''
|
downloader.on('message', async function message(data) {
|
||||||
let startTime = Date.now()
|
const text = data.toString()
|
||||||
let prevBytes = 0
|
if (text == 'done') {
|
||||||
let speed = 0
|
isDownloading = false
|
||||||
const alreadyPrecentages = []
|
|
||||||
|
|
||||||
const target = Array.isArray(downloadJson.url) ? downloadJson.url[0] : downloadJson.url
|
|
||||||
const download = wget.download(target, `./videos/${id}.mp4`, {
|
|
||||||
proxy: {
|
|
||||||
protocol: 'http',
|
|
||||||
host: 'gluetun',
|
|
||||||
port: '8888',
|
|
||||||
headers: {
|
|
||||||
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36',
|
|
||||||
accept: '*/*',
|
|
||||||
origin: 'https://www.youtube.com',
|
|
||||||
referer: 'https://www.youtube.com',
|
|
||||||
DNT: '?1'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
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') {
|
|
||||||
return resolve({
|
|
||||||
fail: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(downloadJson.url)) { // this means video is separate
|
|
||||||
ws.send(`DATA - Downloading the video has finished, downloading audio.`);
|
|
||||||
|
|
||||||
const audioDownload = wget.download(downloadJson.url[1], `./videos/${id}_audio.mp4`, {
|
|
||||||
proxy: {
|
|
||||||
protocol: 'http',
|
|
||||||
host: 'gluetun',
|
|
||||||
port: '8888',
|
|
||||||
headers: {
|
|
||||||
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36',
|
|
||||||
accept: '*/*',
|
|
||||||
origin: 'https://www.youtube.com',
|
|
||||||
referer: 'https://www.youtube.com',
|
|
||||||
DNT: '?1'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
audioDownload.on('end', async (audioOutput) => {
|
|
||||||
if (audioOutput !== 'Finished writing to disk') {
|
|
||||||
return resolve({ fail: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
fs.renameSync(`./videos/${id}.mp4`, `./videos/${id}_video.mp4`);
|
|
||||||
try {
|
|
||||||
await mergeIt(`./videos/${id}_audio.mp4`, `./videos/${id}_video.mp4`, `./videos/${id}.mp4`);
|
|
||||||
ws.send(`DATA - Merging succeeded.`)
|
|
||||||
|
|
||||||
fs.rmSync(`./videos/${id}_audio.mp4`)
|
|
||||||
fs.rmSync(`./videos/${id}_video.mp4`)
|
|
||||||
|
|
||||||
return resolve({ fail: false });
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Merging error:', error);
|
|
||||||
return resolve({ fail: true });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
audioDownload.on('error', (err) => {
|
|
||||||
console.error('Audio download error:', err);
|
|
||||||
return resolve({ fail: true });
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
ws.send(`DATA - Download has finished`)
|
|
||||||
return resolve({
|
return resolve({
|
||||||
fail: false
|
fail: false
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
ws.send(text)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
downloader.on('close', function close(code, reason) {
|
||||||
|
if (!isDownloading) return
|
||||||
|
|
||||||
|
return resolve({
|
||||||
|
fail: true,
|
||||||
|
message: 'The metadata server unexpectedly closed the websocket. Please try again.'
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function mergeIt(audioPath, videoPath, outputPath) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
ffmpeg()
|
|
||||||
.addInput(videoPath)
|
|
||||||
.addInput(audioPath)
|
|
||||||
.outputOptions('-c:v copy')
|
|
||||||
.outputOptions('-c:a aac')
|
|
||||||
.output(outputPath)
|
|
||||||
.on('end', () => {
|
|
||||||
resolve('Merging finished!');
|
|
||||||
})
|
|
||||||
.on('error', (err) => {
|
|
||||||
reject(new Error('An error occurred: ' + err.message));
|
|
||||||
})
|
|
||||||
.run();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
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 }
|
module.exports = { downloadVideo }
|
|
@ -1502,6 +1502,11 @@ ws@^8.11.0:
|
||||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.12.1.tgz#c51e583d79140b5e42e39be48c934131942d4a8f"
|
resolved "https://registry.yarnpkg.com/ws/-/ws-8.12.1.tgz#c51e583d79140b5e42e39be48c934131942d4a8f"
|
||||||
integrity sha512-1qo+M9Ba+xNhPB+YTWUlK6M17brTut5EXbcBaMRN5pH5dFrXz7lzz1ChFSUq3bOUl8yEvSenhHmYUNJxFzdJew==
|
integrity sha512-1qo+M9Ba+xNhPB+YTWUlK6M17brTut5EXbcBaMRN5pH5dFrXz7lzz1ChFSUq3bOUl8yEvSenhHmYUNJxFzdJew==
|
||||||
|
|
||||||
|
ws@^8.17.1:
|
||||||
|
version "8.17.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b"
|
||||||
|
integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==
|
||||||
|
|
||||||
xml-name-validator@^4.0.0:
|
xml-name-validator@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835"
|
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835"
|
||||||
|
|
Loading…
Reference in New Issue