feat: 完善视频源类型识别逻辑,修复动漫误判为电视剧的问题 (#77)
This commit is contained in:
1 parent
90de8a29c5
commit
b794f02733
4 files changed
+137
-17
No files matched your search
@@ -169,7 +169,8 @@ export default class BilibiliSource extends BaseSource {
|
||||
const mediaId = item.season_id ? `ss${item.season_id}` : item.bvid ? `bv${item.bvid}` : "";
|
||||
if (!mediaId) continue;
|
||||
|
||||
const mediaType = item.season_type_name === "电影" ? "电影" : "电视剧";
|
||||
// 提取媒体类型(参考 bilibili.py 和优化后的 youku.js)
|
||||
const mediaType = this._extractMediaType(item.season_type_name);
|
||||
const episodeCount = mediaType === "电影" ? 1 : (item.ep_size || 0);
|
||||
|
||||
// 提取年份
|
||||
@@ -217,6 +218,46 @@ export default class BilibiliSource extends BaseSource {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 season_type_name 提取媒体类型
|
||||
* B站 API 返回的类型包括:电影、番剧、国创、纪录片、综艺、电视剧等
|
||||
* @param {string} seasonTypeName - API 返回的 season_type_name
|
||||
* @returns {string} 标准化的媒体类型
|
||||
*/
|
||||
_extractMediaType(seasonTypeName) {
|
||||
const typeName = (seasonTypeName || "").toLowerCase();
|
||||
|
||||
// 电影类型
|
||||
if (typeName.includes("电影") || typeName.includes("movie")) {
|
||||
return "电影";
|
||||
}
|
||||
|
||||
// 动漫类型(包括番剧和国创)
|
||||
if (typeName.includes("番剧") || typeName.includes("国创") ||
|
||||
typeName.includes("动漫") || typeName.includes("anime")) {
|
||||
return "动漫";
|
||||
}
|
||||
|
||||
// 纪录片类型
|
||||
if (typeName.includes("纪录片") || typeName.includes("documentary")) {
|
||||
return "纪录片";
|
||||
}
|
||||
|
||||
// 综艺类型
|
||||
if (typeName.includes("综艺") || typeName.includes("variety")) {
|
||||
return "综艺";
|
||||
}
|
||||
|
||||
// 电视剧类型
|
||||
if (typeName.includes("电视剧") || typeName.includes("剧集") ||
|
||||
typeName.includes("drama") || typeName.includes("tv")) {
|
||||
return "电视剧";
|
||||
}
|
||||
|
||||
// 默认返回电视剧(最常见的类型)
|
||||
return "电视剧";
|
||||
}
|
||||
|
||||
async search(keyword) {
|
||||
try {
|
||||
log("info", `[Bilibili] 开始搜索: ${keyword}`);
|
||||
|
||||
@@ -140,15 +140,22 @@ export default class IqiyiSource extends BaseSource {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 过滤不相关频道
|
||||
// 提取媒体类型(参考优化后的 youku.js 和 bilibili.js)
|
||||
const channel = album.channel || "";
|
||||
let mediaType = "电视剧";
|
||||
let mediaType = "电视剧"; // 默认类型
|
||||
|
||||
if (channel.includes("电影")) {
|
||||
mediaType = "电影";
|
||||
} else if (channel.includes("电视剧") || channel.includes("动漫")) {
|
||||
} else if (channel.includes("动漫")) {
|
||||
mediaType = "动漫";
|
||||
} else if (channel.includes("综艺")) {
|
||||
mediaType = "综艺";
|
||||
} else if (channel.includes("纪录片")) {
|
||||
mediaType = "纪录片";
|
||||
} else if (channel.includes("电视剧")) {
|
||||
mediaType = "电视剧";
|
||||
} else {
|
||||
// 只保留电影、电视剧、动漫
|
||||
// 只保留支持的类型:电影、电视剧、动漫、综艺、纪录片
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,43 @@ export default class MangoSource extends BaseSource {
|
||||
return Math.floor((leftColor + rightColor) / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从类型字符串中提取标准化的媒体类型
|
||||
* @param {string} typeStr - API 返回的类型字符串
|
||||
* @returns {string} 标准化的媒体类型
|
||||
*/
|
||||
_extractMediaType(typeStr) {
|
||||
const type = (typeStr || "").toLowerCase();
|
||||
|
||||
// 电影类型
|
||||
if (type.includes("电影") || type.includes("movie")) {
|
||||
return "电影";
|
||||
}
|
||||
|
||||
// 动漫类型
|
||||
if (type.includes("动漫") || type.includes("动画") || type.includes("anime")) {
|
||||
return "动漫";
|
||||
}
|
||||
|
||||
// 综艺类型
|
||||
if (type.includes("综艺") || type.includes("真人秀") || type.includes("variety")) {
|
||||
return "综艺";
|
||||
}
|
||||
|
||||
// 纪录片类型
|
||||
if (type.includes("纪录片") || type.includes("documentary")) {
|
||||
return "纪录片";
|
||||
}
|
||||
|
||||
// 电视剧类型
|
||||
if (type.includes("电视剧") || type.includes("剧集") || type.includes("drama") || type.includes("tv")) {
|
||||
return "电视剧";
|
||||
}
|
||||
|
||||
// 默认返回电视剧(最常见的类型)
|
||||
return "电视剧";
|
||||
}
|
||||
|
||||
async search(keyword) {
|
||||
try {
|
||||
log("info", `[Mango] 开始搜索: ${keyword}`);
|
||||
@@ -95,9 +132,9 @@ export default class MangoSource extends BaseSource {
|
||||
const yearMatch = item.desc && item.desc[0] ? item.desc[0].match(/[12][890][0-9][0-9]/) : null;
|
||||
const year = yearMatch ? parseInt(yearMatch[0]) : null;
|
||||
|
||||
// 提取类型
|
||||
// 提取媒体类型(参考优化后的 youku.js 和 bilibili.js)
|
||||
const typeMatch = item.desc && item.desc[0] ? item.desc[0].split('/')[0].replace("类型:", "").trim() : '';
|
||||
const mediaType = typeMatch === "电影" ? "电影" : "电视剧";
|
||||
const mediaType = this._extractMediaType(typeMatch);
|
||||
|
||||
results.push({
|
||||
provider: "imgo",
|
||||
|
||||
+45
-10
@@ -55,8 +55,31 @@ export default class YoukuSource extends BaseSource {
|
||||
// 清理标题 (移除HTML标签和特殊符号)
|
||||
let cleanedTitle = title.replace(/<[^>]+>/g, '').replace(/【.+?】/g, '').trim().replace(/:/g, ':');
|
||||
|
||||
// 提取媒体类型
|
||||
const mediaType = commonData.feature.includes("电影") ? "电影" : "电视剧";
|
||||
// 提取媒体类型(参考 Python 版本的 _extract_media_type_from_response)
|
||||
let mediaType = "电视剧"; // 默认类型
|
||||
const cats = (commonData.cats || "").toLowerCase();
|
||||
const feature = (commonData.feature || "").toLowerCase();
|
||||
|
||||
// 优先使用 cats 字段
|
||||
if (cats.includes("动漫") || cats.includes("anime")) {
|
||||
mediaType = "动漫";
|
||||
} else if (cats.includes("电影") || cats.includes("movie")) {
|
||||
mediaType = "电影";
|
||||
} else if (cats.includes("电视剧") || cats.includes("drama")) {
|
||||
mediaType = "电视剧";
|
||||
} else if (cats.includes("综艺") || cats.includes("variety")) {
|
||||
mediaType = "综艺";
|
||||
}
|
||||
// 备用:从 feature 字段提取
|
||||
else if (feature.includes("动漫")) {
|
||||
mediaType = "动漫";
|
||||
} else if (feature.includes("电影")) {
|
||||
mediaType = "电影";
|
||||
} else if (feature.includes("电视剧")) {
|
||||
mediaType = "电视剧";
|
||||
} else if (feature.includes("综艺")) {
|
||||
mediaType = "综艺";
|
||||
}
|
||||
|
||||
return {
|
||||
provider: "youku",
|
||||
@@ -323,27 +346,39 @@ export default class YoukuSource extends BaseSource {
|
||||
}
|
||||
|
||||
/**
|
||||
* 从分类信息中提取媒体类型
|
||||
* 从分类信息中提取媒体类型(参考 Python 版本的 _extract_media_type_from_response)
|
||||
* @param {string} cats - 分类字符串
|
||||
* @param {string} feature - 特征字符串
|
||||
* @returns {string} 媒体类型
|
||||
* @returns {string} 媒体类型 (variety/movie/anime/drama)
|
||||
*/
|
||||
_extractMediaType(cats, feature) {
|
||||
const catsLower = (cats || '').toLowerCase();
|
||||
const featureLower = (feature || '').toLowerCase();
|
||||
|
||||
if (catsLower.includes('综艺') || catsLower.includes('variety') || featureLower.includes('综艺')) {
|
||||
// 优先使用 cats 字段
|
||||
if (catsLower.includes('综艺') || catsLower.includes('variety')) {
|
||||
return 'variety';
|
||||
} else if (catsLower.includes('电影') || catsLower.includes('movie') || featureLower.includes('电影')) {
|
||||
} else if (catsLower.includes('电影') || catsLower.includes('movie')) {
|
||||
return 'movie';
|
||||
} else if (catsLower.includes('动漫') || catsLower.includes('anime') || featureLower.includes('动漫')) {
|
||||
} else if (catsLower.includes('动漫') || catsLower.includes('anime')) {
|
||||
return 'anime';
|
||||
} else if (catsLower.includes('电视剧') || catsLower.includes('drama') || featureLower.includes('电视剧')) {
|
||||
} else if (catsLower.includes('电视剧') || catsLower.includes('drama')) {
|
||||
return 'drama';
|
||||
}
|
||||
|
||||
// 备用:从 feature 字段提取
|
||||
if (featureLower.includes('综艺')) {
|
||||
return 'variety';
|
||||
} else if (featureLower.includes('电影')) {
|
||||
return 'movie';
|
||||
} else if (featureLower.includes('动漫')) {
|
||||
return 'anime';
|
||||
} else if (featureLower.includes('电视剧')) {
|
||||
return 'drama';
|
||||
}
|
||||
|
||||
// 默认返回综艺
|
||||
return 'variety';
|
||||
// 默认返回电视剧类型
|
||||
return 'drama';
|
||||
}
|
||||
|
||||
async getEpisodeDanmu(id) {
|
||||
|
||||
Reference in new issue
Block a user