mirror of
https://github.com/Jerryplusy/rc-plugin.git
synced 2025-10-14 16:19:18 +00:00
✨ feat: 增加哔哩哔哩解析自适应时间解析算法
This commit is contained in:
parent
4ab03fef25
commit
8aac44c724
@ -10,7 +10,7 @@ import HttpProxyAgent from "https-proxy-agent";
|
|||||||
import { mkdirsSync } from "../utils/file.js";
|
import { mkdirsSync } from "../utils/file.js";
|
||||||
import { downloadBFile, getDownloadUrl, mergeFileToMp4, getDynamic } from "../utils/bilibili.js";
|
import { downloadBFile, getDownloadUrl, mergeFileToMp4, getDynamic } from "../utils/bilibili.js";
|
||||||
import { parseUrl, parseM3u8, downloadM3u8Videos, mergeAcFileToMp4 } from "../utils/acfun.js";
|
import { parseUrl, parseM3u8, downloadM3u8Videos, mergeAcFileToMp4 } from "../utils/acfun.js";
|
||||||
import { transMap, douyinTypeMap, XHS_CK, TEN_THOUSAND } from "../utils/constant.js";
|
import { transMap, douyinTypeMap, XHS_CK, TEN_THOUSAND, BILI_DURATION } from "../utils/constant.js";
|
||||||
import { getIdVideo, generateRandomStr } from "../utils/common.js";
|
import { getIdVideo, generateRandomStr } from "../utils/common.js";
|
||||||
import config from "../model/index.js";
|
import config from "../model/index.js";
|
||||||
import Translate from "../utils/trans-strategy.js";
|
import Translate from "../utils/trans-strategy.js";
|
||||||
@ -332,7 +332,7 @@ export class tools extends plugin {
|
|||||||
// 视频信息获取例子:http://api.bilibili.com/x/web-interface/view?bvid=BV1hY411m7cB
|
// 视频信息获取例子:http://api.bilibili.com/x/web-interface/view?bvid=BV1hY411m7cB
|
||||||
// 请求视频信息
|
// 请求视频信息
|
||||||
const videoInfo = await getVideoInfo(url);
|
const videoInfo = await getVideoInfo(url);
|
||||||
const { title, desc, dynamic, stat, aid, cid } = videoInfo;
|
const { title, desc, duration, dynamic, stat, aid, cid } = videoInfo;
|
||||||
// 视频信息
|
// 视频信息
|
||||||
let { view, danmaku, reply, favorite, coin, share, like } = stat;
|
let { view, danmaku, reply, favorite, coin, share, like } = stat;
|
||||||
// 数据处理
|
// 数据处理
|
||||||
@ -341,7 +341,7 @@ export class tools extends plugin {
|
|||||||
};
|
};
|
||||||
// 格式化数据
|
// 格式化数据
|
||||||
const combineContent =
|
const combineContent =
|
||||||
`点赞:${dataProcessing(like)} | 硬币:${dataProcessing(coin)} | 收藏:${dataProcessing(
|
`\n点赞:${dataProcessing(like)} | 硬币:${dataProcessing(coin)} | 收藏:${dataProcessing(
|
||||||
favorite,
|
favorite,
|
||||||
)} | 分享:${dataProcessing(share)}\n` +
|
)} | 分享:${dataProcessing(share)}\n` +
|
||||||
`总播放量:${dataProcessing(view)} | 弹幕数量:${dataProcessing(
|
`总播放量:${dataProcessing(view)} | 弹幕数量:${dataProcessing(
|
||||||
@ -350,11 +350,11 @@ export class tools extends plugin {
|
|||||||
`简介:${desc}`;
|
`简介:${desc}`;
|
||||||
e.reply([`识别:哔哩哔哩:${title}`, combineContent]);
|
e.reply([`识别:哔哩哔哩:${title}`, combineContent]);
|
||||||
|
|
||||||
await getDownloadUrl(url)
|
await getDownloadUrl(url, duration > BILI_DURATION)
|
||||||
.then(data => {
|
.then(data => {
|
||||||
this.downBili(`${path}temp`, data.videoUrl, data.audioUrl)
|
this.downBili(`${path}temp`, data.videoUrl, data.audioUrl)
|
||||||
.then(data => {
|
.then(_ => {
|
||||||
e.reply(segment.video(`${path}temp.mp4`));
|
e.reply(segment.video(`${path}temp.mp4`));
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
logger.error(err);
|
logger.error(err);
|
||||||
@ -966,8 +966,7 @@ export class tools extends plugin {
|
|||||||
title + "-video.m4s",
|
title + "-video.m4s",
|
||||||
_.throttle(
|
_.throttle(
|
||||||
value =>
|
value =>
|
||||||
logger.mark("download-progress", {
|
logger.mark("视频下载进度", {
|
||||||
type: "video",
|
|
||||||
data: value,
|
data: value,
|
||||||
}),
|
}),
|
||||||
1000,
|
1000,
|
||||||
@ -978,15 +977,14 @@ export class tools extends plugin {
|
|||||||
title + "-audio.m4s",
|
title + "-audio.m4s",
|
||||||
_.throttle(
|
_.throttle(
|
||||||
value =>
|
value =>
|
||||||
logger.mark("download-progress", {
|
logger.mark("音频下载进度", {
|
||||||
type: "audio",
|
|
||||||
data: value,
|
data: value,
|
||||||
}),
|
}),
|
||||||
1000,
|
1000,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
]).then(data => {
|
]).then(data => {
|
||||||
return mergeFileToMp4(data[0].fullFileName, data[1].fullFileName, title + ".mp4");
|
return mergeFileToMp4(data[0].fullFileName, data[1].fullFileName, `${title}.mp4`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ async function getVideoInfo(url) {
|
|||||||
return {
|
return {
|
||||||
title: respData.title,
|
title: respData.title,
|
||||||
desc: respData.desc,
|
desc: respData.desc,
|
||||||
|
duration: respData.duration,
|
||||||
dynamic: respJson.data.dynamic,
|
dynamic: respJson.data.dynamic,
|
||||||
stat: respData.stat,
|
stat: respData.stat,
|
||||||
aid: respData.aid,
|
aid: respData.aid,
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import child_process from 'node:child_process'
|
import child_process from 'node:child_process'
|
||||||
|
import util from "util";
|
||||||
|
|
||||||
function downloadBFile (url, fullFileName, progressCallback) {
|
async function downloadBFile (url, fullFileName, progressCallback) {
|
||||||
return axios
|
return axios
|
||||||
.get(url, {
|
.get(url, {
|
||||||
responseType: 'stream',
|
responseType: 'stream',
|
||||||
@ -34,7 +35,7 @@ function downloadBFile (url, fullFileName, progressCallback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDownloadUrl (url) {
|
async function getDownloadUrl (url, isLargeVideo=false) {
|
||||||
return axios
|
return axios
|
||||||
.get(url, {
|
.get(url, {
|
||||||
headers: {
|
headers: {
|
||||||
@ -47,12 +48,16 @@ function getDownloadUrl (url) {
|
|||||||
const info = JSON.parse(
|
const info = JSON.parse(
|
||||||
data.match(/<script>window\.__playinfo__=({.*})<\/script><script>/)?.[1],
|
data.match(/<script>window\.__playinfo__=({.*})<\/script><script>/)?.[1],
|
||||||
);
|
);
|
||||||
|
// 如果是大视频直接最低分辨率
|
||||||
|
const level = isLargeVideo ? (Math.min(info?.data?.dash?.video.length - 1, info?.data?.dash?.audio.length - 1)) : 0;
|
||||||
const videoUrl =
|
const videoUrl =
|
||||||
info?.data?.dash?.video?.[0]?.baseUrl ?? info?.data?.dash?.video?.[0]?.backupUrl?.[0];
|
info?.data?.dash?.video?.[level]?.baseUrl ?? info?.data?.dash?.video?.[level]?.backupUrl?.[0];
|
||||||
|
|
||||||
const audioUrl =
|
const audioUrl =
|
||||||
info?.data?.dash?.audio?.[0]?.baseUrl ?? info?.data?.dash?.audio?.[0]?.backupUrl?.[0];
|
info?.data?.dash?.audio?.[level]?.baseUrl ?? info?.data?.dash?.audio?.[level]?.backupUrl?.[0];
|
||||||
const title = data.match(/title="(.*?)"/)?.[1]?.replaceAll?.(/\\|\/|:|\*|\?|"|<|>|\|/g, '');
|
const title = data.match(/title="(.*?)"/)?.[1]?.replaceAll?.(/\\|\/|:|\*|\?|"|<|>|\|/g, '');
|
||||||
|
|
||||||
|
|
||||||
if (videoUrl && audioUrl) {
|
if (videoUrl && audioUrl) {
|
||||||
return { videoUrl, audioUrl, title };
|
return { videoUrl, audioUrl, title };
|
||||||
}
|
}
|
||||||
@ -61,9 +66,7 @@ function getDownloadUrl (url) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function mergeFileToMp4 (vFullFileName, aFullFileName, outputFileName, shouldDelete = true) {
|
async function mergeFileToMp4 (vFullFileName, aFullFileName, outputFileName, shouldDelete = true) {
|
||||||
let cmd = 'ffmpeg';
|
|
||||||
|
|
||||||
// 判断当前环境
|
// 判断当前环境
|
||||||
let env;
|
let env;
|
||||||
if (process.platform === "win32") {
|
if (process.platform === "win32") {
|
||||||
@ -74,30 +77,26 @@ function mergeFileToMp4 (vFullFileName, aFullFileName, outputFileName, shouldDel
|
|||||||
PATH: '/usr/local/bin:' + child_process.execSync('echo $PATH').toString(),
|
PATH: '/usr/local/bin:' + child_process.execSync('echo $PATH').toString(),
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
console.log("暂时不支持当前操作系统!")
|
logger.error("暂时不支持当前操作系统!")
|
||||||
}
|
}
|
||||||
|
const execFile = util.promisify(child_process.execFile);
|
||||||
|
try {
|
||||||
|
const cmd = 'ffmpeg';
|
||||||
|
const args = ['-y', '-i', vFullFileName, '-i', aFullFileName, '-c', 'copy', outputFileName];
|
||||||
|
await execFile(cmd, args, { env });
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
if (shouldDelete) {
|
||||||
child_process.exec(
|
await fs.promises.unlink(vFullFileName);
|
||||||
`${ cmd } -y -i "${ vFullFileName }" -i "${ aFullFileName }" -c copy "${ outputFileName }"`,
|
await fs.promises.unlink(aFullFileName);
|
||||||
{ env },
|
}
|
||||||
err => {
|
|
||||||
if (shouldDelete) {
|
|
||||||
fs.unlink(vFullFileName, f => f);
|
|
||||||
fs.unlink(aFullFileName, f => f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err) {
|
return { outputFileName };
|
||||||
reject(err);
|
} catch (err) {
|
||||||
}
|
throw err;
|
||||||
|
}
|
||||||
resolve({ outputFileName });
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDynamic(dynamicId) {
|
async function getDynamic(dynamicId) {
|
||||||
const dynamicApi = `https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/get_dynamic_detail?dynamic_id=${dynamicId}`
|
const dynamicApi = `https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/get_dynamic_detail?dynamic_id=${dynamicId}`
|
||||||
return axios.get(dynamicApi, {
|
return axios.get(dynamicApi, {
|
||||||
headers: {
|
headers: {
|
||||||
@ -125,4 +124,4 @@ function getDynamic(dynamicId) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export { downloadBFile, getDownloadUrl, mergeFileToMp4, getDynamic }
|
export { downloadBFile, getDownloadUrl, mergeFileToMp4, getDynamic }
|
||||||
|
@ -39,3 +39,5 @@ export const TEN_THOUSAND = 10000;
|
|||||||
export const CAT_LIMIT = 10;
|
export const CAT_LIMIT = 10;
|
||||||
|
|
||||||
export const XHS_CK = 'eGhzVHJhY2tlcklkPTczODhhYmY2LTI0MDgtNGU5YS04MTUyLTE0MGVhOGY1MTQ5ZjsgeGhzVHJhY2tlcklkLnNpZz1UcGUxTkNaX3B3UkFYdG01SVJmVEs0SWUxM0xBaGZuNmNZU2N4Vi1JYWxFOyBhMT0xODY2ZDkwMDM0NmI2NmppcjMzcGpxZ2MwM3JvcG1mczAydXMxdWNoeDEwMDAwMTM1MDUzOyB3ZWJJZD1mMTNkOGJkYjhiZGM3ZGE0MzY0NjA4NWJjYzQ1MDQ1YTsgZ2lkPXlZS0tmajg4SzA4MnlZS0tmajg4cUo3UzRLREtLVjNGcXFVVjd4Q0FrUzhxRk15OGxVNmlNeTg4OHlxMjgycThmMlk0UzAySjsgZ2lkLnNpZ249YlpzcFFzSUxEUmN5akZLQmN2L1FMWVhkU3lvPTsgd2ViX3Nlc3Npb249MDMwMDM3YTRjMDQyYjE1ZTVjMTg4OTUwOGIyNDRhZDExM2UwNTM7IHhoc1RyYWNrZXI9dXJsPW5vdGVEZXRhaWwmeGhzc2hhcmU9V2VpeGluU2Vzc2lvbjsgeGhzVHJhY2tlci5zaWc9YzdmcDVRclk2SGNvVERhUzluX2N3Z2RCRHh2MFZmWnpSU1NTcnlzbG5lQTsgZXh0cmFfZXhwX2lkcz1oNV8yMzAyMDExX29yaWdpbixoNV8xMjA4X2NsdCxoNV8xMTMwX2NsdCxpb3Nfd3hfbGF1bmNoX29wZW5fYXBwX2V4cCxoNV92aWRlb191aV9leHAzLHd4X2xhdW5jaF9vcGVuX2FwcF9kdXJhdGlvbl9vcmlnaW4scXVlc19jbHQyOyBleHRyYV9leHBfaWRzLnNpZz1DVUdrR3NYT3lBZmpVSXkyVGo3SjN4YmRNakFfSnpoR1JkYWd6cVlkbmJnOyB3ZWJCdWlsZD0xLjEuMjE7IHhzZWNhcHBpZD14aHMtcGMtd2ViOyB3ZWJzZWN0aWdhPTU5ZDNlZjFlNjBjNGFhMzdhN2RmM2MyMzQ2N2JkNDZkN2YxZGEwYjE5MThjZjMzNWVlN2YyZTllNTJhYzA0Y2Y7IHNlY19wb2lzb25faWQ9MTI0OTE1NWQtOWU5ZS00MzkyLTg2NTgtNTA1Yzc0YTUzMTM1'
|
export const XHS_CK = 'eGhzVHJhY2tlcklkPTczODhhYmY2LTI0MDgtNGU5YS04MTUyLTE0MGVhOGY1MTQ5ZjsgeGhzVHJhY2tlcklkLnNpZz1UcGUxTkNaX3B3UkFYdG01SVJmVEs0SWUxM0xBaGZuNmNZU2N4Vi1JYWxFOyBhMT0xODY2ZDkwMDM0NmI2NmppcjMzcGpxZ2MwM3JvcG1mczAydXMxdWNoeDEwMDAwMTM1MDUzOyB3ZWJJZD1mMTNkOGJkYjhiZGM3ZGE0MzY0NjA4NWJjYzQ1MDQ1YTsgZ2lkPXlZS0tmajg4SzA4MnlZS0tmajg4cUo3UzRLREtLVjNGcXFVVjd4Q0FrUzhxRk15OGxVNmlNeTg4OHlxMjgycThmMlk0UzAySjsgZ2lkLnNpZ249YlpzcFFzSUxEUmN5akZLQmN2L1FMWVhkU3lvPTsgd2ViX3Nlc3Npb249MDMwMDM3YTRjMDQyYjE1ZTVjMTg4OTUwOGIyNDRhZDExM2UwNTM7IHhoc1RyYWNrZXI9dXJsPW5vdGVEZXRhaWwmeGhzc2hhcmU9V2VpeGluU2Vzc2lvbjsgeGhzVHJhY2tlci5zaWc9YzdmcDVRclk2SGNvVERhUzluX2N3Z2RCRHh2MFZmWnpSU1NTcnlzbG5lQTsgZXh0cmFfZXhwX2lkcz1oNV8yMzAyMDExX29yaWdpbixoNV8xMjA4X2NsdCxoNV8xMTMwX2NsdCxpb3Nfd3hfbGF1bmNoX29wZW5fYXBwX2V4cCxoNV92aWRlb191aV9leHAzLHd4X2xhdW5jaF9vcGVuX2FwcF9kdXJhdGlvbl9vcmlnaW4scXVlc19jbHQyOyBleHRyYV9leHBfaWRzLnNpZz1DVUdrR3NYT3lBZmpVSXkyVGo3SjN4YmRNakFfSnpoR1JkYWd6cVlkbmJnOyB3ZWJCdWlsZD0xLjEuMjE7IHhzZWNhcHBpZD14aHMtcGMtd2ViOyB3ZWJzZWN0aWdhPTU5ZDNlZjFlNjBjNGFhMzdhN2RmM2MyMzQ2N2JkNDZkN2YxZGEwYjE5MThjZjMzNWVlN2YyZTllNTJhYzA0Y2Y7IHNlY19wb2lzb25faWQ9MTI0OTE1NWQtOWU5ZS00MzkyLTg2NTgtNTA1Yzc0YTUzMTM1'
|
||||||
|
|
||||||
|
export const BILI_DURATION = 400;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user