feat: 添加油管饼干选项,防止部分🪜无法解析 && 去除ws

This commit is contained in:
zhiyu1998 2024-11-06 16:45:24 +08:00
parent 21e8073559
commit a217370f61
5 changed files with 55 additions and 25 deletions

View File

@ -269,25 +269,27 @@ export class tools extends plugin {
// 加载 BBDown 的CDN配置 // 加载 BBDown 的CDN配置
this.biliCDN = this.toolsConfig.biliCDN; this.biliCDN = this.toolsConfig.biliCDN;
// 加载网易云Cookie // 加载网易云Cookie
this.neteaseCookie = this.toolsConfig.neteaseCookie this.neteaseCookie = this.toolsConfig.neteaseCookie;
// 加载是否转化群语音 // 加载是否转化群语音
this.isSendVocal = this.toolsConfig.isSendVocal this.isSendVocal = this.toolsConfig.isSendVocal;
// 加载是否自建服务器 // 加载是否自建服务器
this.useLocalNeteaseAPI = this.toolsConfig.useLocalNeteaseAPI this.useLocalNeteaseAPI = this.toolsConfig.useLocalNeteaseAPI;
// 加载自建服务器API // 加载自建服务器API
this.neteaseCloudAPIServer = this.toolsConfig.neteaseCloudAPIServer this.neteaseCloudAPIServer = this.toolsConfig.neteaseCloudAPIServer;
// 加载网易云解析最高音质 // 加载网易云解析最高音质
this.neteaseCloudAudioQuality = this.toolsConfig.neteaseCloudAudioQuality this.neteaseCloudAudioQuality = this.toolsConfig.neteaseCloudAudioQuality;
// 加载哔哩哔哩是否使用Aria2 // 加载哔哩哔哩是否使用Aria2
this.biliDownloadMethod = this.toolsConfig.biliDownloadMethod; this.biliDownloadMethod = this.toolsConfig.biliDownloadMethod;
// 加载哔哩哔哩最高分辨率 // 加载哔哩哔哩最高分辨率
this.biliResolution = this.toolsConfig.biliResolution; this.biliResolution = this.toolsConfig.biliResolution;
// 加载youtube的截取时长 // 加载youtube的截取时长
this.youtubeClipTime = this.toolsConfig.youtubeClipTime this.youtubeClipTime = this.toolsConfig.youtubeClipTime;
// 加载youtube的解析时长 // 加载youtube的解析时长
this.youtubeDuration = this.toolsConfig.youtubeDuration this.youtubeDuration = this.toolsConfig.youtubeDuration;
// 加载油管下载画质选项 // 加载油管下载画质选项
this.youtubeGraphicsOptions = this.toolsConfig.youtubeGraphicsOptions this.youtubeGraphicsOptions = this.toolsConfig.youtubeGraphicsOptions;
// 加载youtube的Cookie
this.youtubeCookiePath = this.toolsConfig.youtubeCookiePath;
// 加载抖音Cookie // 加载抖音Cookie
this.douyinCookie = this.toolsConfig.douyinCookie; this.douyinCookie = this.toolsConfig.douyinCookie;
// 加载抖音是否压缩 // 加载抖音是否压缩
@ -1981,8 +1983,8 @@ export class tools extends plugin {
await checkAndRemoveFile(path + "/temp.mp4") await checkAndRemoveFile(path + "/temp.mp4")
await checkAndRemoveFile(path + "/temp.mp3") await checkAndRemoveFile(path + "/temp.mp3")
await checkAndRemoveFile(path + "/thumbnail.png") await checkAndRemoveFile(path + "/thumbnail.png")
await ytDlpGetThumbnail(path, url, isOversea, this.myProxy) await ytDlpGetThumbnail(path, url, isOversea, this.myProxy, this.youtubeCookiePath)
const title = ytDlpGetTilt(url, isOversea, this.myProxy).toString().replace(/\n/g, ''); const title = ytDlpGetTilt(url, isOversea, this.myProxy, this.youtubeCookiePath).toString().replace(/\n/g, '');
// 音频逻辑 // 音频逻辑
if (url.includes("music")) { if (url.includes("music")) {
@ -1990,7 +1992,7 @@ export class tools extends plugin {
segment.image(`${path}/thumbnail.png`), segment.image(`${path}/thumbnail.png`),
`${this.identifyPrefix}识别:油管音乐\n视频标题:${title}` `${this.identifyPrefix}识别:油管音乐\n视频标题:${title}`
]); ]);
await ytDlpHelper(path, url, isOversea, this.myProxy, this.videoDownloadConcurrency, true, graphics, timeRange); await ytDlpHelper(path, url, isOversea, this.myProxy, this.videoDownloadConcurrency, true, graphics, timeRange, this.youtubeCookiePath);
e.reply(segment.record(`${ path }/temp.mp3`)); e.reply(segment.record(`${ path }/temp.mp3`));
this.uploadGroupFile(e, `${ path }/temp.mp3`); this.uploadGroupFile(e, `${ path }/temp.mp3`);
// 发送完就截断 // 发送完就截断
@ -2010,11 +2012,11 @@ export class tools extends plugin {
segment.image(`${path}/thumbnail.png`), segment.image(`${path}/thumbnail.png`),
`${this.identifyPrefix}识别:油管,视频截取中请耐心等待 \n视频标题:${title}\n✂️${DIVIDING_LINE.replace('{}', '截取说明').replace(/\n/g, '')}✂️\n视频时长:${(Duration / 60).toFixed(2).replace(/\.00$/, '')} 分钟\n大于管理员限定截取时长:${(this.youtubeClipTime / 60).toFixed(2).replace(/\.00$/, '')} 分钟\n将截取视频片段` `${this.identifyPrefix}识别:油管,视频截取中请耐心等待 \n视频标题:${title}\n✂️${DIVIDING_LINE.replace('{}', '截取说明').replace(/\n/g, '')}✂️\n视频时长:${(Duration / 60).toFixed(2).replace(/\.00$/, '')} 分钟\n大于管理员限定截取时长:${(this.youtubeClipTime / 60).toFixed(2).replace(/\.00$/, '')} 分钟\n将截取视频片段`
]); ]);
await ytDlpHelper(path, url, isOversea, this.myProxy, this.videoDownloadConcurrency, true, graphics, timeRange); await ytDlpHelper(path, url, isOversea, this.myProxy, this.videoDownloadConcurrency, true, graphics, timeRange, this.youtubeCookiePath);
this.sendVideoToUpload(e, `${path}/temp.mp4`); this.sendVideoToUpload(e, `${path}/temp.mp4`);
} else { } else {
e.reply([segment.image(`${path}/thumbnail.png`), `${this.identifyPrefix}识别:油管,视频下载中请耐心等待 \n视频标题:${title}\n视频时长:${(Duration / 60).toFixed(2).replace(/\.00$/, '')} 分钟`]); e.reply([segment.image(`${path}/thumbnail.png`), `${this.identifyPrefix}识别:油管,视频下载中请耐心等待 \n视频标题:${title}\n视频时长:${(Duration / 60).toFixed(2).replace(/\.00$/, '')} 分钟`]);
await ytDlpHelper(path, url, isOversea, this.myProxy, this.videoDownloadConcurrency, true, graphics, timeRange); await ytDlpHelper(path, url, isOversea, this.myProxy, this.videoDownloadConcurrency, true, graphics, timeRange, this.youtubeCookiePath);
this.sendVideoToUpload(e, `${path}/temp.mp4`); this.sendVideoToUpload(e, `${path}/temp.mp4`);
} }
} catch (error) { } catch (error) {

View File

@ -33,6 +33,7 @@ neteaseCloudAudioQuality: exhigh # 网易云解析最高音质 默认exhigh(极
youtubeGraphicsOptions: 720 # YouTobe的下载画质0为原画1080720480自定义画面高度默认为720 youtubeGraphicsOptions: 720 # YouTobe的下载画质0为原画1080720480自定义画面高度默认为720
youtubeClipTime: 0 # YouTobe限制的最大视频时长默认不开启单位秒 最好不要超过5分钟否则截取效率非常低 youtubeClipTime: 0 # YouTobe限制的最大视频时长默认不开启单位秒 最好不要超过5分钟否则截取效率非常低
youtubeDuration: 480 # YouTobe限制的最大视频时长默认8分钟单位秒 最好不要超过30分钟否则截取效率非常低 youtubeDuration: 480 # YouTobe限制的最大视频时长默认8分钟单位秒 最好不要超过30分钟否则截取效率非常低
youtubeCookiePath: '' # YouTobe的Cookie.txt所在的路径
douyinCookie: '' # douyin's cookie, 格式odin_tt=xxx;passport_fe_beating_status=xxx;sid_guard=xxx;uid_tt=xxx;uid_tt_ss=xxx;sid_tt=xxx;sessionid=xxx;sessionid_ss=xxx;sid_ucp_v1=xxx;ssid_ucp_v1=xxx;passport_assist_user=xxx;ttwid=xxx; douyinCookie: '' # douyin's cookie, 格式odin_tt=xxx;passport_fe_beating_status=xxx;sid_guard=xxx;uid_tt=xxx;uid_tt_ss=xxx;sid_tt=xxx;sessionid=xxx;sessionid_ss=xxx;sid_ucp_v1=xxx;ssid_ucp_v1=xxx;passport_assist_user=xxx;ttwid=xxx;
douyinCompression: true # true-压缩false-不压缩;是否使用压缩视频格式的抖音(默认使用),使用后加速视频发送 douyinCompression: true # true-压缩false-不压缩;是否使用压缩视频格式的抖音(默认使用),使用后加速视频发送

View File

@ -222,7 +222,7 @@ export function supportGuoba() {
}, },
{ {
field: "tools.youtubeDuration", field: "tools.youtubeDuration",
label: "YouTuBe最大解析时长", label: "油管最大解析时长",
bottomHelpMessage: bottomHelpMessage:
"超过时长不解析单位保护魔法的流量计算公式8分钟 x 60秒 = 480秒默认8分钟最好不超过30分钟", "超过时长不解析单位保护魔法的流量计算公式8分钟 x 60秒 = 480秒默认8分钟最好不超过30分钟",
component: "InputNumber", component: "InputNumber",
@ -233,7 +233,7 @@ export function supportGuoba() {
}, },
{ {
field: "tools.youtubeClipTime", field: "tools.youtubeClipTime",
label: "YouTuBe截取时长", label: "油管截取时长",
bottomHelpMessage: bottomHelpMessage:
"超过时长会截取指定时间单位保护魔法的流量计算公式3分钟 x 60秒 = 180秒默认不开启最好不超过5分钟,0表无限or不开启", "超过时长会截取指定时间单位保护魔法的流量计算公式3分钟 x 60秒 = 180秒默认不开启最好不超过5分钟,0表无限or不开启",
component: "InputNumber", component: "InputNumber",
@ -244,7 +244,7 @@ export function supportGuoba() {
}, },
{ {
field: "tools.youtubeGraphicsOptions", field: "tools.youtubeGraphicsOptions",
label: "YouTube最高分辨率", label: "油管最高分辨率",
bottomHelpMessage: bottomHelpMessage:
"油管下载的最高分辨率默认720p请根据自己魔法流量和服务器承载能力进行调整", "油管下载的最高分辨率默认720p请根据自己魔法流量和服务器承载能力进行调整",
component: "Select", component: "Select",
@ -252,6 +252,17 @@ export function supportGuoba() {
options: YOUTUBE_GRAPHICS_LIST, options: YOUTUBE_GRAPHICS_LIST,
} }
}, },
{
field: "tools.youtubeCookiePath",
label: "油管Cookie",
bottomHelpMessage:
"【!重要:这里填写的是路径,例如/path/to/cookies.txt】如果无法解析油管就填写这个Cookie",
component: "Input",
required: false,
componentProps: {
placeholder: "请输入Youtube Cookie所在的路径例如/path/to/cookies.txt",
},
},
{ {
field: "tools.useLocalNeteaseAPI", field: "tools.useLocalNeteaseAPI",
label: "使用自建网易云API", label: "使用自建网易云API",

View File

@ -5,7 +5,6 @@
"dependencies": { "dependencies": {
"axios": "^1.3.4", "axios": "^1.3.4",
"qrcode": "^1.5.3", "qrcode": "^1.5.3",
"p-queue": "^8.0.1", "p-queue": "^8.0.1"
"ws": "^8.17.0"
} }
} }

View File

@ -10,6 +10,17 @@ function constructProxyParam(isOversea, proxy) {
return isOversea ? "" : `--proxy ${proxy}`; return isOversea ? "" : `--proxy ${proxy}`;
} }
/**
* 构造cookie参数
* 目前只支持YouTube构造cookie否则就必须修改`url.includes("youtu")`
* @param url
* @param cookiePath
* @returns {string}
*/
function constructCookiePath(url, cookiePath) {
return (cookiePath !== "" && url.includes("youtu")) ? `--cookies ${ cookiePath }` : "";
}
/** /**
* 获取时长 * 获取时长
@ -27,10 +38,12 @@ export function ytDlpGetDuration(url, isOversea, proxy) {
* @param url * @param url
* @param isOversea * @param isOversea
* @param proxy * @param proxy
* @param cookiePath
* @returns string * @returns string
*/ */
export function ytDlpGetTilt(url, isOversea, proxy) { export function ytDlpGetTilt(url, isOversea, proxy, cookiePath = "") {
return execSync(`yt-dlp --get-title --skip-download ${constructProxyParam(isOversea, proxy)} ${url} --encoding utf8`); const cookieParam = constructCookiePath(url, cookiePath);
return execSync(`yt-dlp --get-title --skip-download ${cookieParam} ${ constructProxyParam(isOversea, proxy) } ${ url } --encoding utf8`);
} }
/** /**
@ -39,9 +52,11 @@ export function ytDlpGetTilt(url, isOversea, proxy) {
* @param url * @param url
* @param isOversea * @param isOversea
* @param proxy * @param proxy
* @param cookiePath
*/ */
export function ytDlpGetThumbnail(path, url, isOversea, proxy) { export function ytDlpGetThumbnail(path, url, isOversea, proxy, cookiePath= "") {
return execSync(`yt-dlp --write-thumbnail --convert-thumbnails png --skip-download ${constructProxyParam(isOversea, proxy)} ${url} -P ${path} -o "thumbnail.%(ext)s"`); const cookieParam = constructCookiePath(url, cookiePath);
return execSync(`yt-dlp --write-thumbnail --convert-thumbnails png --skip-download ${cookieParam} ${constructProxyParam(isOversea, proxy)} ${url} -P ${path} -o "thumbnail.%(ext)s"`);
} }
/** /**
@ -55,17 +70,19 @@ export function ytDlpGetThumbnail(path, url, isOversea, proxy) {
* @param graphics YouTube画质参数 * @param graphics YouTube画质参数
* @param timeRange 截取时间段 * @param timeRange 截取时间段
* @param maxThreads 最大并发 * @param maxThreads 最大并发
* @param cookiePath Cookie所在位置
*/ */
export async function ytDlpHelper(path, url, isOversea, proxy, maxThreads, merge = false, graphics, timeRange) { export async function ytDlpHelper(path, url, isOversea, proxy, maxThreads, merge = false, graphics, timeRange, cookiePath = "") {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let command = ""; let command = "";
const cookieParam = constructCookiePath(url, cookiePath);
if (url.includes("music")) { if (url.includes("music")) {
// e.g yt-dlp -x --audio-format mp3 https://youtu.be/5wEtefq9VzM -o test.mp3 // e.g yt-dlp -x --audio-format mp3 https://youtu.be/5wEtefq9VzM -o test.mp3
command = `yt-dlp -x --audio-format mp3 ${constructProxyParam(isOversea, proxy)} -P ${path} -o "temp.mp3" ${url}`; command = `yt-dlp -x --audio-format mp3 ${cookieParam} ${constructProxyParam(isOversea, proxy)} -P ${path} -o "temp.mp3" ${url}`;
} else { } else {
const fParam = url.includes("youtu") ? `--download-sections "*${timeRange}" -f "bv${graphics}[ext=mp4]+ba[ext=m4a]" ` : ""; const fParam = url.includes("youtu") ? `--download-sections "*${timeRange}" -f "bv${graphics}[ext=mp4]+ba[ext=m4a]" ` : "";
command = `yt-dlp -N ${maxThreads} ${fParam} --concurrent-fragments ${maxThreads} ${constructProxyParam(isOversea, proxy)} -P ${path} -o "temp.%(ext)s" ${url}`; command = `yt-dlp -N ${maxThreads} ${fParam} --concurrent-fragments ${maxThreads} ${cookieParam} ${constructProxyParam(isOversea, proxy)} -P ${path} -o "temp.%(ext)s" ${url}`;
} }
logger.info(`[R插件][yt-dlp审计] ${command}`); logger.info(`[R插件][yt-dlp审计] ${command}`);