diff --git a/routes/index.js b/routes/index.js index 6ccb6ec..df0096d 100644 --- a/routes/index.js +++ b/routes/index.js @@ -80,12 +80,39 @@ router.get('/', function(req, res, next) { router.get('/status/:uuid', function (req, res ,next) { let uuid = req.params.uuid; if (progress[uuid]) { - res.send(progress[uuid]); + return res.send(progress[uuid]); } else { - res.send(undefined); + return res.send(undefined); } }); +router.get('/format', function (req, res ,next) { + let url; + let i = 0; + try { + url = new URL(req.query.url); + } catch (e) { + return res.send(undefined); + } + + let formats = []; + + youtubedl.exec(url.href, ['--dump-json'], {}, function(err, output) { + if (err) throw err + let json = JSON.parse(output); + json.formats.forEach(format => { + if (format.vcodec === 'none' || format.acodec === 'none') + return; + + i++; + formats.push({ext: format.ext, id: format.format_id, note: format.format_note}); + }); + + return res.send(formats); + }); + return; +}); + router.post('/', async function(req, res, next) { let data; const form = formidable({ multiples: true}); @@ -99,22 +126,17 @@ router.post('/', async function(req, res, next) { }) }); - - console.log(data.url); if (data.url === undefined) { //res.render('index', { error: true, errormsg: 'You didn\'t input a link'}) return res.send('You didn\'t input a link') } - let quality; - if (data.quality === 'worst') { - quality = 'worst'; - } else { - quality = 'best'; - } + console.log(data.format); - if (data.format === undefined) { - data.format = 'mp4'; + let format = data.format; + + if (data.format === undefined || data.format === 'mp3' || data.format === 'flac') { + format = 'best'; } if (data.url.toLowerCase().includes('porn')) { @@ -132,7 +154,7 @@ router.post('/', async function(req, res, next) { } } - let options = ['--format=mp4', '-f', quality]; + let options = ['-f', format]; if (data.proxy !== 'none') { options.push('--proxy'); options.push(data.proxy); @@ -182,7 +204,28 @@ router.post('/', async function(req, res, next) { video.on('end', function() { progress[data.uuid] = 0; - if (data.format === 'mp4' || data.format === 'webm') { + + if (data.format === 'mp3' || data.format === 'flac') { + // If user requested an audio format, convert it + ffmpeg(`./public/uploads/${DLFile}`) + .noVideo() + .audioChannels('2') + .audioFrequency('44100') + .audioBitrate('320k') + .format(data.format) + .save(`./public/uploads/${DLFile.replace(`.${ext}`, `.${data.format}`)}`) + .on('error', function(err, stdout, stderr) { + console.log('Cannot process video: ' + err.message); + return res.json({error: err.message}); + //return res.render('index', { error: true, errormsg: err.message}) + }) + .on('end', () => { + fs.unlinkSync(`./public/uploads/${DLFile}`); + if (data.feed !== 'on') generateWaveform(DLFile.replace(`.${ext}`, `.${data.format}`)); + return res.json({url: `uploads/${DLFile.replace(`.${ext}`, `.${data.format}`)}`}); + //return res.attachment(`./public/uploads/${DLFile.replace(`.${ext}`, `.${data.format}`)}`); + }); + } else { if (data.sponsorBlock) { // WARNING: THIS PART SUCK let filter = ''; let abc = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']; @@ -246,26 +289,6 @@ router.post('/', async function(req, res, next) { res.json({url: `uploads/${DLFile}`}) if (data.feed !== 'on') generateThumbnail(DLFile); } - } else { - // If user requested an audio format, convert it - ffmpeg(`./public/uploads/${DLFile}`) - .noVideo() - .audioChannels('2') - .audioFrequency('44100') - .audioBitrate('320k') - .format(data.format) - .save(`./public/uploads/${DLFile.replace(`.${ext}`, `.${data.format}`)}`) - .on('error', function(err, stdout, stderr) { - console.log('Cannot process video: ' + err.message); - return res.json({error: err.message}); - //return res.render('index', { error: true, errormsg: err.message}) - }) - .on('end', () => { - fs.unlinkSync(`./public/uploads/${DLFile}`); - if (data.feed !== 'on') generateWaveform(DLFile.replace(`.${ext}`, `.${data.format}`)); - return res.json({url: `uploads/${DLFile.replace(`.${ext}`, `.${data.format}`)}`}); - //return res.attachment(`./public/uploads/${DLFile.replace(`.${ext}`, `.${data.format}`)}`); - }); } }); diff --git a/views/index.ejs b/views/index.ejs index 104a530..55991ef 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -4,7 +4,7 @@ I guess have fun looking at the html, no easter egg to find here. Come take a look here https://git.namejeff.xyz/Supositware/jeff-downloader for all my bad coding --> <!DOCTYPE html> -<html class="gradientBG" lang="en"> +<html class="has-background-grey-dark" lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> @@ -24,20 +24,8 @@ Come take a look here https://git.namejeff.xyz/Supositware/jeff-downloader for a <title>Le epic video downloader v<%= version %></title> </head> <body class="has-text-light gradientBG"> - <ul class="circles"> - <li></li> - <li></li> - <li></li> - <li></li> - <li></li> - <li></li> - <li></li> - <li></li> - <li></li> - <li></li> - </ul> <section class="section has-text-centered"> - <div class="container "> + <div class="container"> <h1 class="title has-text-light">Le epic downloader v<%= version %></h1> <div class="downloader form"> <form id="download-form" method="POST" action="/" enctype="application/x-www-form-urlencoded"> @@ -45,21 +33,6 @@ Come take a look here https://git.namejeff.xyz/Supositware/jeff-downloader for a <div class="field-body"> <div class="field is-horizontal"> <div class="control"> - <label class="radio" for="small"> - <input class="radio" type="radio" name="quality" id="small" value="small"> - Low quality - </label> - - <label class="radio" for="high"> - <input class="radio" type="radio" name="quality" id="high" value="high" checked> - High quality - </label> - - <label class="checkbox" for="alt"> - <input class="checkbox" type="checkbox" name="alt" id="alt" title="Use this if download dosen't work"> - Alternate download - </label> - <label class="checkbox" for="feed"> <input class="checkbox" type="checkbox" name="feed" id="feed" title="Use this if you don't want the video you are downloading to be public"> Hide from feed @@ -78,8 +51,17 @@ Come take a look here https://git.namejeff.xyz/Supositware/jeff-downloader for a <div class="field-body"> <div class="field is-expanded"> <div class="field has-addons"> + <p class="control"> + <div class="select"> + <select name="format" id="format"> + <option value="mp4">MP4</option> + <option value="mp3">MP3</option> + <option value="flac">FLAC</option> + </select> + </div> + </p> <p class="control is-expanded"> - <input type="text" id="url" name="url" class="downloadurl input is-rounded" placeholder="Link"> + <input type="text" id="url" name="url" class="downloadurl input is-rounded" placeholder="Link" onkeyup="CheckFormat()"> </p> <p class="control"> <button type="submit" class="downloadbtn button is-primary is-rounded" id="button">Download that mf video</button> @@ -97,25 +79,7 @@ Come take a look here https://git.namejeff.xyz/Supositware/jeff-downloader for a </div> <div class="field is-horizontal level"> - - <div class="control level-left"> - <label class="radio" for="mp4"> - <input class="radio" type="radio" name="format" value="mp4" id="mp4" checked> - Video? - </label> - - <label class="radio" for="mp3"> - <input class="radio" type="radio" name="format" value="mp3" id="mp3"> - MP3? - </label> - - <label class="radio" for="flac" title="This is pure placebo"> - <input class="radio" type="radio" name="format" value="flac" id="flac" title="This is pure placebo"> - FLAC? - </label> - </div> - - <div class="field-body level-right"> + <div class="field-body"> <div class="field is-horizontal"> <div class="control"> <span>Proxy options:</span> @@ -216,13 +180,11 @@ Come take a look here https://git.namejeff.xyz/Supositware/jeff-downloader for a document.getElementById('progress').innerHTML = '<progress class="progress is-success" id="progress-bar" max="100">0%</progress>'; let frm = new FormData(form); frm.append('uuid', uuid); - console.log(...frm); let xhttp = new XMLHttpRequest(); - console.log('hi'); let progress = setInterval(() => { CheckProgress(); - }, 1000); + }, 2000); xhttp.addEventListener("load", function(event) { const json = JSON.parse(event.target.responseText); @@ -280,6 +242,43 @@ Come take a look here https://git.namejeff.xyz/Supositware/jeff-downloader for a }); } + function CheckFormat() { + let url; + try { + url = new URL(document.getElementById("url").value); + } catch (e) { + return; + } + + document.getElementsByClassName("select")[0].className = "select is-loading"; + + console.log(encodeURI(url.href)); + let xhttp = new XMLHttpRequest(); + xhttp.open("get", `/format?url=${url.href}`, true); + xhttp.send(); + xhttp.addEventListener("load", function(event) { + console.log(event.target.responseText); + + let html = []; + + let json = JSON.parse(event.target.responseText); + json.forEach(format => { + html.push(`<option value="${format.id}">${format.ext} - ${format.note}</option>`); + }); + + html.reverse(); + html.push('<option value="mp3">MP3</option>'); + html.push('<option value="flac">FLAC</option>'); + + document.getElementById("format").innerHTML = html; + document.getElementsByClassName("select")[0].className = "select"; + }); + + xhttp.addEventListener("error", function(event) { + console.error(event.target.responseText); + }); + } + function uuidv4() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);