mirror of
https://github.com/Jerryplusy/rc-plugin.git
synced 2025-10-14 16:19:18 +00:00
🎈 pref: 通用化ytDlpHelper
This commit is contained in:
parent
009f50c516
commit
3b9efa2b04
@ -13,10 +13,13 @@ import {
|
|||||||
BILI_DEFAULT_INTRO_LEN_LIMIT,
|
BILI_DEFAULT_INTRO_LEN_LIMIT,
|
||||||
COMMON_USER_AGENT,
|
COMMON_USER_AGENT,
|
||||||
DIVIDING_LINE,
|
DIVIDING_LINE,
|
||||||
douyinTypeMap, DOWNLOAD_WAIT_DETECT_FILE_TIME,
|
douyinTypeMap,
|
||||||
HELP_DOC, MESSAGE_RECALL_TIME,
|
DOWNLOAD_WAIT_DETECT_FILE_TIME,
|
||||||
|
HELP_DOC,
|
||||||
|
MESSAGE_RECALL_TIME,
|
||||||
REDIS_YUNZAI_ISOVERSEA,
|
REDIS_YUNZAI_ISOVERSEA,
|
||||||
REDIS_YUNZAI_LAGRANGE, REDOS_YUNZAI_WHITELIST,
|
REDIS_YUNZAI_LAGRANGE,
|
||||||
|
REDOS_YUNZAI_WHITELIST,
|
||||||
SUMMARY_PROMPT,
|
SUMMARY_PROMPT,
|
||||||
transMap,
|
transMap,
|
||||||
TWITTER_BEARER_TOKEN,
|
TWITTER_BEARER_TOKEN,
|
||||||
@ -82,7 +85,7 @@ import { redisExistKey, redisGetKey, redisSetKey } from "../utils/redis-util.js"
|
|||||||
import { saveTDL, startTDL } from "../utils/tdl-util.js";
|
import { saveTDL, startTDL } from "../utils/tdl-util.js";
|
||||||
import Translate from "../utils/trans-strategy.js";
|
import Translate from "../utils/trans-strategy.js";
|
||||||
import { mid2id } from "../utils/weibo.js";
|
import { mid2id } from "../utils/weibo.js";
|
||||||
import { dy2b } from "../utils/yt-dlp-util.js";
|
import { ytDlpGetTilt, ytDlpHelper } from "../utils/yt-dlp-util.js";
|
||||||
import { textArrayToMakeForward } from "../utils/yunzai-util.js";
|
import { textArrayToMakeForward } from "../utils/yunzai-util.js";
|
||||||
|
|
||||||
export class tools extends plugin {
|
export class tools extends plugin {
|
||||||
@ -433,36 +436,14 @@ export class tools extends plugin {
|
|||||||
// 下载逻辑
|
// 下载逻辑
|
||||||
const path = this.getCurDownloadPath(e);
|
const path = this.getCurDownloadPath(e);
|
||||||
await checkAndRemoveFile(path + "/temp.mp4");
|
await checkAndRemoveFile(path + "/temp.mp4");
|
||||||
const title = execSync(`yt-dlp --get-title ${ cleanedTiktokUrl } ${ isOversea ? "" : `--proxy ${ this.myProxy }` }`)
|
const title = ytDlpGetTilt(url, isOversea, this.myProxy);
|
||||||
e.reply(`识别:TikTok,视频下载中请耐心等待 \n${ title }`);
|
e.reply(`识别:TikTok,视频下载中请耐心等待 \n${ title }`);
|
||||||
await this.tiktokHelper(path, cleanedTiktokUrl, isOversea);
|
await ytDlpHelper(path, cleanedTiktokUrl, isOversea, this.myProxy);
|
||||||
await this.sendVideoToUpload(e, `${ path }/temp.mp4`);
|
await this.sendVideoToUpload(e, `${ path }/temp.mp4`);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* yt-dlp for tiktok 工具
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
* @param path 下载路径
|
|
||||||
* @param url 下载链接
|
|
||||||
* @param isOversea 是否是海外用户
|
|
||||||
*/
|
|
||||||
async tiktokHelper(path, url, isOversea) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const command = `yt-dlp ${ isOversea ? "" : `--proxy ${ this.myProxy }` } -P ${ path } -o "temp.%(ext)s" ${ url }`;
|
|
||||||
exec(command, (error, stdout) => {
|
|
||||||
if (error) {
|
|
||||||
console.error(`Error executing command: ${ error }`);
|
|
||||||
reject(error);
|
|
||||||
} else {
|
|
||||||
console.log(`Command output: ${ stdout }`);
|
|
||||||
resolve(stdout);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 哔哩哔哩扫码登录
|
// 哔哩哔哩扫码登录
|
||||||
async biliScan(e) {
|
async biliScan(e) {
|
||||||
e.reply('R插件开源免责声明:\n您将通过扫码完成获取哔哩哔哩refresh_token以及ck。\n本Bot将不会保存您的登录状态。\n我方仅提供视频解析及相关B站内容服务,若您的账号封禁、被盗等处罚与我方无关。\n害怕风险请勿扫码 ~', { recallMsg: 180 });
|
e.reply('R插件开源免责声明:\n您将通过扫码完成获取哔哩哔哩refresh_token以及ck。\n本Bot将不会保存您的登录状态。\n我方仅提供视频解析及相关B站内容服务,若您的账号封禁、被盗等处罚与我方无关。\n害怕风险请勿扫码 ~', { recallMsg: 180 });
|
||||||
@ -585,7 +566,7 @@ export class tools extends plugin {
|
|||||||
// 拼接在线人数
|
// 拼接在线人数
|
||||||
const onlineTotal = await this.biliOnlineTotal(bvid, cid);
|
const onlineTotal = await this.biliOnlineTotal(bvid, cid);
|
||||||
// 格式化数据
|
// 格式化数据
|
||||||
const combineContent = `\n${ formatBiliInfo(dataProcessMap) }\n📝 简介:${ truncateString(filteredDesc, this.toolsConfig.biliIntroLenLimit || BILI_DEFAULT_INTRO_LEN_LIMIT) }\n🏄♂️️ 当前视频有 ${onlineTotal.total} 人在观看,其中 ${onlineTotal.count} 人在网页端观看`;
|
const combineContent = `\n${ formatBiliInfo(dataProcessMap) }\n📝 简介:${ truncateString(filteredDesc, this.toolsConfig.biliIntroLenLimit || BILI_DEFAULT_INTRO_LEN_LIMIT) }\n🏄♂️️ 当前视频有 ${ onlineTotal.total } 人在观看,其中 ${ onlineTotal.count } 人在网页端观看`;
|
||||||
let biliInfo = [`识别:哔哩哔哩:${ title }`, combineContent]
|
let biliInfo = [`识别:哔哩哔哩:${ title }`, combineContent]
|
||||||
// 总结
|
// 总结
|
||||||
const summary = await this.getBiliSummary(bvid, cid, owner.mid);
|
const summary = await this.getBiliSummary(bvid, cid, owner.mid);
|
||||||
@ -1367,9 +1348,9 @@ export class tools extends plugin {
|
|||||||
}
|
}
|
||||||
const path = this.getCurDownloadPath(e);
|
const path = this.getCurDownloadPath(e);
|
||||||
await checkAndRemoveFile(path + "/temp.mp4")
|
await checkAndRemoveFile(path + "/temp.mp4")
|
||||||
const title = execSync(`yt-dlp --get-title ${ url } ${ isOversea ? "" : `--proxy ${ this.myProxy }` }`)
|
const title = await ytDlpGetTilt(url, isOversea, this.myProxy);
|
||||||
e.reply(`识别:油管,视频下载中请耐心等待 \n${ title }`);
|
e.reply(`识别:油管,视频下载中请耐心等待 \n${ title }`);
|
||||||
await dy2b(path, url, isOversea, this.myProxy);
|
await ytDlpHelper(path, url, isOversea, this.myProxy, true);
|
||||||
this.sendVideoToUpload(e, `${ path }/temp.mp4`);
|
this.sendVideoToUpload(e, `${ path }/temp.mp4`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@ -1618,7 +1599,7 @@ export class tools extends plugin {
|
|||||||
// 找到音频文件
|
// 找到音频文件
|
||||||
const mediaFiles = await getMediaFilesAndOthers(musicPath);
|
const mediaFiles = await getMediaFilesAndOthers(musicPath);
|
||||||
for (let other of mediaFiles.others) {
|
for (let other of mediaFiles.others) {
|
||||||
await this.uploadGroupFile(e, `${musicPath}/${other}`);
|
await this.uploadGroupFile(e, `${ musicPath }/${ other }`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 计数
|
// 计数
|
||||||
@ -1754,7 +1735,7 @@ export class tools extends plugin {
|
|||||||
// 检查当前环境
|
// 检查当前环境
|
||||||
const isExistTdl = await checkToolInCurEnv("tdl");
|
const isExistTdl = await checkToolInCurEnv("tdl");
|
||||||
if (!isExistTdl) {
|
if (!isExistTdl) {
|
||||||
e.reply(`未检测到必要的环境,无法解析小飞机${HELP_DOC}`);
|
e.reply(`未检测到必要的环境,无法解析小飞机${ HELP_DOC }`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const url = urlRex.exec(e.msg)[0];
|
const url = urlRex.exec(e.msg)[0];
|
||||||
@ -1765,7 +1746,7 @@ export class tools extends plugin {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
e.reply(`识别:小飞机(学习版)`);
|
e.reply(`识别:小飞机(学习版)`);
|
||||||
const tgSavePath = `${this.getCurDownloadPath(e)}/tg`;
|
const tgSavePath = `${ this.getCurDownloadPath(e) }/tg`;
|
||||||
// 如果没有文件夹则创建
|
// 如果没有文件夹则创建
|
||||||
await mkdirIfNotExists(tgSavePath);
|
await mkdirIfNotExists(tgSavePath);
|
||||||
// 删除之前的文件
|
// 删除之前的文件
|
||||||
@ -1775,7 +1756,7 @@ export class tools extends plugin {
|
|||||||
const mediaFiles = await getMediaFilesAndOthers(tgSavePath);
|
const mediaFiles = await getMediaFilesAndOthers(tgSavePath);
|
||||||
if (mediaFiles.images.length > 0) {
|
if (mediaFiles.images.length > 0) {
|
||||||
const imagesData = mediaFiles.images.map(item => {
|
const imagesData = mediaFiles.images.map(item => {
|
||||||
const fileContent = fs.readFileSync(`${tgSavePath}/${item}`);
|
const fileContent = fs.readFileSync(`${ tgSavePath }/${ item }`);
|
||||||
return {
|
return {
|
||||||
message: segment.image(fileContent),
|
message: segment.image(fileContent),
|
||||||
nickname: e.sender.card || e.user_id,
|
nickname: e.sender.card || e.user_id,
|
||||||
@ -1785,7 +1766,7 @@ export class tools extends plugin {
|
|||||||
e.reply(await Bot.makeForwardMsg(imagesData), true, { recallMsg: MESSAGE_RECALL_TIME });
|
e.reply(await Bot.makeForwardMsg(imagesData), true, { recallMsg: MESSAGE_RECALL_TIME });
|
||||||
} else if (mediaFiles.videos.length > 0) {
|
} else if (mediaFiles.videos.length > 0) {
|
||||||
for (const item of mediaFiles.videos) {
|
for (const item of mediaFiles.videos) {
|
||||||
await this.sendVideoToUpload(e, `${tgSavePath}/${item}`);
|
await this.sendVideoToUpload(e, `${ tgSavePath }/${ item }`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (let other of mediaFiles.others) {
|
for (let other of mediaFiles.others) {
|
||||||
@ -2023,10 +2004,10 @@ export class tools extends plugin {
|
|||||||
|
|
||||||
// 构造aria2c命令参数
|
// 构造aria2c命令参数
|
||||||
const aria2cArgs = [
|
const aria2cArgs = [
|
||||||
`"${url}"`,
|
`"${ url }"`,
|
||||||
`--out="temp.mp4"`,
|
`--out="temp.mp4"`,
|
||||||
`--dir="${groupPath}"`,
|
`--dir="${ groupPath }"`,
|
||||||
`--user-agent="${userAgent}"`,
|
`--user-agent="${ userAgent }"`,
|
||||||
`--max-connection-per-server=${ numThreads }`, // 每个服务器的最大连接数
|
`--max-connection-per-server=${ numThreads }`, // 每个服务器的最大连接数
|
||||||
`--split=${ numThreads }`, // 分成 6 个部分进行下载
|
`--split=${ numThreads }`, // 分成 6 个部分进行下载
|
||||||
];
|
];
|
||||||
@ -2034,28 +2015,28 @@ export class tools extends plugin {
|
|||||||
// 如果有自定义头信息
|
// 如果有自定义头信息
|
||||||
if (headers) {
|
if (headers) {
|
||||||
for (const [key, value] of Object.entries(headers)) {
|
for (const [key, value] of Object.entries(headers)) {
|
||||||
aria2cArgs.push(`--header="${key}: ${value}"`);
|
aria2cArgs.push(`--header="${ key }: ${ value }"`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果使用代理
|
// 如果使用代理
|
||||||
if (proxyOption && proxyOption.httpAgent) {
|
if (proxyOption && proxyOption.httpAgent) {
|
||||||
const proxyUrl = proxyOption.httpAgent.proxy.href;
|
const proxyUrl = proxyOption.httpAgent.proxy.href;
|
||||||
aria2cArgs.push(`--all-proxy="${proxyUrl}"`);
|
aria2cArgs.push(`--all-proxy="${ proxyUrl }"`);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await checkAndRemoveFile(target);
|
await checkAndRemoveFile(target);
|
||||||
logger.mark(`开始下载: ${url}`);
|
logger.mark(`开始下载: ${ url }`);
|
||||||
|
|
||||||
// 执行aria2c命令
|
// 执行aria2c命令
|
||||||
const command = `aria2c ${aria2cArgs.join(' ')}`;
|
const command = `aria2c ${ aria2cArgs.join(' ') }`;
|
||||||
exec(command, (error, stdout, stderr) => {
|
exec(command, (error, stdout, stderr) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
logger.error(`下载视频发生错误!\ninfo:${stderr}`);
|
logger.error(`下载视频发生错误!\ninfo:${ stderr }`);
|
||||||
throw error;
|
throw error;
|
||||||
} else {
|
} else {
|
||||||
logger.mark(`下载完成: ${url}`);
|
logger.mark(`下载完成: ${ url }`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2078,7 +2059,7 @@ export class tools extends plugin {
|
|||||||
}, DOWNLOAD_WAIT_DETECT_FILE_TIME);
|
}, DOWNLOAD_WAIT_DETECT_FILE_TIME);
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(`下载视频发生错误!\ninfo:${err}`);
|
logger.error(`下载视频发生错误!\ninfo:${ err }`);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2094,38 +2075,38 @@ export class tools extends plugin {
|
|||||||
|
|
||||||
// 构造axel命令参数
|
// 构造axel命令参数
|
||||||
const axelArgs = [
|
const axelArgs = [
|
||||||
`-n ${numThreads}`,
|
`-n ${ numThreads }`,
|
||||||
`-o "${target}"`,
|
`-o "${ target }"`,
|
||||||
`-U "${userAgent}"`,
|
`-U "${ userAgent }"`,
|
||||||
url
|
url
|
||||||
];
|
];
|
||||||
|
|
||||||
// 如果有自定义头信息
|
// 如果有自定义头信息
|
||||||
if (headers) {
|
if (headers) {
|
||||||
for (const [key, value] of Object.entries(headers)) {
|
for (const [key, value] of Object.entries(headers)) {
|
||||||
axelArgs.push(`-H "${key}: ${value}"`);
|
axelArgs.push(`-H "${ key }: ${ value }"`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果使用代理
|
// 如果使用代理
|
||||||
if (proxyOption && proxyOption.httpAgent) {
|
if (proxyOption && proxyOption.httpAgent) {
|
||||||
const proxyUrl = proxyOption.httpAgent.proxy.href;
|
const proxyUrl = proxyOption.httpAgent.proxy.href;
|
||||||
axelArgs.push(`--proxy="${proxyUrl}"`);
|
axelArgs.push(`--proxy="${ proxyUrl }"`);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await checkAndRemoveFile(target);
|
await checkAndRemoveFile(target);
|
||||||
logger.mark(`开始下载: ${url}`);
|
logger.mark(`开始下载: ${ url }`);
|
||||||
|
|
||||||
|
|
||||||
// 执行axel命令
|
// 执行axel命令
|
||||||
const command = `axel ${axelArgs.join(' ')}`;
|
const command = `axel ${ axelArgs.join(' ') }`;
|
||||||
exec(command, (error, stdout, stderr) => {
|
exec(command, (error, stdout, stderr) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
logger.error(`下载视频发生错误!\ninfo:${stderr}`);
|
logger.error(`下载视频发生错误!\ninfo:${ stderr }`);
|
||||||
throw error;
|
throw error;
|
||||||
} else {
|
} else {
|
||||||
logger.mark(`下载完成: ${url}`);
|
logger.mark(`下载完成: ${ url }`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2138,7 +2119,7 @@ export class tools extends plugin {
|
|||||||
if (fs.existsSync(target)) {
|
if (fs.existsSync(target)) {
|
||||||
logger.info("[R插件][Axel] 检测到文件!");
|
logger.info("[R插件][Axel] 检测到文件!");
|
||||||
clearInterval(checkInterval);
|
clearInterval(checkInterval);
|
||||||
logger.info(`[R插件][Axel] 下载到${groupPath}`);
|
logger.info(`[R插件][Axel] 下载到${ groupPath }`);
|
||||||
resolve(groupPath);
|
resolve(groupPath);
|
||||||
}
|
}
|
||||||
if (count === 6) {
|
if (count === 6) {
|
||||||
@ -2149,7 +2130,7 @@ export class tools extends plugin {
|
|||||||
}, DOWNLOAD_WAIT_DETECT_FILE_TIME);
|
}, DOWNLOAD_WAIT_DETECT_FILE_TIME);
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(`下载视频发生错误!\ninfo:${err}`);
|
logger.error(`下载视频发生错误!\ninfo:${ err }`);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,46 @@
|
|||||||
import { exec } from "child_process";
|
import { exec, execSync } from "child_process";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* yt-dlp工具类
|
* 构建梯子参数
|
||||||
* @returns {Promise<void>}
|
* @param isOversea
|
||||||
* @param path 下载路径
|
* @param proxy
|
||||||
* @param url 下载链接
|
* @returns {string|string}
|
||||||
* @param isOversea 是否是海外用户
|
|
||||||
*/
|
*/
|
||||||
export async function dy2b(path, url, isOversea, proxy) {
|
function constructProxyParam(isOversea, proxy) {
|
||||||
|
return isOversea ? "" : `--proxy ${ proxy }`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取标题
|
||||||
|
* @param url
|
||||||
|
* @param isOversea
|
||||||
|
* @param proxy
|
||||||
|
* @returns string
|
||||||
|
*/
|
||||||
|
export function ytDlpGetTilt(url, isOversea, proxy) {
|
||||||
|
return execSync(`yt-dlp --get-title ${ constructProxyParam(isOversea, proxy) } ${ url }`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* yt-dlp 工具类
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
* @param path 下载路径
|
||||||
|
* @param url 下载链接
|
||||||
|
* @param isOversea 是否是海外用户
|
||||||
|
* @param proxy 代理地址
|
||||||
|
* @param merge 是否合并输出为 mp4 格式 (仅适用于视频合并需求)
|
||||||
|
*/
|
||||||
|
export async function ytDlpHelper(path, url, isOversea, proxy, merge = false) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const command = `yt-dlp ${ isOversea ? "" : `--proxy ${ proxy }` } -P ${ path } -o "temp.%(ext)s" --merge-output-format "mp4" ${ url }`;
|
const mergeOption = merge ? '--merge-output-format "mp4"' : '';
|
||||||
|
const command = `yt-dlp ${ constructProxyParam(isOversea, proxy) } -P ${ path } -o "temp.%(ext)s" ${ mergeOption } ${ url }`;
|
||||||
|
|
||||||
exec(command, (error, stdout) => {
|
exec(command, (error, stdout) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error(`Error executing command: ${ error }`);
|
console.error(`Error executing command: ${error}`);
|
||||||
reject(error);
|
reject(error);
|
||||||
} else {
|
} else {
|
||||||
console.log(`Command output: ${ stdout }`);
|
console.log(`Command output: ${stdout}`);
|
||||||
resolve(stdout);
|
resolve(stdout);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user