Backend can kick off downloads without using deprecated node-youtube-dl library

Downloads can now be cancelled and better "paused"
This commit is contained in:
Isaac Abadi
2023-09-05 00:35:36 -04:00
parent 3fc1110fc1
commit ea43ea7121
9 changed files with 105 additions and 26 deletions

View File

@@ -1,5 +1,7 @@
const fs = require('fs-extra');
const fetch = require('node-fetch');
const execa = require('execa');
const kill = require('tree-kill');
const logger = require('./logger');
const utils = require('./utils');
@@ -24,7 +26,20 @@ exports.youtubedl_forks = {
}
}
exports.runYoutubeDL = async (url, args, downloadMethod = youtubedl.exec) => {
exports.runYoutubeDL = async (url, args, downloadMethod = null) => {
let callback = null;
let child_process = null;
if (downloadMethod) {
callback = exports.runYoutubeDLMain(url, args, downloadMethod);
} else {
({callback, child_process} = await runYoutubeDLProcess(url, args));
}
return {child_process, callback};
}
// Run youtube-dl in a main thread (with possible downloadMethod)
exports.runYoutubeDLMain = async (url, args, downloadMethod = youtubedl.exec) => {
return new Promise(resolve => {
downloadMethod(url, args, {maxBuffer: Infinity}, async function(err, output) {
const parsed_output = utils.parseOutputJSON(output, err);
@@ -33,6 +48,30 @@ exports.runYoutubeDL = async (url, args, downloadMethod = youtubedl.exec) => {
});
}
// Run youtube-dl in a subprocess
const runYoutubeDLProcess = async (url, args) => {
const child_process = execa(await getYoutubeDLPath(), [url, ...args], {maxBuffer: Infinity});
const callback = new Promise(async resolve => {
try {
const {stdout, stderr} = await child_process;
const parsed_output = utils.parseOutputJSON(stdout.trim().split(/\r?\n/), stderr);
resolve({parsed_output, err: stderr});
} catch (e) {
resolve({parsed_output: null, err: e})
}
});
return {child_process, callback}
}
async function getYoutubeDLPath() {
const guessed_base_path = 'node_modules/youtube-dl/bin/';
return guessed_base_path + 'youtube-dl' + (is_windows ? '.exe' : '');
}
exports.killYoutubeDLProcess = async (child_process) => {
kill(child_process.pid, 'SIGKILL');
}
exports.checkForYoutubeDLUpdate = async () => {
const default_downloader = config_api.getConfigItem('ytdl_default_downloader');
// get current version