mirror of
https://github.com/Jerryplusy/rc-plugin.git
synced 2025-10-14 08:09:19 +00:00
🎈 perf: V1.3.2 优化油管解析性能
1. 优化了寻找最佳解析分辨率的算法 2. 优化“魔法值”,增加后期可维护性 3. 说明 X 的不可维护性
This commit is contained in:
parent
9769dce7a4
commit
4046905c83
@ -113,6 +113,9 @@ chmod a+rx ~/.local/bin/yt-dlp
|
|||||||
|
|
||||||
<img src="./img/douyin_cookie.webp" alt="小程序解析" width="50%" height="50%" />
|
<img src="./img/douyin_cookie.webp" alt="小程序解析" width="50%" height="50%" />
|
||||||
|
|
||||||
|
### ✖️ 小蓝鸟问题
|
||||||
|
**2024-2-5**,修复小蓝鸟的时候看到free计划已经[没有给查看Tweet的api](https://developer.twitter.com/en/portal/products/basic),原先[使用的库也出现了403报错](https://github.com/PLhery/node-twitter-api-v2),开通会员要100美元,不值得。目前暂停更新,后续有方案和精力再更新!
|
||||||
|
|
||||||
## 🤺 R插件交流群
|
## 🤺 R插件交流群
|
||||||
扫码不行就:575663150
|
扫码不行就:575663150
|
||||||
|
|
||||||
@ -161,7 +164,9 @@ chmod a+rx ~/.local/bin/yt-dlp
|
|||||||
* [x0rz4](https://gitee.com/x0rz4) 提供依赖掉包解决方案
|
* [x0rz4](https://gitee.com/x0rz4) 提供依赖掉包解决方案
|
||||||
|
|
||||||
感谢以下框架的开源:
|
感谢以下框架的开源:
|
||||||
YouTube解析参考了:[yt-dlp:A youtube-dl fork with additional features and fixes](https://github.com/yt-dlp/yt-dlp)
|
|
||||||
|
YouTube解析参考了:
|
||||||
|
- [yt-dlp:A youtube-dl fork with additional features and fixes](https://github.com/yt-dlp/yt-dlp)
|
||||||
|
|
||||||
## ☕ 请我喝一杯瑞幸咖啡
|
## ☕ 请我喝一杯瑞幸咖啡
|
||||||
如果你觉得插件能帮助到你增进好友关系,那么你可以在有条件的情况下[请我喝一杯瑞幸咖啡](https://afdian.net/a/zhiyu1998),这是我开源这个插件的最大动力!
|
如果你觉得插件能帮助到你增进好友关系,那么你可以在有条件的情况下[请我喝一杯瑞幸咖啡](https://afdian.net/a/zhiyu1998),这是我开源这个插件的最大动力!
|
||||||
|
137
apps/tools.js
137
apps/tools.js
@ -16,6 +16,7 @@ import {
|
|||||||
DIVIDING_LINE,
|
DIVIDING_LINE,
|
||||||
XHS_NO_WATERMARK_HEADER,
|
XHS_NO_WATERMARK_HEADER,
|
||||||
REDIS_YUNZAI_ISOVERSEA,
|
REDIS_YUNZAI_ISOVERSEA,
|
||||||
|
TWITTER_BEARER_TOKEN,
|
||||||
} from "../constants/constant.js";
|
} from "../constants/constant.js";
|
||||||
import { containsChinese, formatBiliInfo, getIdVideo, secondsToTime } from "../utils/common.js";
|
import { containsChinese, formatBiliInfo, getIdVideo, secondsToTime } from "../utils/common.js";
|
||||||
import config from "../model/index.js";
|
import config from "../model/index.js";
|
||||||
@ -27,8 +28,8 @@ import { av2BV } from "../utils/bilibili-bv-av-convert.js";
|
|||||||
import querystring from "querystring";
|
import querystring from "querystring";
|
||||||
import TokenBucket from "../utils/token-bucket.js";
|
import TokenBucket from "../utils/token-bucket.js";
|
||||||
import { getWbi } from "../utils/biliWbi.js";
|
import { getWbi } from "../utils/biliWbi.js";
|
||||||
import { BILI_SUMMARY } from "../constants/bili.js";
|
import { BILI_SUMMARY, DY_INFO, TIKTOK_INFO, TWITTER_TWEET_INFO, XHS_REQ_LINK } from "../constants/tools.js";
|
||||||
import { XHS_VIDEO } from "../constants/xhs.js";
|
import { XHS_VIDEO } from "../constants/tools.js";
|
||||||
import child_process from 'node:child_process'
|
import child_process from 'node:child_process'
|
||||||
import { getAudio, getVideo } from "../utils/y2b.js";
|
import { getAudio, getVideo } from "../utils/y2b.js";
|
||||||
import { processTikTokUrl } from "../utils/tiktok.js";
|
import { processTikTokUrl } from "../utils/tiktok.js";
|
||||||
@ -168,7 +169,7 @@ export class tools extends plugin {
|
|||||||
Referer: "https://www.douyin.com/",
|
Referer: "https://www.douyin.com/",
|
||||||
cookie: this.douyinCookie,
|
cookie: this.douyinCookie,
|
||||||
};
|
};
|
||||||
const dyApi = `https://www.douyin.com/aweme/v1/web/aweme/detail/?device_platform=webapp&aid=6383&channel=channel_pc_web&aweme_id=${ douId }&pc_client_type=1&version_code=190500&version_name=19.5.0&cookie_enabled=true&screen_width=1344&screen_height=756&browser_language=zh-CN&browser_platform=Win32&browser_name=Firefox&browser_version=118.0&browser_online=true&engine_name=Gecko&engine_version=109.0&os_name=Windows&os_version=10&cpu_core_num=16&device_memory=&platform=PC&webid=7284189800734082615&msToken=B1N9FM825TkvFbayDsDvZxM8r5suLrsfQbC93TciS0O9Iii8iJpAPd__FM2rpLUJi5xtMencSXLeNn8xmOS9q7bP0CUsrt9oVTL08YXLPRzZm0dHKLc9PGRlyEk=`;
|
const dyApi = DY_INFO.replace("{}", douId);
|
||||||
// xg参数
|
// xg参数
|
||||||
const xbParam = xBogus.sign(
|
const xbParam = xBogus.sign(
|
||||||
new URLSearchParams(new URL(dyApi).search).toString(),
|
new URLSearchParams(new URL(dyApi).search).toString(),
|
||||||
@ -236,7 +237,7 @@ export class tools extends plugin {
|
|||||||
let tiktokVideoId = await getIdVideo(url);
|
let tiktokVideoId = await getIdVideo(url);
|
||||||
tiktokVideoId = tiktokVideoId.replace(/\//g, "");
|
tiktokVideoId = tiktokVideoId.replace(/\//g, "");
|
||||||
// API链接
|
// API链接
|
||||||
const API_URL = `https://api16-normal-c-useast1a.tiktokv.com/aweme/v1/feed/?aweme_id=${ tiktokVideoId }`;
|
const API_URL = TIKTOK_INFO.replace("{}", tiktokVideoId);
|
||||||
await fetch(API_URL, {
|
await fetch(API_URL, {
|
||||||
headers: {
|
headers: {
|
||||||
"User-Agent":
|
"User-Agent":
|
||||||
@ -491,7 +492,7 @@ export class tools extends plugin {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 小蓝鸟解析
|
// 小蓝鸟解析:停止更新
|
||||||
// 例子:https://twitter.com/chonkyanimalx/status/1595834168000204800
|
// 例子:https://twitter.com/chonkyanimalx/status/1595834168000204800
|
||||||
async twitter(e) {
|
async twitter(e) {
|
||||||
// 配置参数及解析
|
// 配置参数及解析
|
||||||
@ -499,65 +500,70 @@ export class tools extends plugin {
|
|||||||
const twitterUrl = reg.exec(e.msg);
|
const twitterUrl = reg.exec(e.msg);
|
||||||
const id = twitterUrl[1];
|
const id = twitterUrl[1];
|
||||||
// 判断是否是海外服务器,默认为false
|
// 判断是否是海外服务器,默认为false
|
||||||
const isProxy = !(await this.isOverseasServer());
|
const isOversea = !(await this.isOverseasServer());
|
||||||
const httpAgent = new HttpsProxyAgent(this.myProxy);
|
|
||||||
const twitterClient = new TwitterApi(Buffer.from(TWITTER_BEARER_TOKEN, "base64").toString(), !isProxy ?? { httpAgent });
|
|
||||||
|
|
||||||
// Tell typescript it's a readonly app
|
// 请求
|
||||||
const readOnlyClient = twitterClient.readOnly;
|
const params = {
|
||||||
readOnlyClient.v2
|
"ids": id,
|
||||||
.singleTweet(id, {
|
"media.fields":
|
||||||
"media.fields":
|
"duration_ms,height,media_key,preview_image_url,public_metrics,type,url,width,alt_text,variants",
|
||||||
"duration_ms,height,media_key,preview_image_url,public_metrics,type,url,width,alt_text,variants",
|
"expansions": ["entities.mentions.username", "attachments.media_keys"],
|
||||||
expansions: ["entities.mentions.username", "attachments.media_keys"],
|
}
|
||||||
})
|
await fetch(TWITTER_TWEET_INFO.replace("{}", id), {
|
||||||
.then(async resp => {
|
headers: {
|
||||||
e.reply(`识别:小蓝鸟学习版,${ resp.data.text }`);
|
"User-Agent": "v2TweetLookupJS",
|
||||||
const downloadPath = `${ this.defaultPath }${ this.e.group_id || this.e.user_id }`;
|
"authorization": `Bearer ${Buffer.from(TWITTER_BEARER_TOKEN, "base64").toString()}`
|
||||||
// 创建文件夹(如果没有过这个群)
|
},
|
||||||
if (!fs.existsSync(downloadPath)) {
|
...params,
|
||||||
mkdirsSync(downloadPath);
|
agent: !isOversea ? '' : new HttpProxyAgent(this.myProxy),
|
||||||
|
}).then(async resp => {
|
||||||
|
logger.info(resp)
|
||||||
|
e.reply(`识别:小蓝鸟学习版,${ resp.data.text }`);
|
||||||
|
const downloadPath = `${ this.defaultPath }${ this.e.group_id || this.e.user_id }`;
|
||||||
|
// 创建文件夹(如果没有过这个群)
|
||||||
|
if (!fs.existsSync(downloadPath)) {
|
||||||
|
mkdirsSync(downloadPath);
|
||||||
|
}
|
||||||
|
// 逐个遍历判断
|
||||||
|
let task = [];
|
||||||
|
for (let item of resp.includes.media) {
|
||||||
|
if (item.type === "photo") {
|
||||||
|
// 图片
|
||||||
|
task.push(this.downloadImg(item.url, downloadPath, "", true));
|
||||||
|
} else if (item.type === "video") {
|
||||||
|
// 视频
|
||||||
|
await this.downloadVideo(resp.includes.media[0].variants[0].url, true).then(
|
||||||
|
_ => {
|
||||||
|
e.reply(segment.video(`${ downloadPath }/temp.mp4`));
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// 逐个遍历判断
|
}
|
||||||
let task = [];
|
// 如果没有图片直接返回走
|
||||||
for (let item of resp.includes.media) {
|
if (task.length === 0) {
|
||||||
if (item.type === "photo") {
|
return true;
|
||||||
// 图片
|
}
|
||||||
task.push(this.downloadImg(item.url, downloadPath, "", true));
|
// 下面是有图片的情况
|
||||||
} else if (item.type === "video") {
|
let images = [];
|
||||||
// 视频
|
let path = [];
|
||||||
await this.downloadVideo(resp.includes.media[0].variants[0].url, true).then(
|
// 获取所有图片的promise
|
||||||
_ => {
|
await Promise.all(task).then(resp => {
|
||||||
e.reply(segment.video(`${ downloadPath }/temp.mp4`));
|
// console.log(resp)
|
||||||
},
|
resp.forEach(item => {
|
||||||
);
|
path.push(item);
|
||||||
}
|
images.push({
|
||||||
}
|
message: segment.image(fs.readFileSync(item)),
|
||||||
// 如果没有图片直接返回走
|
nickname: this.e.sender.card || this.e.user_id,
|
||||||
if (task.length === 0) {
|
user_id: this.e.user_id,
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// 下面是有图片的情况
|
|
||||||
let images = [];
|
|
||||||
let path = [];
|
|
||||||
// 获取所有图片的promise
|
|
||||||
await Promise.all(task).then(resp => {
|
|
||||||
// console.log(resp)
|
|
||||||
resp.forEach(item => {
|
|
||||||
path.push(item);
|
|
||||||
images.push({
|
|
||||||
message: segment.image(fs.readFileSync(item)),
|
|
||||||
nickname: this.e.sender.card || this.e.user_id,
|
|
||||||
user_id: this.e.user_id,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
await e.reply(await Bot.makeForwardMsg(images));
|
|
||||||
// 清理文件
|
|
||||||
path.forEach(item => {
|
|
||||||
fs.unlinkSync(item);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
await e.reply(await Bot.makeForwardMsg(images));
|
||||||
|
// 清理文件
|
||||||
|
path.forEach(item => {
|
||||||
|
fs.unlinkSync(item);
|
||||||
|
});
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -615,7 +621,7 @@ export class tools extends plugin {
|
|||||||
}
|
}
|
||||||
const downloadPath = `${ this.defaultPath }${ this.e.group_id || this.e.user_id }`;
|
const downloadPath = `${ this.defaultPath }${ this.e.group_id || this.e.user_id }`;
|
||||||
// 获取信息
|
// 获取信息
|
||||||
fetch(`https://www.xiaohongshu.com/explore/${ id }`, {
|
fetch(`${XHS_REQ_LINK}${ id }`, {
|
||||||
headers: XHS_NO_WATERMARK_HEADER,
|
headers: XHS_NO_WATERMARK_HEADER,
|
||||||
}).then(async resp => {
|
}).then(async resp => {
|
||||||
const xhsHtml = await resp.text();
|
const xhsHtml = await resp.text();
|
||||||
@ -951,8 +957,8 @@ export class tools extends plugin {
|
|||||||
// bestVideo = Array.from(videos).sort((a, b) => a.rate - b.rate)[videos.length - 1];
|
// bestVideo = Array.from(videos).sort((a, b) => a.rate - b.rate)[videos.length - 1];
|
||||||
|
|
||||||
// 较为有性能的分辨率
|
// 较为有性能的分辨率
|
||||||
bestVideo = Array.from(videos).filter(item => item.scale.includes("720") || item.scale.includes("360"))[0];
|
bestVideo = Array.from(videos).find(item => item.scale.includes("720") || item.scale.includes("360"));
|
||||||
bestAudio = Array.from(audios).filter(item => item.format === 'm4a')[0];
|
bestAudio = Array.from(audios).find(item => item.format === 'm4a');
|
||||||
// logger.mark({
|
// logger.mark({
|
||||||
// bestVideo,
|
// bestVideo,
|
||||||
// bestAudio
|
// bestAudio
|
||||||
@ -969,7 +975,7 @@ export class tools extends plugin {
|
|||||||
let cmd = //`cd '${__dirname}' && (cd tmp > /dev/null || (mkdir tmp && cd tmp)) &&` +
|
let cmd = //`cd '${__dirname}' && (cd tmp > /dev/null || (mkdir tmp && cd tmp)) &&` +
|
||||||
`yt-dlp ${ this.y2bCk !== undefined ? `--cookies ${ this.y2bCk }` : '' } ${url} -f ${ format.replace('x', '+') } ` +
|
`yt-dlp ${ this.y2bCk !== undefined ? `--cookies ${ this.y2bCk }` : '' } ${url} -f ${ format.replace('x', '+') } ` +
|
||||||
`-o '${ fullpath }/${ v }.%(ext)s' ${ isProxy ? `--proxy ${ this.proxyAddr }:${ this.proxyPort }` : '' } -k --write-info-json`;
|
`-o '${ fullpath }/${ v }.%(ext)s' ${ isProxy ? `--proxy ${ this.proxyAddr }:${ this.proxyPort }` : '' } -k --write-info-json`;
|
||||||
logger.info(cmd)
|
logger.mark(cmd)
|
||||||
try {
|
try {
|
||||||
await child_process.execSync(cmd);
|
await child_process.execSync(cmd);
|
||||||
e.reply(segment.video(`${ fullpath }/${ v }.mp4`))
|
e.reply(segment.video(`${ fullpath }/${ v }.mp4`))
|
||||||
@ -1147,6 +1153,11 @@ export class tools extends plugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置海外模式
|
||||||
|
* @param e
|
||||||
|
* @returns {Promise<boolean>}
|
||||||
|
*/
|
||||||
async setOversea(e) {
|
async setOversea(e) {
|
||||||
// 查看当前设置
|
// 查看当前设置
|
||||||
let os;
|
let os;
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
/**
|
|
||||||
* AI总结API
|
|
||||||
* https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/misc/sign/wbi.md
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
export const BILI_SUMMARY = "https://api.bilibili.com/x/web-interface/view/conclusion/get"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 视频基本信息API
|
|
||||||
* https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/video/info.md
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
export const BILI_VIDEO_INFO = "http://api.bilibili.com/x/web-interface/view"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 登录基本信息
|
|
||||||
* https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/login/login_info.md#%E5%AF%BC%E8%88%AA%E6%A0%8F%E7%94%A8%E6%88%B7%E4%BF%A1%E6%81%AF
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
export const BILI_NAV = "https://api.bilibili.com/x/web-interface/nav"
|
|
@ -69,4 +69,6 @@ export const DIVIDING_LINE = "\n------------------{}------------------"
|
|||||||
* 保存判断机子是否是海外服务器的key
|
* 保存判断机子是否是海外服务器的key
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
export const REDIS_YUNZAI_ISOVERSEA = "Yz:rconsole:tools:oversea";
|
export const REDIS_YUNZAI_ISOVERSEA = "Yz:rconsole:tools:oversea";
|
||||||
|
|
||||||
|
export const TWITTER_BEARER_TOKEN = ""
|
50
constants/tools.js
Normal file
50
constants/tools.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
* AI总结API
|
||||||
|
* https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/misc/sign/wbi.md
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
export const BILI_SUMMARY = "https://api.bilibili.com/x/web-interface/view/conclusion/get"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频基本信息API
|
||||||
|
* https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/video/info.md
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
export const BILI_VIDEO_INFO = "http://api.bilibili.com/x/web-interface/view"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录基本信息
|
||||||
|
* https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/login/login_info.md#%E5%AF%BC%E8%88%AA%E6%A0%8F%E7%94%A8%E6%88%B7%E4%BF%A1%E6%81%AF
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
export const BILI_NAV = "https://api.bilibili.com/x/web-interface/nav"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频请求链接CDN
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
export const XHS_VIDEO = "http://sns-video-bd.xhscdn.com/"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dy API
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
export const DY_INFO = "https://www.douyin.com/aweme/v1/web/aweme/detail/?device_platform=webapp&aid=6383&channel=channel_pc_web&aweme_id={}&pc_client_type=1&version_code=190500&version_name=19.5.0&cookie_enabled=true&screen_width=1344&screen_height=756&browser_language=zh-CN&browser_platform=Win32&browser_name=Firefox&browser_version=118.0&browser_online=true&engine_name=Gecko&engine_version=109.0&os_name=Windows&os_version=10&cpu_core_num=16&device_memory=&platform=PC&webid=7284189800734082615&msToken=B1N9FM825TkvFbayDsDvZxM8r5suLrsfQbC93TciS0O9Iii8iJpAPd__FM2rpLUJi5xtMencSXLeNn8xmOS9q7bP0CUsrt9oVTL08YXLPRzZm0dHKLc9PGRlyEk="
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tiktok API
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
export const TIKTOK_INFO = "https://api16-normal-c-useast1a.tiktokv.com/aweme/v1/feed/?aweme_id={}"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* X API
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
export const TWITTER_TWEET_INFO = "https://api.twitter.com/2/tweets?ids={}"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XHS 的请求链接
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
export const XHS_REQ_LINK = "https://www.xiaohongshu.com/explore/"
|
@ -1,5 +0,0 @@
|
|||||||
/**
|
|
||||||
* 视频请求链接CDN
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
export const XHS_VIDEO = "http://sns-video-bd.xhscdn.com/"
|
|
@ -1,6 +1,6 @@
|
|||||||
import fetch from "node-fetch";
|
import fetch from "node-fetch";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { BILI_VIDEO_INFO } from "../constants/bili.js";
|
import { BILI_VIDEO_INFO } from "../constants/tools.js";
|
||||||
|
|
||||||
async function getVideoInfo(url) {
|
async function getVideoInfo(url) {
|
||||||
// const baseVideoInfo = "http://api.bilibili.com/x/web-interface/view";
|
// const baseVideoInfo = "http://api.bilibili.com/x/web-interface/view";
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import md5 from 'md5'
|
import md5 from 'md5'
|
||||||
import { BILI_NAV } from "../constants/bili.js";
|
import { BILI_NAV } from "../constants/tools.js";
|
||||||
|
|
||||||
const mixinKeyEncTab = [
|
const mixinKeyEncTab = [
|
||||||
46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49,
|
46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user