Compare commits

..

4 commits

6 changed files with 67 additions and 63 deletions

View file

@ -129,13 +129,13 @@ async function download(url, interaction, originalInteraction) {
utils.downloadVideo(url, interaction.id, format) utils.downloadVideo(url, interaction.id, format)
.then(async () => { .then(async () => {
const file = fs.readdirSync(os.tmpdir()).filter(fn => fn.startsWith(interaction.id)); const file = fs.readdirSync(os.tmpdir()).filter(fn => fn.startsWith(interaction.id));
const output = `${os.tmpdir()}/${file}`; let output = `${os.tmpdir()}/${file}`;
const fileStat = fs.statSync(output); const fileStat = fs.statSync(output);
const fileSize = fileStat.size / 1000000.0; const fileSize = fileStat.size / 1000000.0;
const compressInteraction = originalInteraction ? originalInteraction : interaction; const compressInteraction = originalInteraction ? originalInteraction : interaction;
if (compressInteraction.doCompress) { if (compressInteraction.doCompress) {
const presets = [ 'Discord Tiny 5 Minutes 240p30', 'Discord Small 2 Minutes 360p30', 'Discord Nitro Small 10-20 Minutes 480p30', 'Discord Nitro Medium 5-10 Minutes 720p30', 'Discord Nitro Large 3-6 Minutes 1080p30' ]; const presets = [ 'Social 8 MB 3 Minutes 360p30', 'Social 50 MB 10 Minutes 480p30', 'Social 50 MB 5 Minutes 720p30', 'Social 100 MB 5 Minutes 1080p30' ];
const options = []; const options = [];
presets.forEach(p => { presets.forEach(p => {
@ -167,6 +167,17 @@ async function download(url, interaction, originalInteraction) {
return; return;
} }
// If the video format is not one compatible with Discord, reencode it.
const bannedFormats = ['hevc'];
const codec = await utils.getVideoCodec(output);
if (bannedFormats.includes(codec)) {
console.log('Reencoding video');
const oldOutput = output;
output = `${os.tmpdir()}/264${file}`;
await utils.ffmpeg(`-i ${oldOutput} -vcodec libx264 -acodec aac ${output}`);
}
if (fileSize > 100) { if (fileSize > 100) {
await interaction.deleteReply(); await interaction.deleteReply();
await interaction.followUp('Uh oh! The video you tried to download is too big!', { ephemeral: true }); await interaction.followUp('Uh oh! The video you tried to download is too big!', { ephemeral: true });
@ -194,6 +205,8 @@ async function download(url, interaction, originalInteraction) {
async function compress(input, interaction, embed) { async function compress(input, interaction, embed) {
const output = `compressed${input}.mp4`; const output = `compressed${input}.mp4`;
// Delete the file as it apparently don't overwrite?
fs.rmSync(output);
utils.compressVideo(`${os.tmpdir()}/${input}`, output, interaction.values[0]) utils.compressVideo(`${os.tmpdir()}/${input}`, output, interaction.values[0])
.then(async () => { .then(async () => {
const fileStat = fs.statSync(`${os.tmpdir()}/${output}`); const fileStat = fs.statSync(`${os.tmpdir()}/${output}`);

View file

@ -1,29 +0,0 @@
const fs = require('node:fs');
const https = require('node:https');
console.log('Downloading latest version of yt-dlp');
const downloadUrl = 'https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp';
download(downloadUrl);
function download(url) {
https.get(url, (res) => {
if (res.statusCode === 301 || res.statusCode === 302) {
console.log(`yt-dlp download url: ${res.headers.location}`);
return download(res.headers.location);
}
const path = './bin/yt-dlp';
const filePath = fs.createWriteStream(path);
res.pipe(filePath);
filePath.on('finish', () => {
filePath.close();
fs.chmodSync('./bin/yt-dlp', '755');
console.log('yt-dlp download finished.');
});
filePath.on('error', (err) => {
filePath.close();
console.error(err.message);
});
});
}

View file

@ -11,8 +11,8 @@ These instructions will get you a copy of the project up and running on your loc
You need to install the following You need to install the following
* ffmpeg (Optional but very recommanded: for yt-dlp to merge video/audio formats) * ffmpeg (Optional but very recommanded: for yt-dlp to merge video/audio formats and Handbrake to compress videos.)
* yt-dlp ([a file can download it for you](prereq.cjs)) * yt-dlp ([a file can download it for you](scripts/updateytdlp.js))
* HandBrakeCLI (For [download](commands/utility/download.js)) * HandBrakeCLI (For [download](commands/utility/download.js))
* gifsicle (For [vid2gif](commands/utility/vid2gif.js)) * gifsicle (For [vid2gif](commands/utility/vid2gif.js))
* gifki (For [vid2gif](commands/utility/vid2gif.js)) * gifki (For [vid2gif](commands/utility/vid2gif.js))

34
scripts/downloadutils.js Normal file
View file

@ -0,0 +1,34 @@
import fs from 'node:fs';
import https from 'node:https';
export default {
download,
};
async function download(url, output) {
return new Promise((resolve, reject) => {
https.get(url, (res) => {
if (res.statusCode === 301 || res.statusCode === 302) {
console.log(`${output} download url: ${res.headers.location}`);
return download(res.headers.location, output);
}
const path = output;
const tmpPath = `${output}.new`;
const filePath = fs.createWriteStream(tmpPath);
res.pipe(filePath);
filePath.on('finish', () => {
filePath.close();
fs.renameSync(tmpPath, path);
fs.chmodSync(path, '755');
console.log(`${url} download finished.`);
resolve(true);
});
filePath.on('error', (err) => {
filePath.close();
reject(err);
});
});
});
}

View file

@ -1,5 +1,4 @@
import fs from 'node:fs'; import utils from './downloadutils.js';
import https from 'node:https';
if (process.platform !== 'linux' && process.argv[2] !== '-f') { if (process.platform !== 'linux' && process.argv[2] !== '-f') {
console.error('This script only download the linux version of yt-dlp. If you want to download anyway try again with -f'); console.error('This script only download the linux version of yt-dlp. If you want to download anyway try again with -f');
@ -11,31 +10,4 @@ else if (process.platform !== 'linux' && process.argv[2] === '-f') {
const downloadUrl = 'https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp'; const downloadUrl = 'https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp';
download(downloadUrl); utils.download(downloadUrl, './bin/yt-dlp');
async function download(url) {
return new Promise((resolve, reject) => {
https.get(url, (res) => {
if (res.statusCode === 301 || res.statusCode === 302) {
console.log(`yt-dlp download url: ${res.headers.location}`);
return download(res.headers.location);
}
const tmpPath = './bin/yt-dlp.new';
const path = './bin/yt-dlp';
const filePath = fs.createWriteStream(tmpPath);
res.pipe(filePath);
filePath.on('finish', () => {
filePath.close();
fs.renameSync(tmpPath, path);
fs.chmodSync('./bin/yt-dlp', '755');
console.log('yt-dlp download finished.');
resolve(true);
});
filePath.on('error', (err) => {
filePath.close();
reject(err);
});
});
});
}

View file

@ -8,6 +8,7 @@ export default {
ffmpeg, ffmpeg,
stringIsAValidurl, stringIsAValidurl,
compressVideo, compressVideo,
getVideoCodec,
}; };
async function downloadVideo(urlArg, output, format = 'bestvideo*+bestaudio/best') { async function downloadVideo(urlArg, output, format = 'bestvideo*+bestaudio/best') {
await new Promise((resolve, reject) => { await new Promise((resolve, reject) => {
@ -77,3 +78,16 @@ async function compressVideo(input, output, preset) {
}); });
}); });
} }
async function getVideoCodec(input) {
return await new Promise((resolve, reject) => {
exec(`ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 ${input}`, (err, stdout, stderr) => {
if (err) {
reject(stderr);
}
if (stderr) {
console.error(stderr);
}
resolve(stdout.trim());
});
});
}