diff --git a/apps/tools.js b/apps/tools.js index 01d38c6..aee0b16 100644 --- a/apps/tools.js +++ b/apps/tools.js @@ -1807,6 +1807,7 @@ export class tools extends plugin { }), 1000, ), + this.biliUseAria2 ), downloadBFile( audioUrl, @@ -1818,9 +1819,10 @@ export class tools extends plugin { }), 1000, ), + this.biliUseAria2 ), ]).then(data => { - return mergeFileToMp4(data[0].fullFileName, data[1].fullFileName, `${title}.mp4`); + return mergeFileToMp4(data[0].fullFileName, data[1].fullFileName, `${ title }.mp4`); }); } diff --git a/guoba.support.js b/guoba.support.js index d075070..7ffd87a 100644 --- a/guoba.support.js +++ b/guoba.support.js @@ -133,7 +133,7 @@ export function supportGuoba() { field: "tools.biliUseAria2", label: "使用Aria2下载", bottomHelpMessage: - "【默认不开启,目前只有开启BBDown后才有效果】如果不爱折腾就使用默认下载方式,如果喜欢折腾就开启,开启后更加强劲,宽带直接拉满,Debian和Ubuntu用户直接使用命令安装:apt-get install aria2", + "【默认不开启】如果不爱折腾就使用默认下载方式,如果喜欢折腾就开启,开启后更加强劲,宽带直接拉满,Debian和Ubuntu用户直接使用命令安装:apt-get install aria2", component: "Switch", required: false, }, diff --git a/utils/bilibili.js b/utils/bilibili.js index e171ebd..8e57caf 100644 --- a/utils/bilibili.js +++ b/utils/bilibili.js @@ -11,6 +11,7 @@ import { BILI_VIDEO_INFO } from "../constants/tools.js"; import { mkdirIfNotExists } from "./file.js"; +import { spawn } from 'child_process'; import qrcode from "qrcode" const biliHeaders = { @@ -24,9 +25,25 @@ const biliHeaders = { * @param url * @param fullFileName * @param progressCallback + * @param isAria2 * @returns {Promise} */ -export async function downloadBFile(url, fullFileName, progressCallback) { +export async function downloadBFile(url, fullFileName, progressCallback, isAria2 = false) { + if (isAria2) { + return aria2DownloadBFile(url, fullFileName, progressCallback); + } else { + return normalDownloadBFile(url, fullFileName, progressCallback); + } +} + +/** + * 正常下载 + * @param url + * @param fullFileName + * @param progressCallback + * @returns {Promise} + */ +async function normalDownloadBFile(url, fullFileName, progressCallback) { return axios .get(url, { responseType: 'stream', @@ -56,6 +73,60 @@ export async function downloadBFile(url, fullFileName, progressCallback) { }); } +/** + * 使用Aria2下载 + * @param url + * @param fullFileName + * @param progressCallback + * @returns {Promise} + */ +async function aria2DownloadBFile(url, fullFileName, progressCallback) { + return new Promise((resolve, reject) => { + logger.info(`[R插件][Aria2下载] 正在使用Aria2进行下载!`); + // 构建aria2c命令 + const aria2cArgs = [ + '--file-allocation=none', // 避免预分配文件空间 + '--continue', // 启用暂停支持 + '-o', fullFileName, // 指定输出文件名 + '--console-log-level=warn', // 减少日志 verbosity + '--download-result=hide', // 隐藏下载结果概要 + '--header', 'referer: https://www.bilibili.com', // 添加自定义标头 + url + ]; + + // Spawn aria2c 进程 + const aria2c = spawn('aria2c', aria2cArgs); + + let totalLen = 0; + let currentLen = 0; + + // 处理aria2c标准输出数据以捕获进度(可选) + aria2c.stdout.on('data', (data) => { + const output = data.toString(); + const match = output.match(/\((\d+)\s*\/\s*(\d+)\)/); + if (match) { + currentLen = parseInt(match[1], 10); + totalLen = parseInt(match[2], 10); + progressCallback?.(currentLen / totalLen); + } + }); + + // 处理aria2c的stderr以捕获错误 + aria2c.stderr.on('data', (data) => { + console.error(`aria2c error: ${data}`); + }); + + // 处理进程退出 + aria2c.on('close', (code) => { + if (code === 0) { + resolve({ fullFileName, totalLen }); + } else { + reject(new Error(`aria2c exited with code ${code}`)); + } + }); + }); +} + /** * 获取下载链接 * @param url