🐞 fix: 修复哔哩哔哩总结不能总结一些没有弹幕视频的问题

This commit is contained in:
zhiyu1998 2023-03-24 10:03:12 +08:00
parent 28b106fa93
commit d8401b3a90
3 changed files with 39 additions and 36 deletions

View File

@ -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 } from "../utils/constant.js"; import { transMap, douyinTypeMap, XHS_CK, TEN_THOUSAND } 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,21 @@ 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 { title, combineContent, aid, cid } = await getVideoInfo(url); const videoInfo = await getVideoInfo(url);
const { title, desc, dynamic, stat, aid, cid } = videoInfo
// 视频信息
let { view, danmaku, reply, favorite, coin, share, like } = stat;
// 数据处理
const dataProcessing = data => {
return Number(data) >= TEN_THOUSAND ? (data / TEN_THOUSAND).toFixed(1) + "万" : data;
};
const combineContent = `总播放量:${dataProcessing(view)}, 弹幕数量:${dataProcessing(
danmaku,
)}, 回复量${dataProcessing(reply)}, 收藏数${dataProcessing(
favorite,
)}, 投币${dataProcessing(coin)}, 分享${dataProcessing(share)}, 点赞${dataProcessing(
like,
)}\n`;
e.reply([title, combineContent]); e.reply([title, combineContent]);
await getDownloadUrl(url) await getDownloadUrl(url)
@ -355,9 +369,9 @@ export class tools extends plugin {
if (this.biliSessData && this.openaiApiKey) { if (this.biliSessData && this.openaiApiKey) {
let prompt; let prompt;
try { try {
prompt = await getBiliGptInputText(title, aid, cid, this.biliSessData); prompt = await getBiliGptInputText({title, desc, dynamic, aid, cid}, this.biliSessData);
} catch (err) { } catch (err) {
logger.error("总结失败,可能是没有弹幕或者网络问题!"); logger.error("总结失败,可能是没有弹幕或者网络问题!\n", err);
return true; return true;
} }
const response = await this.chatGptClient.sendMessage(prompt); const response = await this.chatGptClient.sendMessage(prompt);

View File

@ -12,27 +12,11 @@ async function getVideoInfo(url) {
).then(async resp => { ).then(async resp => {
const respJson = await resp.json(); const respJson = await resp.json();
const respData = respJson.data; const respData = respJson.data;
// 视频标题
const title = "识别:哔哩哔哩," + respData.title + "\n";
// 视频图片(暂时不加入,影响性能)
// const videoCover = respData.pic;
// 视频信息
let { view, danmaku, reply, favorite, coin, share, like } = respData.stat;
// 数据处理
const dataProcessing = data => {
return Number(data) >= TEN_THOUSAND ? (data / TEN_THOUSAND).toFixed(1) + "万" : data;
};
// 组合内容
const combineContent = `总播放量:${dataProcessing(view)}, 弹幕数量:${dataProcessing(
danmaku,
)}, 回复量${dataProcessing(reply)}, 收藏数${dataProcessing(
favorite,
)}, 投币${dataProcessing(coin)}, 分享${dataProcessing(share)}, 点赞${dataProcessing(
like,
)}\n`;
return { return {
title, title: respData.title,
combineContent, desc: respData.desc,
dynamic: respJson.data.dynamic,
stat: respData.stat,
aid: respData.aid, aid: respData.aid,
cid: respData.pages?.[0].cid, cid: respData.pages?.[0].cid,
}; };

View File

@ -1,13 +1,12 @@
import _ from 'lodash'
/** /**
* 获取gpt提取视频信息的文字 * 获取gpt提取视频信息的文字
* @param title 视频标题 * @param videoInfo
* @param aid
* @param cid
* @param biliSessData * @param biliSessData
* @param shouldShowTimestamp 是否在每段字幕前面加入时间标识 * @param shouldShowTimestamp 是否在每段字幕前面加入时间标识
* @returns {Promise<string>} * @returns {Promise<string>}
*/ */
export async function getBiliGptInputText(title, aid, cid, biliSessData, shouldShowTimestamp = false) { export async function getBiliGptInputText(videoInfo, biliSessData, shouldShowTimestamp = false) {
const headers = { const headers = {
Accept: "application/json", Accept: "application/json",
"Content-Type": "application/json", "Content-Type": "application/json",
@ -22,26 +21,32 @@ export async function getBiliGptInputText(title, aid, cid, biliSessData, shouldS
headers, headers,
referrerPolicy: "no-referrer", referrerPolicy: "no-referrer",
}; };
const {title, desc, dynamic, aid, cid} = videoInfo
// https://api.bilibili.com/x/player/v2?aid=438937138&cid=1066979272 // https://api.bilibili.com/x/player/v2?aid=438937138&cid=1066979272
const resp = await fetch( const resp = await fetch(
`https://api.bilibili.com/x/player/v2?aid=${aid}&cid=${cid}`, `https://api.bilibili.com/x/player/v2?aid=${aid}&cid=${cid}`,
commonConfig, commonConfig,
); );
const subtitles = (await resp.json()).data.subtitle.subtitles; const subtitles = (await resp.json()).data.subtitle.subtitles;
const res = await fetch(`http:${subtitles[0]?.subtitle_url}`); const subtitlesUrl = subtitles?.subtitle_url?.startsWith('//')
if (_.isUndefined(res)) { ? `https:${subtitles?.subtitle_url}`
throw new Error(""); : subtitles?.subtitle_url
} let inputText = "";
logger.mark(subtitlesUrl);
if (subtitlesUrl !== undefined) {
const res = await fetch(subtitlesUrl);
const subtitlesData = (await res.json()).body; const subtitlesData = (await res.json()).body;
const subtitleTimestamp = reduceBilibiliSubtitleTimestamp(subtitlesData, shouldShowTimestamp); const subtitleTimestamp = reduceBilibiliSubtitleTimestamp(subtitlesData, shouldShowTimestamp);
const inputText = getSmallSizeTranscripts(subtitleTimestamp, subtitleTimestamp); inputText = getSmallSizeTranscripts(subtitleTimestamp, subtitleTimestamp);
} else {
inputText = `${desc} ${dynamic}`;
}
const videoConfig = { const videoConfig = {
showEmoji: false, showEmoji: false,
}; };
const userPrompt = shouldShowTimestamp return shouldShowTimestamp
? getUserSubtitleWithTimestampPrompt(title, inputText, videoConfig) ? getUserSubtitleWithTimestampPrompt(title, inputText, videoConfig)
: getUserSubtitlePrompt(title, inputText, videoConfig); : getUserSubtitlePrompt(title, inputText, videoConfig);
return userPrompt;
} }
// 以下拼接算法来自https://github.com/JimmyLv/BibiGPT // 以下拼接算法来自https://github.com/JimmyLv/BibiGPT