新增腾讯源/爱奇艺源/优酷源/芒果源/b站源/咪咕源/搜狐源弹幕点赞数显示 (#204)

* 修改搜索接口的titleMatches里的相似度阈值从原先>=80%改为>80%

* 打印hanjutv搜索结果

* 增加 s5 解密后 打印

* 删除hanjutv打印

* 搜狐源增加弹幕点赞数显示

* 芒果源增加弹幕点赞数显示

* 腾讯源/爱奇艺源/优酷源/芒果源/b站源/咪咕源/搜狐源增加弹幕点赞数显示

* 恢复多余的修改
This commit is contained in:
huangxd- authored and GitHub committed 2026-02-27 22:53:05 +08:00
1 parent aac6e6d8bc
commit e402f1f77c
14 files changed
+37 -21

No files matched your search

+3 -1
View File
@@ -18,7 +18,7 @@ LogVar 弹幕 API 服务器
---
一个人人都能部署的基于 js 的弹幕 API 服务器,支持爱优腾芒哔咪人韩巴狐乐西弹幕直接获取,兼容弹弹play的搜索、详情查询和弹幕获取接口规范,并提供日志记录,支持vercel/netlify/edgeone/cloudflare/docker/claw等部署方式,不用提前下载弹幕,没有nas或小鸡也能一键部署。
一个人人都能部署的基于 js 的弹幕 API 服务器,支持爱优腾芒哔咪人韩巴狐乐西埋弹幕直接获取,兼容弹弹play的搜索、详情查询和弹幕获取接口规范,并提供日志记录,支持vercel/netlify/edgeone/cloudflare/docker/claw等部署方式,不用提前下载弹幕,没有nas或小鸡也能一键部署。
本项目仅为个人爱好开发,代码开源。如有任何侵权行为,请联系本人删除。
@@ -76,6 +76,7 @@ LogVar 弹幕 API 服务器
- 将顶部和底部弹幕转换为浮动弹幕(`CONVERT_TOP_BOTTOM_TO_SCROLL`)
- 转换弹幕颜色为白色或彩色(`CONVERT_COLOR`)
- 解决部分播放器不支持顶部/底部弹幕和彩色弹幕的问题
- 增加点赞数显示,先去重再拼接点赞标记,点赞数缩写显示,≥5 才显示,避免低赞干扰
- **弹幕限制数量**:支持通过环境变量配置等间隔采样弹幕数量。
- **弹幕分片请求**:
- `/api/v2/comment` 请求时支持定义 `segmentflag=true` 参数,用于请求弹幕分片列表
@@ -587,6 +588,7 @@ API 支持返回 Bilibili 标准 XML 格式的弹幕数据,通过查询参数
│ ├── cookie-util.js # b站 cookie获取工具
│ ├── danmu-util.js # 弹幕处理工具
│ ├── douban-util.js # 豆瓣API请求工具
│ ├── hanjutv-util.js # 韩剧tv加解密工具
│ ├── http-util.js # 请求工具
│ ├── imdb-util.js # IMDB API请求工具
│ ├── log-util.js # 日志工具
+1 -1
View File
@@ -75,7 +75,7 @@ export function handleConfig(hasPermission = false) {
originalEnvVars: originalEnvVars, // 系统设置使用原始环境变量(已脱敏)
hasAdminToken: hasAdminToken, // 添加admin token配置状态
repository: "https://github.com/huangxd-/danmu_api.git",
description: "一个人人都能部署的基于 js 的弹幕 API 服务器,支持爱优腾芒哔咪人韩巴狐乐西弹幕直接获取,兼容弹弹play的搜索、详情查询和弹幕获取接口规范,并提供日志记录,支持vercel/netlify/edgeone/cloudflare/docker/claw等部署方式,不用提前下载弹幕,没有nas或小鸡也能一键部署。",
description: "一个人人都能部署的基于 js 的弹幕 API 服务器,支持爱优腾芒哔咪人韩巴狐乐西埋弹幕直接获取,兼容弹弹play的搜索、详情查询和弹幕获取接口规范,并提供日志记录,支持vercel/netlify/edgeone/cloudflare/docker/claw等部署方式,不用提前下载弹幕,没有nas或小鸡也能一键部署。",
notice: "本项目仅为个人爱好开发,代码开源。如有任何侵权行为,请联系本人删除。有问题提issue或私信机器人都ok,TG MSG ROBOT: [https://t.me/ddjdd_bot]; 推荐加互助群咨询,TG GROUP: [https://t.me/logvar_danmu_group]; 关注频道获取最新更新内容,TG CHANNEL: [https://t.me/logvar_danmu_channel]。"
});
}
+1 -1
View File
@@ -13,7 +13,7 @@ export const Globals = {
accessedEnvVars: {},
// 静态常量
VERSION: '1.15.1',
VERSION: '1.15.2',
MAX_LOGS: 1000, // 日志存储,最多保存 1000 行
MAX_ANIMES: 100,
MAX_RECORDS: 100, // 请求记录最大数量
+7 -8
View File
@@ -839,14 +839,13 @@ export default class BilibiliSource extends BaseSource {
}
formatComments(comments) {
// 弹幕繁体转简体
if (globals.danmuSimplifiedTraditional === 'simplified') {
return comments.map(c => {
if (c.m) c.m = simplized(c.m);
return c;
});
}
return comments;
return comments.map(c => {
if (globals.danmuSimplifiedTraditional === 'simplified') {
if (c.m) c.m = simplized(c.m);
}
c.like = c.like_num;
return c;
});
}
// 构建代理URL
+3
View File
@@ -870,11 +870,13 @@ export default class IqiyiSource extends BaseSource {
const danmaku = extract(xml, "content");
const showTime = extract(xml, "showTime");
const color = extract(xml, "color");
const like = extract(xml, "likeCount");
contents.push(...danmaku.map((content, i) => ({
content,
showTime: showTime[i],
color: color[i],
like: parseInt(like[i]) || 0,
})));
}
@@ -900,6 +902,7 @@ export default class IqiyiSource extends BaseSource {
content.color = parseInt(item["color"], 16);
content.content = decodeHtmlEntities(item["content"]);
content.size = 25;
content.like = item["like"];
return content;
});
}
+1
View File
@@ -725,6 +725,7 @@ export default class MangoSource extends BaseSource {
content.timepoint = item.time / 1000;
content.content = item.content;
content.uid = item.uid;
content.like = item.v2_up_count;
return content;
});
}
+2 -1
View File
@@ -359,7 +359,8 @@ class MiguSource extends BaseSource {
cid: Number(c.cid),
p: `${c.playtime},1,${hexToInt(c.textcolor)},[migu]`,
m: c.msg,
t: c.playtime
t: c.playtime,
like: c.praiseCount
}));
}
+2 -1
View File
@@ -512,7 +512,8 @@ export default class SohuSource extends BaseSource {
cid: String(danmuId),
p: pString,
m: comment.c || '',
t: parseFloat(vtime)
t: parseFloat(vtime),
like: comment.fcount
};
} catch (error) {
log("error", `格式化弹幕失败: ${error.message}, 弹幕数据:`, comment);
+2
View File
@@ -616,6 +616,8 @@ export default class TencentSource extends BaseSource {
}
}
content.like = parseInt(item.up_count) || 0;
return content;
});
}
+1
View File
@@ -682,6 +682,7 @@ export default class YoukuSource extends BaseSource {
else if (pos === 2) content.ct = 4;
}
content.content = item.content;
content.like = item.extFields.voteUp;
return content;
});
}
+1 -1
View File
@@ -303,7 +303,7 @@ export const HTML_TEMPLATE = /* html */ `
<!-- 项目声明 -->
<footer class="footer">
<p class="footer-text">
一个人人都能部署的基于 js 的弹幕 API 服务器,支持爱优腾芒哔咪人韩巴狐乐西弹幕直接获取,兼容弹弹play的搜索、详情查询和弹幕获取接口规范,并提供日志记录,支持vercel/netlify/edgeone/cloudflare/docker/claw等部署方式,不用提前下载弹幕,没有nas或小鸡也能一键部署。
一个人人都能部署的基于 js 的弹幕 API 服务器,支持爱优腾芒哔咪人韩巴狐乐西埋弹幕直接获取,兼容弹弹play的搜索、详情查询和弹幕获取接口规范,并提供日志记录,支持vercel/netlify/edgeone/cloudflare/docker/claw等部署方式,不用提前下载弹幕,没有nas或小鸡也能一键部署。
</p>
<p class="footer-text">本项目仅为个人爱好开发,代码开源。如有任何侵权行为,请联系本人删除。</p>
<p class="footer-links">
+6 -1
View File
@@ -189,7 +189,12 @@ export function addAnime(anime) {
}
log("info", `animes: ${JSON.stringify(
globals.animes,
globals.animes.map(anime => ({
links: anime.links,
animeId: anime.animeId,
bangumiId: anime.bangumiId,
animeTitle: anime.animeTitle
})),
(key, value) => key === 'links' ? value.length : value
)}`);
+2 -2
View File
@@ -244,12 +244,12 @@ export function titleMatches(title, query) {
if (t.includes(q)) return true;
// 策略3:相似度匹配 (阈值0.8)
// 解决"和/与"等翻译差异,只要搜索词中 80% 的字符出现在标题里,即视为匹配
// 解决"和/与"等翻译差异,只要搜索词中 大于 80% 的字符出现在标题里,即视为匹配
const qSet = new Set(q);
const tSet = new Set(t);
const matchCount = [...qSet].reduce((acc, char) => acc + (tSet.has(char) ? 1 : 0), 0);
return (matchCount / qSet.size) >= 0.8;
return (matchCount / qSet.size) > 0.8;
}
/**
+5 -4
View File
@@ -118,11 +118,12 @@ export function handleDanmusLike(groupedDanmus) {
return item;
}
// 获取弹幕来源信息,判断是否为hanjutv
const isHanjutv = item.p.includes('[hanjutv]');
// 获取弹幕来源信息,判断是否为需要特殊处理的源(低阈值)
const lowThresholdSources = ['[hanjutv]', '[sohu]', '[bilibili1]', '[migu]'];
const isLowThresholdSource = lowThresholdSources.some(source => item.p.includes(source));
// 确定阈值:hanjutv中>=100用🔥,其他>=1000用🔥
const threshold = isHanjutv ? 100 : 1000;
// 确定阈值:特定源中>=100用🔥,其他>=1000用🔥
const threshold = isLowThresholdSource ? 100 : 1000;
const icon = item.like >= threshold ? '🔥' : '❤️';
// 格式化点赞数,缩写显示