mirror of
https://github.com/Jerryplusy/rc-plugin.git
synced 2025-10-14 16:19:18 +00:00
🎈 pref: 优化 哔哩哔哩 专栏发送逻辑 && 优化直播切片
This commit is contained in:
parent
5782a3ad22
commit
e285ab042e
@ -8,6 +8,8 @@ import fs from "node:fs";
|
||||
import PQueue from 'p-queue';
|
||||
import path from "path";
|
||||
import querystring from "querystring";
|
||||
import { pipeline } from 'stream';
|
||||
import { promisify } from 'util';
|
||||
import {
|
||||
BILI_CDN_SELECT_LIST,
|
||||
BILI_DEFAULT_INTRO_LEN_LIMIT,
|
||||
@ -28,6 +30,7 @@ import {
|
||||
import {
|
||||
ANIME_SERIES_SEARCH_LINK,
|
||||
ANIME_SERIES_SEARCH_LINK2,
|
||||
BILI_ARTICLE_INFO,
|
||||
BILI_EP_INFO,
|
||||
BILI_ONLINE,
|
||||
BILI_SSID_INFO,
|
||||
@ -362,7 +365,6 @@ export class tools extends plugin {
|
||||
// 普通类型
|
||||
dyApi = DY_INFO.replace("{}", douId);
|
||||
}
|
||||
logger.info(dyApi);
|
||||
// a-bogus参数
|
||||
const abParam = aBogus.generate_a_bogus(
|
||||
new URLSearchParams(new URL(dyApi).search).toString(),
|
||||
@ -481,28 +483,27 @@ export class tools extends plugin {
|
||||
* @param second
|
||||
*/
|
||||
async sendStreamSegment(e, stream_url, second = this.streamDuration) {
|
||||
const pipelineAsync = promisify(pipeline);
|
||||
const outputFilePath = `${ this.getCurDownloadPath(e) }/stream_10s.flv`;
|
||||
await checkAndRemoveFile(outputFilePath);
|
||||
const file = fs.createWriteStream(outputFilePath);
|
||||
axios.get(stream_url, {
|
||||
responseType: 'stream'
|
||||
}).then(response => {
|
||||
logger.info("[R插件][发送直播流] 正在下载直播流...");
|
||||
// 将流数据写入文件
|
||||
response.data.pipe(file);
|
||||
|
||||
// 设置 10 秒后停止下载
|
||||
try {
|
||||
const response = await axios.get(stream_url, { responseType: 'stream' });
|
||||
logger.info("[R插件][发送直播流] 正在下载直播流...");
|
||||
|
||||
const file = fs.createWriteStream(outputFilePath);
|
||||
await pipelineAsync(response.data, file);
|
||||
|
||||
// 设置 streamDuration 秒后停止下载
|
||||
setTimeout(async () => {
|
||||
logger.info(`[R插件][发送直播流] 直播下载 ${ this.streamDuration } 秒钟到,停止下载!`);
|
||||
response.data.destroy(); // 销毁流
|
||||
await this.sendVideoToUpload(e, outputFilePath);
|
||||
file.close(); // 关闭文件流
|
||||
}, second * 1000); // 10秒 = 10000毫秒
|
||||
}).catch(error => {
|
||||
logger.error(`下载失败:${ error.message }`);
|
||||
fs.unlink(outputFilePath, () => {
|
||||
}); // 下载失败时删除文件
|
||||
});
|
||||
}, second * 1000);
|
||||
} catch (error) {
|
||||
logger.error(`下载失败: ${ error.message }`);
|
||||
await fs.promises.unlink(outputFilePath); // 下载失败时删除文件
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -648,6 +649,7 @@ export class tools extends plugin {
|
||||
}
|
||||
// 处理专栏
|
||||
if (e.msg !== undefined && e.msg.includes("read\/cv")) {
|
||||
await this.biliArticle(e);
|
||||
this.linkShareSummary(e);
|
||||
return true;
|
||||
}
|
||||
@ -708,6 +710,31 @@ export class tools extends plugin {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取哔哩哔哩专栏
|
||||
* @param e
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async biliArticle(e) {
|
||||
const cvid = e.msg.match(/read\/cv(\d+)/)?.[1];
|
||||
logger.info(BILI_ARTICLE_INFO.replace("{}", cvid));
|
||||
const articleResp = await fetch(BILI_ARTICLE_INFO.replace("{}", cvid), {
|
||||
headers: BILI_HEADER
|
||||
});
|
||||
const articleData = (await articleResp.json()).data;
|
||||
const { title, author_name, origin_image_urls } = articleData;
|
||||
e.reply(`${ this.identifyPrefix }识别:哔哩哔哩专栏,${ title }-${ author_name }\n`);
|
||||
if (origin_image_urls) {
|
||||
await e.reply(Bot.makeForwardMsg(origin_image_urls.map(item => {
|
||||
return {
|
||||
message: segment.image(item),
|
||||
nickname: e.sender.card || e.user_id,
|
||||
user_id: e.user_id,
|
||||
}
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造哔哩哔哩信息
|
||||
* @param videoInfo
|
||||
|
@ -89,6 +89,13 @@ export const BILI_EP_INFO = "https://api.bilibili.com/pgc/view/web/season?ep_id=
|
||||
*/
|
||||
export const BILI_SSID_INFO = "https://api.bilibili.com/pgc/web/season/section?season_id={}"
|
||||
|
||||
/**
|
||||
* 专栏信息
|
||||
* https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/article/info.md
|
||||
* @type {string}
|
||||
*/
|
||||
export const BILI_ARTICLE_INFO = "https://api.bilibili.com/x/article/viewinfo?id={}"
|
||||
|
||||
/**
|
||||
* 米游社网页端获取文章
|
||||
* https://github.com/UIGF-org/mihoyo-api-collect/blob/main/hoyolab/article/article.md#%E8%8E%B7%E5%8F%96%E5%AE%8C%E6%95%B4%E6%96%87%E7%AB%A0%E4%BF%A1%E6%81%AF
|
||||
|
@ -1,7 +1,13 @@
|
||||
import path from 'path';
|
||||
import { exec } from 'child_process';
|
||||
|
||||
// 写一个执行ffmpeg提取视频关键帧的函数,例如:ffmpeg -i input.mp4 -vf "select=eq(pict_type\,I)" -vsync drop -vframes 5 -qscale:v 2 keyframes\keyframe_%03d.jpg
|
||||
/**
|
||||
* 提取关键帧
|
||||
* @param inputFilePath
|
||||
* @param outputFolderPath
|
||||
* @param frameCount
|
||||
* @returns {Promise<unknown>}
|
||||
*/
|
||||
export async function extractKeyframes(inputFilePath, outputFolderPath, frameCount = 20) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 创建输出文件夹路径
|
||||
@ -21,3 +27,29 @@ export async function extractKeyframes(inputFilePath, outputFolderPath, frameCou
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用 ffmpeg 将 FLV 文件转换为 MP4 文件
|
||||
* @param {string} inputFilePath - 输入的 FLV 文件路径
|
||||
* @param {string} outputFilePath - 输出的 MP4 文件路径
|
||||
* @returns {Promise<string>} - 返回一个 Promise,成功时返回输出文件路径,失败时返回错误信息
|
||||
*/
|
||||
function convertFlvToMp4(inputFilePath, outputFilePath) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const command = `ffmpeg -i ${inputFilePath} ${outputFilePath}`;
|
||||
|
||||
logger.info(`[R插件][ffmpeg工具]执行命令:${command}`);
|
||||
|
||||
exec(command, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
reject(`执行 ffmpeg 命令时出错: ${error.message}`);
|
||||
return;
|
||||
}
|
||||
if (stderr) {
|
||||
reject(`ffmpeg 标准错误输出: ${stderr}`);
|
||||
return;
|
||||
}
|
||||
resolve(outputFilePath);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user