mirror of
https://github.com/Jerryplusy/rc-plugin.git
synced 2025-10-14 08:09:19 +00:00
Merge branch 'master' of https://github.com/nikoyoke1/rconsole-plugin
This commit is contained in:
commit
ab3a92ac8a
137
apps/check-car.js
Normal file
137
apps/check-car.js
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
import _ from 'lodash'
|
||||||
|
import { createRequire } from 'module'
|
||||||
|
|
||||||
|
const setimetu = 60 //消息撤回时间
|
||||||
|
|
||||||
|
//作者MiX
|
||||||
|
//使用前请用电脑浏览器打开https://whatslink.info/,然后获取到cookie填入第45行以获得更高的请求。
|
||||||
|
|
||||||
|
export class checkCar extends plugin {
|
||||||
|
constructor() {
|
||||||
|
super({
|
||||||
|
name: '验车',
|
||||||
|
dsc: '验车',
|
||||||
|
event: 'message',
|
||||||
|
priority: -100,
|
||||||
|
rule: [
|
||||||
|
{
|
||||||
|
reg: '^#验车(.*?)',
|
||||||
|
fnc: 'yc'
|
||||||
|
},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async yc(e) {
|
||||||
|
// 检查用户是否为管理员,如果不是则回复相应消息并返回。取消注释即仅主人可用
|
||||||
|
//if (!e.isMaster) {
|
||||||
|
// e.reply("涩批!不给你看😡", true);
|
||||||
|
// return true;
|
||||||
|
//}
|
||||||
|
|
||||||
|
// 从消息中提取关键词
|
||||||
|
let tag = e.msg.replace(/#验车/g, "");
|
||||||
|
const tags = `磁力:${tag}`;
|
||||||
|
|
||||||
|
// 构造获取涩图的URL
|
||||||
|
const api = `https://whatslink.info/api/v1/link?url=${tag}`;
|
||||||
|
const options = {
|
||||||
|
method: 'GET',
|
||||||
|
headers: ({
|
||||||
|
'Accept': 'application/json, text/plain, */*',
|
||||||
|
'Accept-Encoding': 'gzip, deflate, br',
|
||||||
|
'Accept-Language': 'zh-CN,zh;q=0.9',
|
||||||
|
'Connection': 'keep-alive',
|
||||||
|
'Cookie': 'aliyungf_tc=786a8710254a682250630ad426a4b444be3d405cfbdaa1e6e9b98f6d94487eb1',
|
||||||
|
'Host': 'whatslink.info',
|
||||||
|
'Referer': 'https://whatslink.info/',
|
||||||
|
'Sec-Ch-Ua': '"Not A(Brand";v="99", "Google Chrome";v="121", "Chromium";v="121"',
|
||||||
|
'Sec-Ch-Ua-Mobile': '?0',
|
||||||
|
'Sec-Ch-Ua-Platform': '"Windows"',
|
||||||
|
'Sec-Fetch-Dest': 'empty',
|
||||||
|
'Sec-Fetch-Mode': 'cors',
|
||||||
|
'Sec-Fetch-Site': 'same-origin',
|
||||||
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36'
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
// 使用fetch获取数据
|
||||||
|
const response = await fetch(api, options);
|
||||||
|
const data = await response.json();
|
||||||
|
logger.info('验车data----------', data)
|
||||||
|
const screenshots = data.screenshots
|
||||||
|
if (screenshots === null) {
|
||||||
|
await e.reply(data.name, false, { recallMsg: setimetu })
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
const jsonusedata = data.screenshots.map(item => ({
|
||||||
|
url: item.screenshot,
|
||||||
|
}));
|
||||||
|
const image = []
|
||||||
|
for (const { url } of jsonusedata) {
|
||||||
|
image.push({
|
||||||
|
urls: segment.image(url),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构造回复消息
|
||||||
|
let type = `文件类型:${data.file_type}`
|
||||||
|
let Msg = await this.makeForwardMsg(e, [tags, data.name, type, image]);
|
||||||
|
// e.reply(await Bot.makeForwardMsg(image))
|
||||||
|
await e.reply(Msg);
|
||||||
|
// await e.reply(Msg, false, { recallMsg: setimetu });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async makeForwardMsg(e, msg = [], dec = '') {
|
||||||
|
let userInfo = {
|
||||||
|
nickname: e.nickname,
|
||||||
|
user_id: e.user_id
|
||||||
|
}
|
||||||
|
|
||||||
|
let forwardMsg = []
|
||||||
|
msg.forEach(v => {
|
||||||
|
if (Array.isArray(v)) {
|
||||||
|
v.forEach(vv => {
|
||||||
|
forwardMsg.push({
|
||||||
|
...userInfo,
|
||||||
|
message: vv.urls
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
forwardMsg.push({
|
||||||
|
...userInfo,
|
||||||
|
message: v
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (e.isGroup) {
|
||||||
|
forwardMsg = await e.group.makeForwardMsg(forwardMsg)
|
||||||
|
} else if (e.friend) {
|
||||||
|
forwardMsg = await e.friend.makeForwardMsg(forwardMsg)
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dec) {
|
||||||
|
if (typeof (forwardMsg.data) === 'object') {
|
||||||
|
let detail = forwardMsg.data?.meta?.detail
|
||||||
|
if (detail) {
|
||||||
|
detail.news = [{ text: dec }]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
forwardMsg.data = forwardMsg.data
|
||||||
|
.replace('<?xml version="1.0" encoding="utf-8"?>', '<?xml version="1.0" encoding="utf-8" ?>')
|
||||||
|
.replace(/\n/g, '')
|
||||||
|
.replace(/<title color="#777777" size="26">(.+?)<\/title>/g, '___')
|
||||||
|
.replace(/___+/, `<title color="#777777" size="26">${dec}</title>`)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return forwardMsg
|
||||||
|
}
|
||||||
|
}
|
72
apps/deep-faker2.js
Normal file
72
apps/deep-faker2.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||||
|
|
||||||
|
import fs from "fs";
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
const DOWNLOAD_PATH = "./data/";
|
||||||
|
const GPTSOVITS_HOST = "https://cn-sy-bgp-plustmp1.natfrp.cloud:49918"
|
||||||
|
|
||||||
|
const voiceList = Object.freeze([
|
||||||
|
"雷军",
|
||||||
|
])
|
||||||
|
|
||||||
|
export class example extends plugin {
|
||||||
|
constructor () {
|
||||||
|
super({
|
||||||
|
name: '语音包',
|
||||||
|
dsc: '语音包',
|
||||||
|
// 匹配的消息类型,参考https://oicqjs.github.io/oicq/#events
|
||||||
|
event: 'message',
|
||||||
|
priority: 5000,
|
||||||
|
rule: [
|
||||||
|
{
|
||||||
|
reg: `^(${voiceList.join('|')})说(.*)`,
|
||||||
|
fnc: 'voicePack'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
reg: "^语音列表$",
|
||||||
|
fnc: 'voiceList'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async voicePack(e) {
|
||||||
|
const parts = e.msg.trim()
|
||||||
|
const part1 = parts.split("说", 1)[0];
|
||||||
|
const part2 = parts.substring(parts.indexOf("说") + 1).replaceAll(" ", ",");
|
||||||
|
|
||||||
|
// Data payload
|
||||||
|
const data = {
|
||||||
|
text: part2,
|
||||||
|
text_language: "zh"
|
||||||
|
};
|
||||||
|
|
||||||
|
// Make the POST request
|
||||||
|
axios.post(GPTSOVITS_HOST, data, { responseType: 'arraybuffer' })
|
||||||
|
.then(response => {
|
||||||
|
if (response.status === 400) {
|
||||||
|
throw new Error(`请求GPTSoVITS出现错误: ${response.data.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the content to a file
|
||||||
|
fs.writeFile(DOWNLOAD_PATH + "voicePack.wav", response.data, (err) => {
|
||||||
|
if (err) throw err;
|
||||||
|
e.reply(segment.record(fs.readFileSync(DOWNLOAD_PATH + "voicePack.wav")));
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error.message);
|
||||||
|
});
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
async voiceList(e) {
|
||||||
|
e.reply(Bot.makeForwardMsg([{
|
||||||
|
message: { type: "text", text: voiceList.join("\n") },
|
||||||
|
nickname: e.sender.card || e.user_id,
|
||||||
|
user_id: e.user_id,
|
||||||
|
}]));
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
177
apps/kimi.js
Normal file
177
apps/kimi.js
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
import config from "../model/config.js";
|
||||||
|
import puppeteer from "../../../lib/puppeteer/puppeteer.js";
|
||||||
|
import fs from "fs";
|
||||||
|
import { marked } from "marked"
|
||||||
|
|
||||||
|
async function markdownRender(e, query, aiContent) {
|
||||||
|
// 打开一个新的页面
|
||||||
|
const browser = await puppeteer.browserInit();
|
||||||
|
const page = await browser.newPage();
|
||||||
|
|
||||||
|
if (aiContent.indexOf("搜索结果来自:") !== -1) {
|
||||||
|
aiContent = aiContent.split("搜索结果来自:")[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
const htmlContent = `<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Kimi Chat Interface</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: #1a1a1a;
|
||||||
|
color: #ffffff;
|
||||||
|
margin: 0;
|
||||||
|
padding: 20px;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
.chat-container {
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
.logo {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.logo img {
|
||||||
|
max-width: 200px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
.message {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
.avatar {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
.message-content {
|
||||||
|
background-color: #2a2a2a;
|
||||||
|
border-radius: 18px;
|
||||||
|
padding: 12px 12px;
|
||||||
|
max-width: 70%;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.user-message {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
.user-message .message-content {
|
||||||
|
background-color: #0066cc;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
.ai-message .message-content {
|
||||||
|
background-color: #2a2a2a;
|
||||||
|
}
|
||||||
|
.user-message .avatar {
|
||||||
|
order: 1;
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 12px;
|
||||||
|
}
|
||||||
|
pre {
|
||||||
|
background-color: #1e1e1e;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 12px;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
code {
|
||||||
|
font-family: 'Courier New', Courier, monospace;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="chat-container">
|
||||||
|
<div class="logo">
|
||||||
|
<img src="https://gitee.com/kyrzy0416/rconsole-plugin-complementary-set/raw/master/kimi/logo.png" alt="KIMI Logo">
|
||||||
|
</div>
|
||||||
|
<div class="message user-message">
|
||||||
|
<div class="message-content">
|
||||||
|
<p>${ query }</p>
|
||||||
|
</div>
|
||||||
|
<img src="http://q1.qlogo.cn/g?b=qq&nk=${ e.user_id }&s=100" alt="User Avatar" class="avatar">
|
||||||
|
</div>
|
||||||
|
<div class="message ai-message">
|
||||||
|
<img src="https://gitee.com/kyrzy0416/rconsole-plugin-complementary-set/raw/master/kimi/kimi.png" alt="AI Avatar" class="avatar">
|
||||||
|
<div class="message-content">
|
||||||
|
<div id="ai-content">${ marked.parse(aiContent) }</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>`;
|
||||||
|
await page.setViewport({
|
||||||
|
width: 1280,
|
||||||
|
height: 720,
|
||||||
|
deviceScaleFactor: 10, // 根据显示器的分辨率调整比例,2 是常见的 Retina 显示比例
|
||||||
|
});
|
||||||
|
// 设置页面内容为包含 Base64 图片的 HTML
|
||||||
|
await page.setContent(htmlContent, {
|
||||||
|
waitUntil: "networkidle0",
|
||||||
|
});
|
||||||
|
// 获取页面上特定元素的位置和尺寸
|
||||||
|
const element = await page.$(".chat-container"); // 可以用CSS选择器选中你要截取的部分
|
||||||
|
// 直接截图该元素
|
||||||
|
await element.screenshot({
|
||||||
|
path: "./chat.png",
|
||||||
|
type: "jpeg",
|
||||||
|
fullPage: false,
|
||||||
|
omitBackground: false,
|
||||||
|
quality: 50,
|
||||||
|
});
|
||||||
|
await e.reply(segment.image(fs.readFileSync("./chat.png")));
|
||||||
|
}
|
||||||
|
|
||||||
|
export class kimiJS extends plugin {
|
||||||
|
constructor() {
|
||||||
|
super({
|
||||||
|
name: 'Moonshot AI',
|
||||||
|
dsc: 'Moonshot AI Assistant',
|
||||||
|
event: 'message',
|
||||||
|
priority: 1,
|
||||||
|
rule: [
|
||||||
|
{
|
||||||
|
reg: '^#kimi(.*)$',
|
||||||
|
fnc: 'chat'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
// 配置文件
|
||||||
|
this.toolsConfig = config.getConfig("tools");
|
||||||
|
// 设置基础 URL 和 headers
|
||||||
|
this.baseURL = this.toolsConfig.aiBaseURL;
|
||||||
|
this.headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Authorization": "Bearer " + this.toolsConfig.aiApiKey
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async chat(e) {
|
||||||
|
const query = e.msg.replace(/^#kimi/, '').trim();
|
||||||
|
// 请求Kimi
|
||||||
|
const completion = await fetch(this.baseURL + "/v1/chat/completions", {
|
||||||
|
method: 'POST',
|
||||||
|
headers: this.headers,
|
||||||
|
body: JSON.stringify({
|
||||||
|
model: "moonshot-v1-8k",
|
||||||
|
messages: [
|
||||||
|
{
|
||||||
|
"role": "system",
|
||||||
|
"content": this.prompt,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: "user",
|
||||||
|
content: query
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
timeout: 100000
|
||||||
|
});
|
||||||
|
await markdownRender(e, query, (await completion.json()).choices[0].message.content, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
238
apps/songRequest.js
Normal file
238
apps/songRequest.js
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
import { formatTime } from '../utils/other.js'
|
||||||
|
import puppeteer from "../../../lib/puppeteer/puppeteer.js";
|
||||||
|
import PickSongList from "../model/pick-song.js";
|
||||||
|
import { NETEASE_API_CN, NETEASE_SONG_DOWNLOAD, NETEASE_TEMP_API } from "../constants/tools.js";
|
||||||
|
import { COMMON_USER_AGENT, REDIS_YUNZAI_ISOVERSEA, REDIS_YUNZAI_SONGINFO } from "../constants/constant.js";
|
||||||
|
import { } from "../utils/common.js";
|
||||||
|
import { redisExistKey, redisGetKey, redisSetKey } from "../utils/redis-util.js";
|
||||||
|
import { checkAndRemoveFile } from "../utils/file.js";
|
||||||
|
import config from "../model/config.js";
|
||||||
|
|
||||||
|
export class songRequest extends plugin {
|
||||||
|
constructor() {
|
||||||
|
super({
|
||||||
|
name: "R插件点歌",
|
||||||
|
dsc: "实现快捷点歌",
|
||||||
|
priority: 300,
|
||||||
|
rule: [
|
||||||
|
{
|
||||||
|
reg: '^点歌|#听[1-9][0-9]|#听[0-9]*$',
|
||||||
|
fnc: 'pickSong'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
reg: "^播放(.*)",
|
||||||
|
fnc: "playSong"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
});
|
||||||
|
this.toolsConfig = config.getConfig("tools");
|
||||||
|
// 加载网易云Cookie
|
||||||
|
this.neteaseCookie = this.toolsConfig.neteaseCookie
|
||||||
|
// 加载是否自建服务器
|
||||||
|
this.useLocalNeteaseAPI = this.toolsConfig.useLocalNeteaseAPI
|
||||||
|
// 加载自建服务器API
|
||||||
|
this.neteaseCloudAPIServer = this.toolsConfig.neteaseCloudAPIServer
|
||||||
|
// 加载网易云解析最高音质
|
||||||
|
this.neteaseCloudAudioQuality = this.toolsConfig.neteaseCloudAudioQuality
|
||||||
|
// 加载识别前缀
|
||||||
|
this.identifyPrefix = this.toolsConfig.identifyPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断是否海外服务器
|
||||||
|
async isOverseasServer() {
|
||||||
|
// 如果第一次使用没有值就设置
|
||||||
|
if (!(await redisExistKey(REDIS_YUNZAI_ISOVERSEA))) {
|
||||||
|
await redisSetKey(REDIS_YUNZAI_ISOVERSEA, {
|
||||||
|
os: false,
|
||||||
|
})
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 如果有就取出来
|
||||||
|
return (await redisGetKey(REDIS_YUNZAI_ISOVERSEA)).os;
|
||||||
|
}
|
||||||
|
|
||||||
|
async pickSong(e) {
|
||||||
|
const isOversea = await this.isOverseasServer();
|
||||||
|
let autoSelectNeteaseApi
|
||||||
|
if (this.useLocalNeteaseAPI) {
|
||||||
|
// 使用自建 API
|
||||||
|
autoSelectNeteaseApi = this.neteaseCloudAPIServer
|
||||||
|
} else {
|
||||||
|
// 自动选择 API
|
||||||
|
autoSelectNeteaseApi = isOversea ? NETEASE_SONG_DOWNLOAD : NETEASE_API_CN;
|
||||||
|
}
|
||||||
|
let songInfo = []
|
||||||
|
|
||||||
|
// 获取搜索歌曲列表信息
|
||||||
|
|
||||||
|
let searchUrl = autoSelectNeteaseApi + '/search?keywords={}&limit=10' //搜索API
|
||||||
|
let detailUrl = autoSelectNeteaseApi + "/song/detail?ids={}" //歌曲详情API
|
||||||
|
if (e.msg.replace(/\s+/g, "").match(/点歌(.+)/)) {
|
||||||
|
const songKeyWord = e.msg.replace(/\s+/g, "").match(/点歌(.+)/)[1]
|
||||||
|
searchUrl = searchUrl.replace("{}", songKeyWord)
|
||||||
|
await axios.get(searchUrl, {
|
||||||
|
headers: {
|
||||||
|
"User-Agent": COMMON_USER_AGENT
|
||||||
|
},
|
||||||
|
}).then(async res => {
|
||||||
|
if (res.data.result.songs) {
|
||||||
|
for (const info of res.data.result.songs) {
|
||||||
|
songInfo.push({
|
||||||
|
'id': info.id,
|
||||||
|
'songName': info.name,
|
||||||
|
'singerName': info.artists[0]?.name,
|
||||||
|
'duration': formatTime(info.duration)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const ids = songInfo.map(item => item.id).join(',');
|
||||||
|
detailUrl = detailUrl.replace("{}", ids)
|
||||||
|
await axios.get(detailUrl, {
|
||||||
|
headers: {
|
||||||
|
"User-Agent": COMMON_USER_AGENT
|
||||||
|
},
|
||||||
|
}).then(res => {
|
||||||
|
for (let i = 0; i < res.data.songs.length; i++) {
|
||||||
|
songInfo[i].cover = res.data.songs[i].al.picUrl
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await redisSetKey(REDIS_YUNZAI_SONGINFO, songInfo)
|
||||||
|
const data = await new PickSongList(e).getData(songInfo)
|
||||||
|
let img = await puppeteer.screenshot("pick-song", data);
|
||||||
|
e.reply(img, true);
|
||||||
|
} else {
|
||||||
|
e.reply('暂未找到你想听的歌哦~')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else if (await redisGetKey(REDIS_YUNZAI_SONGINFO) != []) {
|
||||||
|
if (e.msg.match(/#听(\d+)/)) {
|
||||||
|
const pickNumber = e.msg.match(/#听(\d+)/)[1] - 1
|
||||||
|
let songInfo = await redisGetKey(REDIS_YUNZAI_SONGINFO)
|
||||||
|
const AUTO_NETEASE_SONG_DOWNLOAD = autoSelectNeteaseApi + "/song/url/v1?id={}&level=" + this.neteaseCloudAudioQuality;
|
||||||
|
const pickSongUrl = AUTO_NETEASE_SONG_DOWNLOAD.replace("{}", songInfo[pickNumber].id)
|
||||||
|
const statusUrl = autoSelectNeteaseApi + '/login/status' //用户状态API
|
||||||
|
const isCkExpired = await axios.get(statusUrl, {
|
||||||
|
headers: {
|
||||||
|
"User-Agent": COMMON_USER_AGENT,
|
||||||
|
"Cookie": this.neteaseCookie
|
||||||
|
},
|
||||||
|
}).then(res => {
|
||||||
|
const userInfo = res.data.data.profile
|
||||||
|
if (userInfo) {
|
||||||
|
logger.info('ck活着,使用ck进行高音质下载')
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
logger.info('ck失效,将启用临时接口下载')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// // 请求netease数据
|
||||||
|
axios.get(pickSongUrl, {
|
||||||
|
headers: {
|
||||||
|
"User-Agent": COMMON_USER_AGENT,
|
||||||
|
"Cookie": this.neteaseCookie
|
||||||
|
},
|
||||||
|
}).then(async resp => {
|
||||||
|
// 国内解决方案,替换API后这里也需要修改
|
||||||
|
|
||||||
|
// 英转中字典匹配
|
||||||
|
const translationDict = {
|
||||||
|
'standard': '标准',
|
||||||
|
'higher': '较高',
|
||||||
|
'exhigh': '极高',
|
||||||
|
'lossless': '无损',
|
||||||
|
'hires': 'Hi-Res',
|
||||||
|
'jyeffect': '高清环绕声',
|
||||||
|
'sky': '沉浸环绕声',
|
||||||
|
'dolby': '杜比全景声',
|
||||||
|
'jymaster': '超清母带'
|
||||||
|
};
|
||||||
|
|
||||||
|
// 英转中
|
||||||
|
function translateToChinese(word) {
|
||||||
|
return translationDict[word] || word; // 如果找不到对应翻译,返回原词
|
||||||
|
}
|
||||||
|
|
||||||
|
// 字节转MB
|
||||||
|
function bytesToMB(sizeInBytes) {
|
||||||
|
const sizeInMB = sizeInBytes / (1024 * 1024); // 1 MB = 1024 * 1024 bytes
|
||||||
|
return sizeInMB.toFixed(2); // 保留两位小数
|
||||||
|
}
|
||||||
|
logger.info('下载歌曲详情-----------', resp.data.data)
|
||||||
|
let url = await resp.data.data?.[0]?.url || null;
|
||||||
|
const AudioLevel = translateToChinese(resp.data.data?.[0]?.level)
|
||||||
|
const AudioSize = bytesToMB(resp.data.data?.[0]?.size)
|
||||||
|
// 获取歌曲信息
|
||||||
|
let title = songInfo[pickNumber].songName + '-' + songInfo[pickNumber].singerName
|
||||||
|
// 一般这个情况是VIP歌曲 (如果没有url或者是国内,公用接口暂时不可用,必须自建并且ck可用状态才能进行高质量解析)
|
||||||
|
if (!isCkExpired || !this.useLocalNeteaseAPI || url == null) {
|
||||||
|
url = await this.musicTempApi(e, title, "网易云音乐");
|
||||||
|
} else {
|
||||||
|
// 拥有ck,并且有效,直接进行解析
|
||||||
|
let audioInfo = AudioLevel;
|
||||||
|
if (AudioLevel == '杜比全景声') {
|
||||||
|
audioInfo += '\n(杜比下载文件为MP4,编码格式为AC-4,需要设备支持才可播放)';
|
||||||
|
}
|
||||||
|
e.reply([segment.image(songInfo[pickNumber].cover), `${this.identifyPrefix}识别:网易云音乐,${title}\n当前下载音质: ${audioInfo}\n预估大小: ${AudioSize}MB`]);
|
||||||
|
}
|
||||||
|
// 动态判断后缀名
|
||||||
|
let musicExt = resp.data.data?.[0]?.type
|
||||||
|
// 下载音乐
|
||||||
|
downloadAudio(url, this.getCurDownloadPath(e), title, 'follow', musicExt).then(async path => {
|
||||||
|
// 发送语音
|
||||||
|
if (musicExt != 'mp4') {
|
||||||
|
await e.reply(segment.record(path));
|
||||||
|
}
|
||||||
|
// 上传群文件
|
||||||
|
await this.uploadGroupFile(e, path);
|
||||||
|
// 删除文件
|
||||||
|
await checkAndRemoveFile(path);
|
||||||
|
}).catch(err => {
|
||||||
|
logger.error(`下载音乐失败,错误信息为: ${err}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async musicTempApi(e, title, musicType) {
|
||||||
|
let musicReqApi = NETEASE_TEMP_API;
|
||||||
|
// 临时接口,title经过变换后搜索到的音乐质量提升
|
||||||
|
const vipMusicData = await axios.get(musicReqApi.replace("{}", title.replace("-", " ")), {
|
||||||
|
headers: {
|
||||||
|
"User-Agent": COMMON_USER_AGENT,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const messageTitle = title + "\nR插件检测到当前为VIP音乐,正在转换...";
|
||||||
|
// ??后的内容是适配`QQ_MUSIC_TEMP_API`、最后是汽水
|
||||||
|
const url = vipMusicData.data?.music_url ?? vipMusicData.data?.data?.music_url ?? vipMusicData.data?.music;
|
||||||
|
const cover = vipMusicData.data?.cover ?? vipMusicData.data?.data?.cover ?? vipMusicData.data?.cover;
|
||||||
|
await e.reply([segment.image(cover), `${this.identifyPrefix}识别:${musicType},${messageTitle}`]);
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前发送人/群的下载路径
|
||||||
|
* @param e Yunzai 机器人事件
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
getCurDownloadPath(e) {
|
||||||
|
return `${this.defaultPath}${e.group_id || e.user_id}`
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传到群文件
|
||||||
|
* @param e 交互事件
|
||||||
|
* @param path 上传的文件所在路径
|
||||||
|
* @return {Promise<void>}
|
||||||
|
*/
|
||||||
|
async uploadGroupFile(e, path) {
|
||||||
|
// 判断是否是ICQQ
|
||||||
|
if (e.bot?.sendUni) {
|
||||||
|
await e.group.fs.upload(path);
|
||||||
|
} else {
|
||||||
|
await e.group.sendFile(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -21,61 +21,61 @@
|
|||||||
- group: 工具类合集
|
- group: 工具类合集
|
||||||
list:
|
list:
|
||||||
- icon: translate
|
- icon: translate
|
||||||
title: "翻中/英/日 xxx"
|
title: 翻中/英/日 xxx
|
||||||
desc: R插件翻译引擎
|
desc: R插件翻译引擎
|
||||||
- icon: tiktok
|
- icon: tiktok
|
||||||
title: "douyin"
|
title: douyin
|
||||||
desc: 抖音分享实时下载
|
desc: 抖音分享实时下载
|
||||||
- icon: bilibili
|
- icon: bilibili
|
||||||
title: "哔哩哔哩"
|
title: 哔哩哔哩
|
||||||
desc: 哔哩哔哩分享实时下载
|
desc: 哔哩哔哩分享实时下载
|
||||||
- icon: bqrcode
|
- icon: bqrcode
|
||||||
title: "#rbq/#RBQ"
|
title: "#rbq/#RBQ"
|
||||||
desc: R插件B站扫码
|
desc: R插件B站扫码
|
||||||
- icon: applemusic
|
- icon: applemusic
|
||||||
title: "Apple Music"
|
title: Apple Music
|
||||||
desc: Apple Music音乐分享实时下载
|
desc: Apple Music音乐分享实时下载
|
||||||
- icon: youtube
|
- icon: youtube
|
||||||
title: "油管"
|
title: 油管
|
||||||
desc: 油管学习版分享实时下载
|
desc: 油管学习版分享实时下载
|
||||||
- icon: twitter
|
- icon: twitter
|
||||||
title: "小蓝鸟"
|
title: 小蓝鸟
|
||||||
desc: 推特学习版分享实时下载
|
desc: 推特学习版分享实时下载
|
||||||
- icon: acfun
|
- icon: acfun
|
||||||
title: "acfun"
|
title: acfun
|
||||||
desc: 猴山分享实时下载
|
desc: 猴山分享实时下载
|
||||||
- icon: redbook
|
- icon: redbook
|
||||||
title: "小红书"
|
title: 小红书
|
||||||
desc: 小红书分享实时下载
|
desc: 小红书分享实时下载
|
||||||
- icon: kuaishou
|
- icon: kuaishou
|
||||||
title: "快手(测试阶段)"
|
title: 快手(测试阶段)
|
||||||
desc: 快手分享实时下载
|
desc: 快手分享实时下载
|
||||||
- icon: xigua
|
- icon: xigua
|
||||||
title: "西瓜(测试阶段)"
|
title: 西瓜(测试阶段)
|
||||||
desc: 西瓜分享实时下载
|
desc: 西瓜分享实时下载
|
||||||
- icon: miyoushe
|
- icon: miyoushe
|
||||||
title: "米游社"
|
title: 米游社
|
||||||
desc: 米游社文章分享实时下载
|
desc: 米游社文章分享实时下载
|
||||||
- icon: weibo
|
- icon: weibo
|
||||||
title: "微博"
|
title: 微博
|
||||||
desc: 微博文章分享实时下载
|
desc: 微博文章分享实时下载
|
||||||
- icon: zuiyou
|
- icon: zuiyou
|
||||||
title: "最右(测试阶段)"
|
title: 最右(测试阶段)
|
||||||
desc: 最右分享实时下载
|
desc: 最右分享实时下载
|
||||||
- icon: pipi
|
- icon: pipi
|
||||||
title: "皮皮虾(测试阶段)"
|
title: 皮皮虾(测试阶段)
|
||||||
desc: 皮皮虾分享实时下载
|
desc: 皮皮虾分享实时下载
|
||||||
- icon: bodian
|
- icon: bodian
|
||||||
title: "波点音乐"
|
title: 波点音乐
|
||||||
desc: 波点云音乐点解析
|
desc: 波点云音乐点解析
|
||||||
- icon: spotify
|
- icon: spotify
|
||||||
title: "Spotify"
|
title: Spotify
|
||||||
desc: 解析Spotify音乐
|
desc: 解析Spotify音乐
|
||||||
- icon: telegram
|
- icon: telegram
|
||||||
title: "小飞机(学习版)"
|
title: 小飞机(学习版)
|
||||||
desc: 解析小飞机
|
desc: 解析小飞机
|
||||||
- group: 其他指令
|
- group: 其他指令
|
||||||
list:
|
list:
|
||||||
- icon: update
|
- icon: update
|
||||||
title: "#R插件更新"
|
title: "#R插件更新"
|
||||||
desc: "进行更新R插件"
|
desc: 进行更新R插件
|
||||||
|
@ -1,50 +1,87 @@
|
|||||||
defaultPath: './data/rcmp4/' # 保存视频的位置
|
defaultPath: ./data/rcmp4/
|
||||||
videoSizeLimit: 70 # 视频大小限制(单位MB),超过大小则转换成群文件上传
|
videoSizeLimit: 100
|
||||||
proxyAddr: '127.0.0.1' # 魔法地址
|
proxyAddr: 127.0.0.1
|
||||||
proxyPort: '7890' # 魔法端口
|
proxyPort: "7890"
|
||||||
identifyPrefix: '' # 识别前缀,比如你识别哔哩哔哩,那么就有:✅ 识别:哔哩哔哩
|
identifyPrefix: ✅
|
||||||
|
deeplApiUrls: http://www.gptspt.cn/translate,http://gptspt.top/translate,http://8.134.135.4:1188/translate,http://120.76.141.173:1188/translate,http://bit.x7ys.com:1188/translate,http://deeplxapi.x7ys.com:1188/translate
|
||||||
deeplApiUrls: 'http://www.gptspt.cn/translate,http://gptspt.top/translate,http://8.134.135.4:1188/translate,http://120.76.141.173:1188/translate,http://bit.x7ys.com:1188/translate,http://deeplxapi.x7ys.com:1188/translate'
|
streamDuration: 10
|
||||||
|
streamCompatibility: false
|
||||||
streamDuration: 10 # 视频最大时长(单位秒)
|
biliSessData: a56d470f%2C1744730590%2C813e6%2Aa2CjAD_PFOxMcmeZ40kSD03f6j1kTArPuM-cpVjnSK_5azosYAuZxGAeQ3RzK7Eh0O40ESVlJsUkxTWDlFVEY3VGNTU1dtWEFEQmh4TER3OW5UQ3FOTzBWSkx5WXYzTFBoai1nTEpwMVprek5BNlJic3g2RWhYVTRqNXJFME9WX1p1U1RoMGQ1Qkh3IIEC
|
||||||
streamCompatibility: false # 兼容模式,NCQQ不用开,其他ICQQ、LLO需要开启
|
biliIntroLenLimit: 50
|
||||||
|
biliDuration: 900
|
||||||
biliSessData: '' # 哔哩哔哩的SESSDATA
|
biliDisplayCover: true
|
||||||
biliIntroLenLimit: 50 # 哔哩哔哩简介长度限制,填 0 或者 -1 可以不做任何限制,显示完整简介
|
biliDisplayInfo: true
|
||||||
biliDuration: 480 # 哔哩哔哩限制的最大视频时长(默认8分钟),单位:秒
|
biliDisplayIntro: true
|
||||||
biliDisplayCover: true # 是否显示哔哩哔哩的封面
|
biliDisplayOnline: true
|
||||||
biliDisplayInfo: true # 是否显示哔哩哔哩的视频信息
|
biliDisplaySummary: false
|
||||||
biliDisplayIntro: true # 是否显示哔哩哔哩的简介
|
biliUseBBDown: true
|
||||||
biliDisplayOnline: true # 是否显示哔哩哔哩的在线人数
|
biliCDN: 0
|
||||||
biliDisplaySummary: false # 是否显示哔哩哔哩的总结
|
biliDownloadMethod: 0
|
||||||
biliUseBBDown: false # 是否使用BBDown,默认不开启,开启后使用强劲的BBDown下载最高画质
|
biliResolution: 2
|
||||||
biliCDN: 0 # 哔哩哔哩 CDN,默认为0表示不使用
|
useLocalNeteaseAPI: true
|
||||||
biliDownloadMethod: 0 # 哔哩哔哩的下载方式:0默认使用原生稳定的下载方式,如果你在乎内存可以使用轻量的wget和axel下载方式,如果在乎性能可以使用Aria2下载
|
neteaseCookie: MUSIC_U=000B6FB760D4DD0C8FF579D22EF13F4631A662365882A1DCB227B306A50E274E5A93061745A36AB27D85F9EFF82699A34BA6DF9B311AF9C52EF096F512D8BE274001B1D0064FEE95158AD7BDE28CD277212FA99569D0B94ADB14281355C80E2C0A730F49304C257AD0E16492F253EA47B91D64206344527DD9768454C27343D73ACFB59B13830B6FD6F367B69EDE875796CED7958CFF653AF87E7F3FEFCF43B8D9E7C75C9494F8C31C553B64A23357E2B59A07B8D7AFFAC1234589DD0C338C7DAD7A36407D36933A6DA7F21F7E975A271E65D5C38805CFE3AE3D7E55588E64DDB2D94A719FABA9464A54E78F699182728206C72D5A10FF9D1E5BF2C4DDFB7E47F61723DDE3ABF47A5D6352E2EDC984BA1A4767B7BB4F8E8D018E6ACDB1D71D85694D29B8C4DBF0C6072CD2127EA7D94348;
|
||||||
biliResolution: 1 # 哔哩哔哩的下载画质,0为原画,1为清晰画,2为流畅画(默认为0)
|
os=pc
|
||||||
|
neteaseCloudAPIServer: http://www.qdy.ink:55522
|
||||||
useLocalNeteaseAPI: false # 是否使用网易云解析自建API
|
neteaseCloudAudioQuality: jymaster
|
||||||
neteaseCookie: '' # 网易云ck
|
youtubeGraphicsOptions: 1080
|
||||||
neteaseCloudAPIServer: '' # 网易云自建服务器地址
|
youtubeClipTime: null
|
||||||
neteaseCloudAudioQuality: exhigh # 网易云解析最高音质 默认exhigh(极高) 分类:standard => 标准,higher => 较高, exhigh=>极高, lossless=>无损, hires=>Hi-Res, jyeffect => 高清环绕声, sky => 沉浸环绕声, dolby => 杜比全景声, jymaster => 超清母带
|
youtubeDuration: 900
|
||||||
|
douyinCookie: ttwid=1%7CGlKor0s7yJTURXYA5X9sbAgunYFVfBoVLX9v2mfAyhQ%7C1694051452%7C80e7c98a8473faed6f881b7379f7e29405be10e9ac35b7618cc43adf8a1a2f41;
|
||||||
youtubeGraphicsOptions: 720 # YouTobe的下载画质,0为原画,1080,720,480,自定义画面高度(默认为720)
|
SEARCH_RESULT_LIST_TYPE=%22single%22;
|
||||||
youtubeClipTime: 0 # YouTobe限制的最大视频时长(默认不开启),单位:秒 最好不要超过5分钟,否则截取效率非常低
|
UIFID_TEMP=1ee16134db40129a5ff28e6a352dddaa8524f48fc5e4ea6d697d6a182d7836e449f664cfb29d1099cfb2fb62ce7db5e6a4fd0aeafe0c2afd30fa1e97fa68fc67ff8e51c3904b654300f5021c7159cd6a;
|
||||||
youtubeDuration: 480 # YouTobe限制的最大视频时长(默认8分钟),单位:秒 最好不要超过30分钟,否则截取效率非常低
|
s_v_web_id=verify_m0up87e5_t8ChctxF_3HK0_4e2k_9UKg_49HT0IC3Hsab;
|
||||||
|
hevc_supported=true; passport_csrf_token=0197d3b34f027df28862da61991c0eb7;
|
||||||
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;
|
passport_csrf_token_default=0197d3b34f027df28862da61991c0eb7;
|
||||||
douyinCompression: true # true-压缩,false-不压缩;是否使用压缩视频格式的抖音(默认使用),使用后加速视频发送
|
bd_ticket_guard_client_web_domain=2;
|
||||||
douyinComments: false # true-开启评论,false-关闭评论
|
fpk1=U2FsdGVkX19oyd9PX2fmFVaSJiFDZTknfNeDgrBL+oovtUMKhA6vexuXHj6gEF9IWKs8iyFJc5r4PmS7QmyiKQ==;
|
||||||
|
fpk2=e8db1a910ee088b469ecfd2b6a9b9da5;
|
||||||
xiaohongshuCookie: '' # 2024-8-2后反馈必须使用ck,不然无法解析
|
UIFID=1ee16134db40129a5ff28e6a352dddaa8524f48fc5e4ea6d697d6a182d7836e4b80abacd6e9013b4a4043a401aab353263551bdef6fcabc5b1891e33448cae02c056b0c65c2758ee92ffbde2996c98ba87eddf939a7e91224bfc962944ab939cefb96fb42fb2482f40658d2ca65e0ee68131f8082f360cbcec35bb06f7d444bb5ef3e84cacc65df726cc55e14e3d6a959699a997c4f9a9a39cbfe63f07bd93ad;
|
||||||
|
d_ticket=22c8797c4bb92fa7f9198fff1c949b98a0750;
|
||||||
queueConcurrency: 1 # 【目前只涉及哔哩哔哩的下载】根据服务器性能设置可以并发下载的个数,如果你的服务器比较强劲,就选择4~12,较弱就一个一个下载,选择1
|
passport_assist_user=Cj8lyV9Z6D9MR1YIPSuyBTmq-MkkfDC_ino72STrLztUelhMSlxQmhu1hWD4SKT5fXqnn9h8Pf-2PoTcZD7AYesaSgo8CWitJ5ebWoBSMtxmNtbczFA-fU49bNw_ESDcASSVeTGd74mnRUFwlknjTqR-OKcWuJGtiWTCmdLeFF1WEMjR2w0Yia_WVCABIgEDk97NRw%3D%3D;
|
||||||
|
n_mh=6PqAsBDwpWzjjhyh0DJxbjfHwLWX-QGpUHXGB71culA;
|
||||||
videoDownloadConcurrency: 1 # 下载视频是否使用多线程,如果不使用默认是1,如果使用根据服务器进行选择,如果不确定是否可以用4即可,高性能服务器随意4~12都可以,看CPU的实力
|
sso_uid_tt=17ce377d8953b76136b51d2c8c476936;
|
||||||
|
sso_uid_tt_ss=17ce377d8953b76136b51d2c8c476936;
|
||||||
lagrangeForwardWebSocket: 'ws://127.0.0.1:9091/' # 格式:ws://地址:端口/,拉格朗日正向连接地址,用于适配拉格朗日上传群文件,解决部分用户无法查看视频问题
|
toutiao_sso_user=cc92e6a4f4c0e72e261228be675000cc;
|
||||||
|
toutiao_sso_user_ss=cc92e6a4f4c0e72e261228be675000cc;
|
||||||
autoclearTrashtime: '0 0 8 * * ?' #每天早上8点自动清理视频缓存,cron可自定义时间
|
sid_ucp_sso_v1=1.0.0-KGU2MTMxNDkyZDY0MzM3YjJhOWI1Mzg2NzYyYTM0Yzk5OTc5YTcwZTYKIAi50eCEpM0CEOTP-rYGGO8xIAwwyZKQrQY4AkDxB0gGGgJsZiIgY2M5MmU2YTRmNGMwZTcyZTI2MTIyOGJlNjc1MDAwY2M;
|
||||||
|
ssid_ucp_sso_v1=1.0.0-KGU2MTMxNDkyZDY0MzM3YjJhOWI1Mzg2NzYyYTM0Yzk5OTc5YTcwZTYKIAi50eCEpM0CEOTP-rYGGO8xIAwwyZKQrQY4AkDxB0gGGgJsZiIgY2M5MmU2YTRmNGMwZTcyZTI2MTIyOGJlNjc1MDAwY2M;
|
||||||
aiBaseURL: '' # 用于识图的接口,kimi默认接口为:https://api.moonshot.cn,其他服务商自己填写
|
uid_tt=e890963c895ad76636236d4ee7bd8012;
|
||||||
aiApiKey: '' # 用于识图的api key,kimi接口申请:https://platform.moonshot.cn/console/api-keys
|
uid_tt_ss=e890963c895ad76636236d4ee7bd8012;
|
||||||
aiModel: 'moonshot-v1-8k' # 模型,使用kimi不用填写,其他要填写
|
sid_tt=c39dac16eb6c7b7e864503b9cc06bfa6;
|
||||||
|
sessionid=c39dac16eb6c7b7e864503b9cc06bfa6;
|
||||||
|
sessionid_ss=c39dac16eb6c7b7e864503b9cc06bfa6; is_staff_user=false;
|
||||||
|
_bd_ticket_crypt_doamin=2;
|
||||||
|
_bd_ticket_crypt_cookie=d94b00dc5003896c6a41e34592d484b8;
|
||||||
|
__security_server_data_status=1; store-region=cn-zj; store-region-src=uid;
|
||||||
|
SelfTabRedDotControl=%5B%5D;
|
||||||
|
FOLLOW_NUMBER_YELLOW_POINT_INFO=%22MS4wLjABAAAAuFw1NBpBldrgd6kUkSzXm882qpOX-nkmG2jMSHiXoxk%2F1728748800000%2F0%2F1728717264795%2F0%22;
|
||||||
|
sid_guard=c39dac16eb6c7b7e864503b9cc06bfa6%7C1728717275%7C5184000%7CWed%2C+11-Dec-2024+07%3A14%3A35+GMT;
|
||||||
|
sid_ucp_v1=1.0.0-KGFmNmNkNWVjZGEzM2JjM2ZkYjNhYmVjMDE5OTllZmFkNjI5NjFhY2IKGgi50eCEpM0CENvDqLgGGO8xIAw4AkDxB0gEGgJsZiIgYzM5ZGFjMTZlYjZjN2I3ZTg2NDUwM2I5Y2MwNmJmYTY;
|
||||||
|
ssid_ucp_v1=1.0.0-KGFmNmNkNWVjZGEzM2JjM2ZkYjNhYmVjMDE5OTllZmFkNjI5NjFhY2IKGgi50eCEpM0CENvDqLgGGO8xIAw4AkDxB0gEGgJsZiIgYzM5ZGFjMTZlYjZjN2I3ZTg2NDUwM2I5Y2MwNmJmYTY;
|
||||||
|
publish_badge_show_info=%220%2C0%2C0%2C1728717274522%22;
|
||||||
|
download_guide=%222%2F20241012%2F0%22; pwa2=%220%7C0%7C2%7C0%22;
|
||||||
|
__ac_nonce=0671204d000cf7a511d5;
|
||||||
|
__ac_signature=_02B4Z6wo00f01yb3HygAAIDDpuujdXSjLbcm1xuAAK664i8ozjg4YMd4AG2mOFHsO0Fd1E73.5lD6UR9uQBCgVA979LZPMOF2vQIAb-o024iWhuUuhVSQtIV4tDeNPYFOuzu5B6QgDXDwB-e37;
|
||||||
|
douyin.com; device_web_cpu_core=12; device_web_memory_size=8;
|
||||||
|
architecture=amd64; csrf_session_id=2264bbdaa769999e3eecc34c080de9b2;
|
||||||
|
strategyABtestKey=%221729234131.288%22;
|
||||||
|
volume_info=%7B%22isUserMute%22%3Afalse%2C%22isMute%22%3Atrue%2C%22volume%22%3A0.5%7D;
|
||||||
|
biz_trace_id=0e5f258d; xg_device_score=7.802204888412783;
|
||||||
|
WallpaperGuide=%7B%22showTime%22%3A1729234135617%2C%22closeTime%22%3A0%2C%22showCount%22%3A2%2C%22cursor1%22%3A16%2C%22cursor2%22%3A4%7D;
|
||||||
|
odin_tt=dbdf6a7f9f8c2fb70be9c86c7caca90a829c468db4ef92e609be2988c736b84cc19ce0736278c3f7153f2fd21c9927d3;
|
||||||
|
passport_fe_beating_status=false;
|
||||||
|
stream_player_status_params=%22%7B%5C%22is_auto_play%5C%22%3A0%2C%5C%22is_full_screen%5C%22%3A0%2C%5C%22is_full_webscreen%5C%22%3A0%2C%5C%22is_mute%5C%22%3A1%2C%5C%22is_speed%5C%22%3A1%2C%5C%22is_visible%5C%22%3A0%7D%22;
|
||||||
|
IsDouyinActive=true; home_can_add_dy_2_desktop=%220%22; dy_swidth=1920;
|
||||||
|
dy_sheight=1080;
|
||||||
|
stream_recommend_feed_params=%22%7B%5C%22cookie_enabled%5C%22%3Atrue%2C%5C%22screen_width%5C%22%3A1920%2C%5C%22screen_height%5C%22%3A1080%2C%5C%22browser_online%5C%22%3Atrue%2C%5C%22cpu_core_num%5C%22%3A12%2C%5C%22device_memory%5C%22%3A8%2C%5C%22downlink%5C%22%3A10%2C%5C%22effective_type%5C%22%3A%5C%224g%5C%22%2C%5C%22round_trip_time%5C%22%3A100%7D%22;
|
||||||
|
bd_ticket_guard_client_data=eyJiZC10aWNrZXQtZ3VhcmQtdmVyc2lvbiI6MiwiYmQtdGlja2V0LWd1YXJkLWl0ZXJhdGlvbi12ZXJzaW9uIjoxLCJiZC10aWNrZXQtZ3VhcmQtcmVlLXB1YmxpYy1rZXkiOiJCTjFqYW5GbHBBUXBIeDhoTGtBYmgzQVBNdmhvWXllazI1OTY5WEVmc2xiYnIvcmdTeGQ2bHRlUUsyL25mWFVQWHRzUExhRG8rNjlQUkRMOGNIT21Xdnc9IiwiYmQtdGlja2V0LWd1YXJkLXdlYi12ZXJzaW9uIjoyfQ%3D%3D
|
||||||
|
douyinCompression: true
|
||||||
|
douyinComments: true
|
||||||
|
xiaohongshuCookie: xsecappid=xhs-pc-web;acw_tc=350c17ac654c7a6669103ccf2dd453f9b24be9618e26768e1dc000632195acb0;websectiga=3633fe24d49c7dd0eb923edc8205740f10fdb18b25d424d2a2322c6196d2a4ad;webBuild=4.39.0;sec_poison_id=5a4ce41c-3934-4231-813e-89b9bcca9775;web_session=040069b66645392a9a51e64e27354bb4c13a46;gid=yjJjdKjJ0KvYyjJjdKjJ8lx0jKfxSK2349CY9IKfWAudux28iJ69Eu888y4yJ2Y8yJW4W2fd;a1=1929e692096dhc65i4tx8d7qzezf2mtwyothzhan650000141258;abRequestId=4592d5bf-bf0a-557f-837a-a4236e412134;unread={%22ub%22:%2266f6862e000000001a022a34%22%2C%22ue%22:%226705181f000000001a022078%22%2C%22uc%22:26};webId=c29b9c5db1577e152daaba1e9076a79b
|
||||||
|
queueConcurrency: 1
|
||||||
|
videoDownloadConcurrency: 12
|
||||||
|
lagrangeForwardWebSocket: ws://127.0.0.1:9091/
|
||||||
|
autoclearTrashtime: 0 0 8 * * ?
|
||||||
|
aiBaseURL: http://localhost:8000
|
||||||
|
aiApiKey: eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ1c2VyLWNlbnRlciIsImV4cCI6MTczNzQ0MDkyMiwiaWF0IjoxNzI5NjY0OTIyLCJqdGkiOiJjc2M5ZjZnamRvN2tndWN2cTZwMCIsInR5cCI6InJlZnJlc2giLCJhcHBfaWQiOiJraW1pIiwic3ViIjoiY3Mydjdrb25zbW1zdmRpYzc5M2ciLCJzcGFjZV9pZCI6ImNzMnY3a29uc21tc3ZkaWM3OTFnIiwiYWJzdHJhY3RfdXNlcl9pZCI6ImNzMnY3a29uc21tc3ZkaWM3OTEwIn0.tmu2lOu-4xQeI-8RhkF-SrObWjPLJ5mZAKahvlUnEzy3LL0dPZ_Ruwv5xpHCMIN-k0GnncXotZC5kIuNhEnyIg
|
||||||
|
aiModel: moonshot-v1-8k
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
- {
|
- version: 1.9.2
|
||||||
version: 1.9.2,
|
|
||||||
data:
|
data:
|
||||||
[
|
- 新增<span class="cmd">RBS查看哔哩哔哩状态</span>功能
|
||||||
新增<span class="cmd">RBS查看哔哩哔哩状态</span>功能,
|
- 新增<span class="cmd">自建ncm</span>功能
|
||||||
新增<span class="cmd">自建ncm</span>功能,
|
- 新增<span class="cmd">直播切片</span>功能
|
||||||
新增<span class="cmd">直播切片</span>功能,
|
- 支持<span class="cmd">锅巴</span>插件,方便查看和修改配置
|
||||||
支持<span class="cmd">锅巴</span>插件,方便查看和修改配置,
|
- 输入<span class="cmd">#R帮助</span>获取插件帮助
|
||||||
输入<span class="cmd">#R帮助</span>获取插件帮助,
|
- 输入<span class="cmd">#R更新</span>更新插件
|
||||||
输入<span class="cmd">#R更新</span>更新插件,
|
- 输入<span class="cmd">#R版本</span>获取插件版本
|
||||||
输入<span class="cmd">#R版本</span>获取插件版本,
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
@ -80,6 +80,13 @@ export const REDIS_YUNZAI_ISOVERSEA = "Yz:rconsole:tools:oversea";
|
|||||||
*/
|
*/
|
||||||
export const REDIS_YUNZAI_LAGRANGE = "Yz:rconsole:tools:lagrange";
|
export const REDIS_YUNZAI_LAGRANGE = "Yz:rconsole:tools:lagrange";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存音乐搜索列表
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
export const REDIS_YUNZAI_SONGINFO = "Yz:rconsole:tools:songinfo";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 某些功能的解析白名单
|
* 某些功能的解析白名单
|
||||||
* @type {string}
|
* @type {string}
|
||||||
|
17
model/pick-song.js
Normal file
17
model/pick-song.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import Base from './base.js'
|
||||||
|
|
||||||
|
export default class PickSongList extends Base {
|
||||||
|
constructor (e) {
|
||||||
|
super(e)
|
||||||
|
this.model = 'pick-song'
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 生成版本信息图片 */
|
||||||
|
async getData (songData) {
|
||||||
|
return {
|
||||||
|
...this.screenData,
|
||||||
|
saveId: 'pick-song',
|
||||||
|
songData: songData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
resources/font/江城月湖体 400W.ttf
Normal file
BIN
resources/font/江城月湖体 400W.ttf
Normal file
Binary file not shown.
106
resources/html/pick-song/pick-song.css
Normal file
106
resources/html/pick-song/pick-song.css
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;700&display=swap');
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'number';
|
||||||
|
src: url("../../font/江城月湖体\ 400W.ttf");
|
||||||
|
}
|
||||||
|
|
||||||
|
body,
|
||||||
|
html {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.songList {
|
||||||
|
min-height: 50vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
background: #121212ef;
|
||||||
|
position: relative;
|
||||||
|
padding: 0px 40px 20px 40px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.songListNav {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
height: 100px;
|
||||||
|
margin-top: 30px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navText {
|
||||||
|
font-size: 30px;
|
||||||
|
color: #fff;
|
||||||
|
margin-left: 20px;
|
||||||
|
width: 85%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.songName{
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.singerText{
|
||||||
|
font-size: 25px;
|
||||||
|
color: #aaa;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.navInfo {
|
||||||
|
display: flex;
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navDuration {
|
||||||
|
color: #aaa;
|
||||||
|
width: 40px;
|
||||||
|
font-size: 25px;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navInfo img {
|
||||||
|
width: 90px;
|
||||||
|
height: 90px;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bgicon {
|
||||||
|
position: absolute;
|
||||||
|
top: calc(50% - 100px);
|
||||||
|
left: calc(50% - 85px);
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bgicon img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
opacity: 0.4
|
||||||
|
}
|
||||||
|
|
||||||
|
.number {
|
||||||
|
width: 40px;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 40px;
|
||||||
|
color: #fff;
|
||||||
|
margin-right: 25px;
|
||||||
|
margin-left: -20px;
|
||||||
|
font-family: 'number'
|
||||||
|
}
|
34
resources/html/pick-song/pick-song.html
Normal file
34
resources/html/pick-song/pick-song.html
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>搜索歌单</title>
|
||||||
|
<style>
|
||||||
|
@import url('{{pluResPath}}html/pick-song/pick-song.css');
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="songList">
|
||||||
|
{{each songData info key}}
|
||||||
|
<div class="songListNav">
|
||||||
|
<div class="navInfo">
|
||||||
|
<div class="number">{{ key+1 }}</div>
|
||||||
|
<img src="{{ info.cover }}" alt="">
|
||||||
|
<div class="navText">
|
||||||
|
<div class="songName">{{ info.songName }}</div>
|
||||||
|
<div class="singerText">{{ info.singerName }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="navDuration">{{ info.duration }}</div>
|
||||||
|
</div>
|
||||||
|
{{ /each }}
|
||||||
|
<div class="bgicon">
|
||||||
|
<img src="{{pluResPath}}img/icon/neteaseRank.png" alt="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
BIN
resources/img/icon/neteaseRank.png
Normal file
BIN
resources/img/icon/neteaseRank.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.0 KiB |
11
utils/other.js
Normal file
11
utils/other.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export function formatTime(timestamp) {
|
||||||
|
const totalSeconds = Math.floor(timestamp / 1000); // 转换为秒
|
||||||
|
const minutes = Math.floor(totalSeconds / 60); // 分钟
|
||||||
|
const seconds = totalSeconds % 60; // 秒钟
|
||||||
|
|
||||||
|
// 补零格式化
|
||||||
|
const formattedMinutes = String(minutes).padStart(2, '0');
|
||||||
|
const formattedSeconds = String(seconds).padStart(2, '0');
|
||||||
|
|
||||||
|
return `${formattedMinutes}:${formattedSeconds}`;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user