Functions
This commit is contained in:
parent
d9f7a8d4fc
commit
3321673f62
7 changed files with 378 additions and 1097 deletions
116
downloader.js
Normal file
116
downloader.js
Normal file
|
@ -0,0 +1,116 @@
|
|||
const expressManager = require("./express.js"),
|
||||
path = require("path"),
|
||||
fs = require("fs"),
|
||||
ytdl = require("@distube/ytdl-core"),
|
||||
ffmpeg = require("ffmpeg-static"),
|
||||
cp = require("child_process")
|
||||
|
||||
var qualityLabels = [
|
||||
"144",
|
||||
"240",
|
||||
"360",
|
||||
"480",
|
||||
"720",
|
||||
"1080",
|
||||
"1440",
|
||||
"2160"
|
||||
]
|
||||
|
||||
var audioFormats = [
|
||||
"mp3"
|
||||
]
|
||||
|
||||
expressManager.app.get("/download", async (req, res) => {
|
||||
var url = req.query.url,
|
||||
quality = req.query.quality,
|
||||
format = req.query.format
|
||||
|
||||
if (ytdl.validateURL(url) && qualityLabels.includes(quality)) {
|
||||
var needsVideo = !audioFormats.includes(format)
|
||||
|
||||
var info = await ytdl.getInfo(url)
|
||||
|
||||
res.setHeader("Content-Disposition", `attachment; filename*="${info.videoDetails.title.replace(/[^a-z0-9 ]/gi, '')}.${format}"`)
|
||||
|
||||
var audioFormat = ytdl.chooseFormat(info.formats, { filter: (format) => {
|
||||
return format.hasAudio && !format.hasVideo
|
||||
} })
|
||||
|
||||
var videoFormat = undefined
|
||||
|
||||
var qualityLabel = quality
|
||||
while (videoFormat == undefined) {
|
||||
for (let i = 0; i < info.formats.length; i++) {
|
||||
const format = info.formats[i];
|
||||
if (format.hasVideo && !format.hasAudio && format.height.toString() == qualityLabel.toString()) {
|
||||
videoFormat = format
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if (qualityLabels.indexOf(qualityLabel) - 1 < 0) {
|
||||
break
|
||||
}
|
||||
qualityLabel = qualityLabels[qualityLabels.indexOf(qualityLabel) - 1]
|
||||
}
|
||||
|
||||
if (!videoFormat) {
|
||||
videoFormat = ytdl.chooseFormat(info.formats, { filter: "videoonly" })
|
||||
}
|
||||
|
||||
var baseArgs = [
|
||||
// Remove ffmpeg's console spamming
|
||||
'-loglevel', 'error',
|
||||
// // Set inputs
|
||||
// '-i', 'pipe:4',
|
||||
// '-i', 'pipe:5',
|
||||
// Map audio & video from streams
|
||||
// '-map', '0:a',
|
||||
// '-map', '1:v',
|
||||
// Keep encoding
|
||||
'-c:v', 'copy',
|
||||
'-movflags','frag_keyframe+empty_moov',
|
||||
'-f', format,
|
||||
// Define output file
|
||||
'-',
|
||||
]
|
||||
|
||||
var inputArgs = [
|
||||
'-i', 'pipe:4'
|
||||
]
|
||||
|
||||
var mapArgs = [
|
||||
'-map', '0:a'
|
||||
]
|
||||
|
||||
if (needsVideo) {
|
||||
inputArgs = inputArgs.concat(['-i', 'pipe:5'])
|
||||
mapArgs = mapArgs.concat(['-map', '1:v'])
|
||||
}
|
||||
|
||||
var args = inputArgs.concat(mapArgs).concat(baseArgs)
|
||||
|
||||
const ffmpegProcess = cp.spawn(ffmpeg, args, {
|
||||
windowsHide: true,
|
||||
stdio: [
|
||||
/* Standard: stdin, stdout, stderr */
|
||||
'pipe', 'pipe', 'pipe',
|
||||
/* Custom: pipe:3, pipe:4, pipe:5 */
|
||||
'pipe', 'pipe', 'pipe',
|
||||
],
|
||||
});
|
||||
|
||||
ffmpegProcess.stdio[1].pipe(res)
|
||||
|
||||
var audio = ytdl(url, { format: audioFormat || "audioonly" })
|
||||
audio.pipe(ffmpegProcess.stdio[4])
|
||||
|
||||
if (needsVideo) {
|
||||
var video = ytdl(url, { format: videoFormat || "videoonly" })
|
||||
video.pipe(ffmpegProcess.stdio[5])
|
||||
}
|
||||
|
||||
} else {
|
||||
res.send("Invalid URL!")
|
||||
}
|
||||
})
|
Loading…
Add table
Add a link
Reference in a new issue