const ytdl = require('ytdl-core'), fs = require('fs'), path = require('path'), express = require('express'), bodyParser = require('body-parser'), cp = require("child_process"), ffmpeg = require('ffmpeg-static'), multer = require('multer') const PORT = process.env.PORT || 8080 const app = express() var formats = { "matroska": "mkv" } if (fs.existsSync(path.join(__dirname, 'uploads'))) { fs.rmSync(path.join(__dirname, 'uploads'), { recursive: true }) } var uploads = multer({ dest: 'uploads/' }) const characters = "abcdefghijklmnopqrstuvwxyz!@$%^*()[]_-=+ " // process.on('uncaughtException', (err, origin) => { // fs.writeSync( // process.stderr.fd, // `Caught exception: ${err}\n` + // `Exception origin: ${origin}`, // ); // }); app.use(bodyParser.urlencoded({ extended: false })) app.post("/convert", uploads.single("files"), (req, res) => { var file = req.file var format = req.body.format || 'mp4' const ffmpegProcess = cp.spawn(ffmpeg, [ '-i', file.path, '-f', format, '-loglevel', 'error', '-movflags', 'frag_keyframe+empty_moov', '-vcodec', 'copy' , '-' ], { stdio: [ 'pipe', 'pipe', 'pipe', 'pipe', 'pipe', ], }) res.setHeader('Content-Disposition', `attachment; filename="${file.originalname.substring(0, file.originalname.lastIndexOf('.'))}.${formats[format] || format}"`); ffmpegProcess.stdio[1].pipe(res) .on("close", () => { fs.rmSync(file.path) }) }) app.get("/download", async (req, res) => { const url = req.query.url const format = req.query.format || 'mp4' const quality = req.query.quality || 'highest' const defin = req.query.definition || 'hd' const preset = 'medium' res.setHeader("X-Accel-Buffering", "no") if (!ytdl.validateURL(url)) { res.header("Content-Type", "text/html") res.write(``) res.write(`

Invalid URL! Check the url for any errors!
URL: ${url}

`) return } var vidinfo = await ytdl.getBasicInfo(url) const ogname = vidinfo.videoDetails.title var filename = "" for (let index = 0; index < ogname.length; index++) { const letter = ogname[index]; if ((characters + characters.toUpperCase()).includes(letter)) { filename += letter } } if ("mp3 ogg wav".includes(format)) { var audio = ytdl(url, { filter: 'audioonly', quality: quality }) const ffmpegProcess = cp.spawn(ffmpeg, [ '-i', `pipe:3`, '-c:v', 'copy', '-c:a', 'libmp3lame', '-preset', preset, '-f', format, '-loglevel', 'error', '-' ], { stdio: [ 'pipe', 'pipe', 'pipe', 'pipe', 'pipe', ], }) audio.pipe(ffmpegProcess.stdio[3]) res.setHeader('Content-Disposition', `attachment; filename="${filename}.${formats[format] || format}"`); ffmpegProcess.stdio[1].pipe(res) } else if (defin == "hd") { var video = ytdl(url, { filter: 'videoonly', quality: quality }) var audio = ytdl(url, { filter: 'audioonly', highWaterMark: 1 << 25 }) const ffmpegProcess = cp.spawn(ffmpeg, [ '-i', `pipe:3`, '-i', `pipe:4`, '-map', '0:v', '-map', '1:a', '-c:v', 'copy', '-c:a', 'libmp3lame', '-crf', '27', '-preset', preset, '-movflags', 'frag_keyframe+empty_moov', '-f', format, '-loglevel', 'error', '-map_metadata', '0', '-' ], { stdio: [ 'pipe', 'pipe', 'pipe', 'pipe', 'pipe', ], }) video.pipe(ffmpegProcess.stdio[3]) audio.pipe(ffmpegProcess.stdio[4]) res.setHeader('Content-Disposition', `attachment; filename="${filename}.${formats[format] || format}"`); ffmpegProcess.stdio[1].pipe(res) } else { if (format != 'mp4') { var video = ytdl(url, { filter: 'videoandaudio', quality: quality, highWaterMark: 1 << 25 }) const ffmpegProcess = cp.spawn(ffmpeg, [ '-i', `pipe:3`, '-preset', preset, '-f', format, '-loglevel', 'error', '-c:v', 'copy', '-c:a', 'libmp3lame', '-movflags', 'frag_keyframe+empty_moov', '-map_metadata', '0', '-' ], { stdio: [ 'pipe', 'pipe', 'pipe', 'pipe', 'pipe', ], }) video.pipe(ffmpegProcess.stdio[3]) res.setHeader('Content-Disposition', `attachment; filename="${filename}.${formats[format] || format}"`); // res.setHeader('Content-Length', fs.readFileSync(dest).length) ffmpegProcess.stdio[1].pipe(res) } else { var video = ytdl(url, { filter: 'videoandaudio', quality: quality, highWaterMark: 1 << 25 }) res.setHeader('Content-Disposition', `attachment; filename="${filename}.${formats[format] || format}"`); video.pipe(res) } } }) app.use(express.static(path.join(__dirname, 'static'))) app.listen(PORT, function () { console.log("Hosted on port " + PORT) })