mirror of
https://github.com/Jerryplusy/rc-plugin.git
synced 2025-10-14 16:19:18 +00:00
🌟 feat: V1.3.0 新增油管解析
1. 新增油管解析 2. 修复tiktok在海外服务器无法解析问题 3. 更换翻译引擎为全局引擎,并初次使用在油管解析中
This commit is contained in:
parent
ef75e7c12c
commit
083b4ea613
20
README.md
20
README.md
@ -38,7 +38,7 @@ utils -- 工具类
|
||||
git clone https://gitee.com/kyrzy0416/rconsole-plugin.git ./plugins/rconsole-plugin/
|
||||
```
|
||||
|
||||
2.【必要】在`Yunzai-Bot`目录下安装axios(0.27.2)、魔法工具(tunnel)、哔哩哔哩总结(chatgpt-api)依赖
|
||||
2.【必要】在`Yunzai-Bot`目录下安装axios(0.27.2)、魔法工具(tunnel)
|
||||
|
||||
|
||||
```shell
|
||||
@ -53,6 +53,19 @@ sudo apt-get install ffmpeg
|
||||
# 其他linux参考(群友推荐):https://gitee.com/baihu433/ffmpeg
|
||||
# Windows 参考:https://www.jianshu.com/p/5015a477de3c
|
||||
````
|
||||
油管解析需要 yt-dlp 的依赖才能完成解析(三选一):
|
||||
```shell
|
||||
# 三选一
|
||||
# ubuntu (国内 or 国外,且安装了snap)
|
||||
snap install yt-dlp
|
||||
# debian 海外
|
||||
curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o ~/.local/bin/yt-dlp
|
||||
chmod a+rx ~/.local/bin/yt-dlp
|
||||
# debian 国内
|
||||
curl -L https://ghproxy.net/https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o ~/.local/bin/yt-dlp
|
||||
chmod a+rx ~/.local/bin/yt-dlp
|
||||
```
|
||||
|
||||
4. 【可选】小程序解析适配了:
|
||||
* 喵崽:[Yoimiya / Miao-Yunzai](https://gitee.com/yoimiya-kokomi/Miao-Yunzai)
|
||||
* TRSS:[时雨◎星空 / Yunzai](https://gitee.com/TimeRainStarSky/Yunzai)
|
||||
@ -118,7 +131,7 @@ sudo apt-get install ffmpeg
|
||||

|
||||
|
||||
## 📝 计划功能
|
||||
- [ ] YouTube解析(这个可能要🕊一久)
|
||||
- [x] YouTube解析(这个可能要🕊一久)
|
||||
- [ ] Instagram解析修复
|
||||
- [ ] 单张图片解析
|
||||
- [ ] 视频解析
|
||||
@ -142,6 +155,9 @@ sudo apt-get install ffmpeg
|
||||
* [一杯凉](https://gitee.com/yibeiliang) 提供小程序解析冲突解决方案
|
||||
* [x0rz4](https://gitee.com/x0rz4) 提供依赖掉包解决方案
|
||||
|
||||
感谢以下框架的开源:
|
||||
YouTube解析参考了:[yt-dlp:A youtube-dl fork with additional features and fixes](https://github.com/yt-dlp/yt-dlp)
|
||||
|
||||
## ☕ 请我喝一杯瑞幸咖啡
|
||||
如果你觉得插件能帮助到你增进好友关系,那么你可以在有条件的情况下[请我喝一杯瑞幸咖啡](https://afdian.net/a/zhiyu1998),这是我开源这个插件的最大动力!
|
||||
感谢以下朋友的支持!(排名不分多少)
|
||||
|
161
apps/tools.js
161
apps/tools.js
@ -12,9 +12,10 @@ import { parseUrl, parseM3u8, downloadM3u8Videos, mergeAcFileToMp4 } from "../ut
|
||||
import {
|
||||
transMap,
|
||||
douyinTypeMap,
|
||||
RESTRICTION_DESCRIPTION, XHS_NO_WATERMARK_HEADER,
|
||||
DIVIDING_LINE,
|
||||
XHS_NO_WATERMARK_HEADER, REDIS_YUNZAI_ISOVERSEA,
|
||||
} from "../constants/constant.js";
|
||||
import { formatBiliInfo, getIdVideo, secondsToTime } from "../utils/common.js";
|
||||
import {containsChinese, formatBiliInfo, getIdVideo, secondsToTime} from "../utils/common.js";
|
||||
import config from "../model/index.js";
|
||||
import Translate from "../utils/trans-strategy.js";
|
||||
import * as xBogus from "../utils/x-bogus.cjs";
|
||||
@ -26,6 +27,8 @@ import TokenBucket from "../utils/token-bucket.js";
|
||||
import { getWbi } from "../utils/biliWbi.js";
|
||||
import { BILI_SUMMARY } from "../constants/bili.js";
|
||||
import { XHS_VIDEO } from "../constants/xhs.js";
|
||||
import child_process from 'node:child_process'
|
||||
import { getAudio, getVideo } from "../utils/y2b.js";
|
||||
|
||||
export class tools extends plugin {
|
||||
constructor() {
|
||||
@ -80,6 +83,11 @@ export class tools extends plugin {
|
||||
fnc: "clearTrash",
|
||||
permission: "master",
|
||||
},
|
||||
{
|
||||
reg: "^#设置海外解析$",
|
||||
fnc: "setOversea",
|
||||
permission: "master",
|
||||
},
|
||||
{
|
||||
reg: "(h5app.kuwo.cn)",
|
||||
fnc: "bodianMusic",
|
||||
@ -88,6 +96,10 @@ export class tools extends plugin {
|
||||
reg: "(kuaishou.com)",
|
||||
fnc: "kuaishou",
|
||||
},
|
||||
{
|
||||
reg: "(youtube.com)",
|
||||
fnc: "y2b"
|
||||
}
|
||||
],
|
||||
});
|
||||
// 配置文件
|
||||
@ -104,6 +116,12 @@ export class tools extends plugin {
|
||||
this.biliDuration = this.toolsConfig.biliDuration;
|
||||
// 加载抖音Cookie
|
||||
this.douyinCookie = this.toolsConfig.douyinCookie;
|
||||
// 翻译引擎
|
||||
this.translateEngine = new Translate({
|
||||
translateAppId: this.toolsConfig.translateAppId,
|
||||
translateSecret: this.toolsConfig.translateSecret,
|
||||
proxy: this.myProxy,
|
||||
});
|
||||
}
|
||||
|
||||
// 翻译插件
|
||||
@ -118,13 +136,8 @@ export class tools extends plugin {
|
||||
return;
|
||||
}
|
||||
const place = msg.slice(1 + language[1].length)
|
||||
const translateEngine = new Translate({
|
||||
translateAppId: this.toolsConfig.translateAppId,
|
||||
translateSecret: this.toolsConfig.translateSecret,
|
||||
proxy: this.myProxy,
|
||||
});
|
||||
// 如果没有百度那就Google
|
||||
const translateResult = await translateEngine.translate(place, language[1]);
|
||||
const translateResult = await this.translateEngine.translate(place, language[1]);
|
||||
e.reply(translateResult.trim(), true);
|
||||
return true;
|
||||
}
|
||||
@ -216,6 +229,8 @@ export class tools extends plugin {
|
||||
const urlShortRex = /(http:|https:)\/\/vt.tiktok.com\/[A-Za-z\d._?%&+\-=\/#]*/g;
|
||||
const urlShortRex2 = /(http:|https:)\/\/vm.tiktok.com\/[A-Za-z\d._?%&+\-=\/#]*/g;
|
||||
let url = e.msg.trim();
|
||||
// 判断是否是海外服务器
|
||||
const isOversea = await this.isOverseasServer();
|
||||
// 短号处理
|
||||
if (url.includes("vt.tiktok")) {
|
||||
const temp_url = urlShortRex.exec(url)[0];
|
||||
@ -223,7 +238,7 @@ export class tools extends plugin {
|
||||
redirect: "follow",
|
||||
follow: 10,
|
||||
timeout: 10000,
|
||||
agent: new HttpProxyAgent(this.myProxy),
|
||||
agent: isOversea ? '' : new HttpProxyAgent(this.myProxy),
|
||||
}).then(resp => {
|
||||
url = resp.url;
|
||||
});
|
||||
@ -234,7 +249,7 @@ export class tools extends plugin {
|
||||
redirect: "follow",
|
||||
follow: 10,
|
||||
timeout: 10000,
|
||||
agent: new HttpProxyAgent(this.myProxy),
|
||||
agent: isOversea ? '' : new HttpProxyAgent(this.myProxy),
|
||||
}).then(resp => {
|
||||
url = resp.url;
|
||||
});
|
||||
@ -255,13 +270,13 @@ export class tools extends plugin {
|
||||
// redirect: "follow",
|
||||
follow: 10,
|
||||
timeout: 10000,
|
||||
agent: new HttpsProxyAgent(this.myProxy),
|
||||
agent: isOversea ? '' : new HttpProxyAgent(this.myProxy),
|
||||
})
|
||||
.then(async resp => {
|
||||
const respJson = await resp.json();
|
||||
const data = respJson.aweme_list[0];
|
||||
e.reply(`识别:tiktok, ${ data.desc }`);
|
||||
this.downloadVideo(data.video.play_addr.url_list[0], true).then(video => {
|
||||
this.downloadVideo(data.video.play_addr.url_list[0], !isOversea).then(video => {
|
||||
e.reply(
|
||||
segment.video(
|
||||
`${ this.defaultPath }${ this.e.group_id || this.e.user_id }/temp.mp4`,
|
||||
@ -343,7 +358,7 @@ export class tools extends plugin {
|
||||
biliInfo.unshift(segment.image(pic))
|
||||
// 限制视频解析
|
||||
const durationInMinutes = (curDuration / 60).toFixed(0);
|
||||
biliInfo.push(`${ RESTRICTION_DESCRIPTION }\n当前视频时长约:${ durationInMinutes }分钟,\n大于管理员设置的最大时长 ${ this.biliDuration / 60 } 分钟!`)
|
||||
biliInfo.push(`${ DIVIDING_LINE.replace('{}', '限制说明') }\n当前视频时长约:${ durationInMinutes }分钟,\n大于管理员设置的最大时长 ${ this.biliDuration / 60 } 分钟!`)
|
||||
summary && biliInfo.push(`\n${ summary }`);
|
||||
e.reply(biliInfo);
|
||||
return true;
|
||||
@ -889,6 +904,102 @@ export class tools extends plugin {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* youtube解析
|
||||
* @param e
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async y2b(e) {
|
||||
const urlRex = /(?:https?:\/\/)?www\.youtube\.com\/[A-Za-z\d._?%&+\-=\/#]*/g;
|
||||
let url = urlRex.exec(e.msg)[0];
|
||||
// 获取url查询参数
|
||||
const query = querystring.parse(url.split("?")[1]);
|
||||
let p = query?.p || '0';
|
||||
let v = query?.v;
|
||||
// 判断是否是海外服务器,默认为false
|
||||
const isProxy = !(await this.isOverseasServer());
|
||||
|
||||
let audios = [], videos = [];
|
||||
let bestAudio = {}, bestVideo = {};
|
||||
|
||||
let rs = { title: '', thumbnail: '', formats: [] };
|
||||
try {
|
||||
let cmd = `yt-dlp --print-json --skip-download ${this.y2bCk !== undefined ? `--cookies ${this.y2bCk}` : ''} '${url}' ${isProxy ? '--proxy http://127.0.0.1:7890' : ''} 2> /dev/null`
|
||||
console.log('解析视频, 命令:', cmd);
|
||||
rs = child_process.execSync(cmd).toString();
|
||||
try {
|
||||
rs = JSON.parse(rs);
|
||||
} catch (error) {
|
||||
let cmd = `yt-dlp --print-json --skip-download ${this.y2bCk !== undefined ? `--cookies ${this.y2bCk}` : ''} '${url}?p=1' ${isProxy ? '--proxy http://127.0.0.1:7890' : ''} 2> /dev/null`;
|
||||
logger.mark('尝试分P, 命令:', cmd);
|
||||
rs = child_process.execSync(cmd).toString();
|
||||
rs = JSON.parse(rs);
|
||||
p = '1';
|
||||
// url = `${msg.url}?p=1`;
|
||||
}
|
||||
if (!containsChinese(rs.title)) {
|
||||
// 启用翻译引擎翻译不是中文的标题
|
||||
const transedTitle = await this.translateEngine.translate(rs.title, '中');
|
||||
// const transedDescription = await this.translateEngine.translate(rs.description, '中');
|
||||
e.reply(`识别:油管,
|
||||
${rs.title.trim()}\n
|
||||
${DIVIDING_LINE.replace("{}", "R插件翻译引擎服务")}\n
|
||||
${transedTitle}\n
|
||||
${rs.description}
|
||||
`);
|
||||
} else {
|
||||
e.reply(`识别:油管,${rs.title}`);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(error.toString());
|
||||
e.reply("解析失败")
|
||||
return;
|
||||
}
|
||||
|
||||
// 格式化
|
||||
rs.formats.forEach(it => {
|
||||
let length = (it.filesize_approx ? '≈' : '') + ((it.filesize || it.filesize_approx || 0) / 1024 / 1024).toFixed(2);
|
||||
if (it.audio_ext != 'none') {
|
||||
audios.push(getAudio(it.format_id, it.ext, (it.abr || 0).toFixed(0), it.format_note || it.format || '', length));
|
||||
} else if (it.video_ext != 'none') {
|
||||
videos.push(getVideo(it.format_id, it.ext, it.resolution, it.height, (it.vbr || 0).toFixed(0), it.format_note || it.format || '', length));
|
||||
}
|
||||
});
|
||||
|
||||
// 寻找最佳的分辨率
|
||||
// bestAudio = Array.from(audios).sort((a, b) => a.rate - b.rate)[audios.length - 1];
|
||||
// bestVideo = Array.from(videos).sort((a, b) => a.rate - b.rate)[videos.length - 1];
|
||||
|
||||
// 较为有性能的分辨率
|
||||
logger.info(videos)
|
||||
bestVideo = Array.from(videos).filter(item => item.scale.includes("720"))[0];
|
||||
bestAudio = Array.from(audios).filter(item => item.format === 'm4a')[0];
|
||||
logger.info({
|
||||
bestVideo,
|
||||
bestAudio
|
||||
})
|
||||
|
||||
// 格式化yt-dlp的请求
|
||||
const format = `${bestVideo.id}x${bestAudio.id}`
|
||||
// 下载地址格式化
|
||||
const path = `${v}${ p ? `/p${p}` : '' }`;
|
||||
const fullpath = `${ this.defaultPath }${ this.e.group_id || this.e.user_id }/${path}`;
|
||||
// yt-dlp下载
|
||||
let cmd = //`cd '${__dirname}' && (cd tmp > /dev/null || (mkdir tmp && cd tmp)) &&` +
|
||||
`yt-dlp ${this.y2bCk !== undefined ? `--cookies ${this.y2bCk}` : ''} https://youtu.be/${v} -f ${format.replace('x', '+')} ` +
|
||||
`-o '${fullpath}/${v}.%(ext)s' ${isProxy ? '--proxy http://127.0.0.1:7890' : ''} -k --write-info-json`;
|
||||
try {
|
||||
await child_process.execSync(cmd);
|
||||
e.reply(segment.video(`${fullpath}/${v}.mp4`))
|
||||
// 清理文件
|
||||
await deleteFolderRecursive(fullpath);
|
||||
} catch (error) {
|
||||
logger.error(error.toString());
|
||||
e.reply("y2b下载失败");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 哔哩哔哩下载
|
||||
* @param title
|
||||
@ -1054,15 +1165,33 @@ export class tools extends plugin {
|
||||
}
|
||||
}
|
||||
|
||||
async setOversea(e) {
|
||||
// 查看当前设置
|
||||
let os;
|
||||
if ((await redis.exists(REDIS_YUNZAI_ISOVERSEA))) {
|
||||
os = JSON.parse(await redis.get(REDIS_YUNZAI_ISOVERSEA)).os;
|
||||
}
|
||||
// 设置
|
||||
os = ~os
|
||||
await redis.set(
|
||||
REDIS_YUNZAI_ISOVERSEA,
|
||||
JSON.stringify({
|
||||
os: os,
|
||||
}),
|
||||
);
|
||||
e.reply(`当前服务器:${os ? '海外服务器' : '国内服务器'}`)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否是海外服务器
|
||||
* @return {Promise<Boolean>}
|
||||
*/
|
||||
async isOverseasServer() {
|
||||
const isOS = "Yz:rconsole:tools:oversea";
|
||||
// 如果第一次使用没有值就设置
|
||||
if (!(await redis.exists(isOS))) {
|
||||
if (!(await redis.exists(REDIS_YUNZAI_ISOVERSEA))) {
|
||||
await redis.set(
|
||||
REDIS_YUNZAI_ISOVERSEA,
|
||||
JSON.stringify({
|
||||
os: false,
|
||||
}),
|
||||
@ -1070,7 +1199,7 @@ export class tools extends plugin {
|
||||
return true;
|
||||
}
|
||||
// 如果有就取出来
|
||||
return JSON.parse(redis.get(isOS)).os;
|
||||
return JSON.parse((await redis.get(REDIS_YUNZAI_ISOVERSEA))).os;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -41,6 +41,9 @@
|
||||
- icon: bilimusic
|
||||
title: "bili音乐+链接"
|
||||
desc: 哔哩哔哩音乐分享实时下载
|
||||
- icon: youtube
|
||||
title: "youtube.com"
|
||||
desc: 油管学习版分享实时下载
|
||||
- icon: 推特
|
||||
title: "小蓝鸟"
|
||||
desc: 推特学习版分享实时下载
|
||||
|
@ -1,10 +1,10 @@
|
||||
- {
|
||||
version: 1.2.3,
|
||||
version: 1.3.0,
|
||||
data:
|
||||
[
|
||||
新增<span class="cmd">油管解析</span>功能,
|
||||
新增<span class="cmd">小红书无水印下载</span>功能,
|
||||
新增<span class="cmd">哔哩哔哩官方AI总结</span>功能,
|
||||
新增<span class="cmd">哔哩哔哩音乐提取</span>功能,
|
||||
新增<span class="cmd">快手解析</span>功能,
|
||||
支持<span class="cmd">锅巴</span>插件,方便查看和修改配置,
|
||||
添加<span class="cmd">#R帮助</span>获取插件帮助,
|
||||
|
@ -59,4 +59,10 @@ export const XHS_NO_WATERMARK_HEADER = {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 UBrowser/6.2.4098.3 Safari/537.36',
|
||||
}
|
||||
|
||||
export const RESTRICTION_DESCRIPTION = "\n-----------------------限制说明-----------------------"
|
||||
/**
|
||||
* 分割线
|
||||
* @type {string}
|
||||
*/
|
||||
export const DIVIDING_LINE = "\n-----------------------{}-----------------------"
|
||||
|
||||
export const REDIS_YUNZAI_ISOVERSEA = "Yz:rconsole:tools:oversea";
|
BIN
resources/img/icon/youtube.png
Normal file
BIN
resources/img/icon/youtube.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
@ -9,7 +9,7 @@ import {TEN_THOUSAND} from "../constants/constant.js";
|
||||
/**
|
||||
* 请求模板
|
||||
*/
|
||||
class jFeatch {
|
||||
export class jFetch {
|
||||
async get(url) {
|
||||
const r = await fetch(url);
|
||||
return await r.json();
|
||||
@ -26,7 +26,7 @@ class jFeatch {
|
||||
* @param time cron
|
||||
* @param isAutoPush 是否推送(开关)
|
||||
*/
|
||||
function autoTask(func, time, groupList, isAutoPush = false) {
|
||||
export function autoTask(func, time, groupList, isAutoPush = false) {
|
||||
if (isAutoPush) {
|
||||
schedule.scheduleJob(time, () => {
|
||||
// 正常传输
|
||||
@ -55,7 +55,7 @@ function autoTask(func, time, groupList, isAutoPush = false) {
|
||||
* @param delay
|
||||
* @returns {Promise<unknown>}
|
||||
*/
|
||||
function retry(func, maxRetries = 3, delay = 1000) {
|
||||
export function retry(func, maxRetries = 3, delay = 1000) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const attempt = (remainingTries) => {
|
||||
func()
|
||||
@ -79,7 +79,7 @@ function retry(func, maxRetries = 3, delay = 1000) {
|
||||
* @param filename
|
||||
* @returns {Promise<unknown>}
|
||||
*/
|
||||
function downloadPDF (url, filename) {
|
||||
export function downloadPDF (url, filename) {
|
||||
return axios({
|
||||
url: url,
|
||||
responseType: "stream",
|
||||
@ -102,7 +102,7 @@ function downloadPDF (url, filename) {
|
||||
* @param url
|
||||
* @returns {Promise<string|string|null>}
|
||||
*/
|
||||
async function getIdVideo(url) {
|
||||
export async function getIdVideo(url) {
|
||||
const matching = url.includes("/video/");
|
||||
if (!matching) {
|
||||
this.e.reply("没找到,正在获取随机视频!");
|
||||
@ -112,7 +112,7 @@ async function getIdVideo(url) {
|
||||
return idVideo.length > 19 ? idVideo.substring(0, idVideo.indexOf("?")) : idVideo;
|
||||
}
|
||||
|
||||
function generateRandomStr(randomlength = 16){
|
||||
export function generateRandomStr(randomlength = 16){
|
||||
const base_str = 'ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789='
|
||||
let random_str = ''
|
||||
for (let i = 0; i < randomlength; i++) {
|
||||
@ -128,7 +128,7 @@ function generateRandomStr(randomlength = 16){
|
||||
* @param redirect 是否要重定向
|
||||
* @returns {Promise<unknown>}
|
||||
*/
|
||||
async function downloadMp3(mp3Url, path, redirect = "manual") {
|
||||
export async function downloadMp3(mp3Url, path, redirect = "manual") {
|
||||
return fetch(mp3Url, {
|
||||
headers: {
|
||||
"User-Agent":
|
||||
@ -178,7 +178,7 @@ const dataProcessing = data => {
|
||||
* @param data
|
||||
* @return {string}
|
||||
*/
|
||||
function formatBiliInfo(data) {
|
||||
export function formatBiliInfo(data) {
|
||||
return Object.keys(data).map(key => `${key}:${dataProcessing(data[key])}`).join(' | ');
|
||||
}
|
||||
|
||||
@ -187,7 +187,7 @@ function formatBiliInfo(data) {
|
||||
* @param seconds
|
||||
* @return {string}
|
||||
*/
|
||||
function secondsToTime(seconds) {
|
||||
export function secondsToTime(seconds) {
|
||||
const pad = (num, size) => num.toString().padStart(size, '0');
|
||||
|
||||
let hours = Math.floor(seconds / 3600);
|
||||
@ -201,4 +201,29 @@ function secondsToTime(seconds) {
|
||||
return `${pad(hours, 2)}:${pad(minutes, 2)}:${pad(secs, 2)}`;
|
||||
}
|
||||
|
||||
export { jFeatch, autoTask, retry, getIdVideo, generateRandomStr, downloadMp3, dataProcessing, formatBiliInfo, secondsToTime };
|
||||
/**
|
||||
* 判断字符串是否是中文(全局判断)
|
||||
* @param str
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isChinese(str) {
|
||||
return /^[\u4e00-\u9fff]+$/.test(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字符串是否包含中文
|
||||
* @param str
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function containsChinese(str) {
|
||||
return /[\u4e00-\u9fff]/.test(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字符串是否包含中文 && 检测标点符号
|
||||
* @param str
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function containsChineseOrPunctuation(str) {
|
||||
return /[\u4e00-\u9fff\uff00-\uffef]/.test(str);
|
||||
}
|
||||
|
27
utils/y2b.js
Normal file
27
utils/y2b.js
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* y2b 音频信息
|
||||
* @param id
|
||||
* @param format
|
||||
* @param rate
|
||||
* @param info
|
||||
* @param size
|
||||
* @returns {{size: (string|*), rate: (string|*), format, id, info}}
|
||||
*/
|
||||
export function getAudio(id, format, rate, info, size) {
|
||||
return { id, format, rate: rate == 0 ? '未知' : rate, info, size: size == 0 ? '未知' : size };
|
||||
}
|
||||
|
||||
/**
|
||||
* y2b 视频信息
|
||||
* @param id
|
||||
* @param format
|
||||
* @param scale
|
||||
* @param frame
|
||||
* @param rate
|
||||
* @param info
|
||||
* @param size
|
||||
* @returns {{size: (string|*), rate: (string|*), format, scale, id, frame, info}}
|
||||
*/
|
||||
export function getVideo(id, format, scale, frame, rate, info, size) {
|
||||
return { id, format, scale, frame, rate: rate == 0 ? '未知' : rate, info, size: size == 0 ? '未知' : size };
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user