优化弹幕匹配逻辑
This commit is contained in:
@@ -41,6 +41,10 @@ import {
|
|||||||
saveDanmakuSourceIndex,
|
saveDanmakuSourceIndex,
|
||||||
getManualDanmakuSelection,
|
getManualDanmakuSelection,
|
||||||
saveManualDanmakuSelection,
|
saveManualDanmakuSelection,
|
||||||
|
saveDanmakuSearchKeyword,
|
||||||
|
getDanmakuSearchKeyword,
|
||||||
|
saveDanmakuAnimeId,
|
||||||
|
getDanmakuAnimeId,
|
||||||
} from '@/lib/danmaku/selection-memory';
|
} from '@/lib/danmaku/selection-memory';
|
||||||
import type { DanmakuAnime, DanmakuSelection, DanmakuSettings } from '@/lib/danmaku/types';
|
import type { DanmakuAnime, DanmakuSelection, DanmakuSettings } from '@/lib/danmaku/types';
|
||||||
import { SearchResult, DanmakuFilterConfig, EpisodeFilterConfig } from '@/lib/types';
|
import { SearchResult, DanmakuFilterConfig, EpisodeFilterConfig } from '@/lib/types';
|
||||||
@@ -662,12 +666,44 @@ function PlayPageClient() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行自动搜索弹幕
|
// 尝试使用保存的动漫ID自动匹配剧集
|
||||||
|
const savedAnimeId = getDanmakuAnimeId(title);
|
||||||
|
if (savedAnimeId) {
|
||||||
|
console.log(`[弹幕记忆] 尝试使用保存的动漫ID: ${savedAnimeId}`);
|
||||||
|
setDanmakuLoading(true);
|
||||||
|
try {
|
||||||
|
const episodesResult = await getEpisodes(savedAnimeId);
|
||||||
|
|
||||||
|
if (episodesResult.success && episodesResult.bangumi.episodes.length > 0) {
|
||||||
|
// 根据当前集数选择对应的弹幕
|
||||||
|
const videoEpTitle = detailRef.current?.episodes_titles?.[episodeIndex];
|
||||||
|
const episode = matchDanmakuEpisode(episodeIndex, episodesResult.bangumi.episodes, videoEpTitle);
|
||||||
|
|
||||||
|
if (episode) {
|
||||||
|
console.log(`[弹幕记忆] 使用保存的动漫ID匹配成功: ${episode.episodeTitle}`);
|
||||||
|
await loadDanmaku(episode.episodeId);
|
||||||
|
setDanmakuEpisodesList(episodesResult.bangumi.episodes);
|
||||||
|
return; // 匹配成功,直接返回
|
||||||
|
} else {
|
||||||
|
console.log('[弹幕记忆] 使用保存的动漫ID匹配失败,降级到关键词搜索');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[弹幕记忆] 使用保存的动漫ID失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行自动搜索弹幕(优先使用保存的关键词)
|
||||||
console.log(`[弹幕] 开始自动搜索`);
|
console.log(`[弹幕] 开始自动搜索`);
|
||||||
setDanmakuLoading(true);
|
setDanmakuLoading(true);
|
||||||
|
|
||||||
|
// 优先使用保存的搜索关键词,否则使用视频标题
|
||||||
|
const savedKeyword = getDanmakuSearchKeyword(title);
|
||||||
|
const searchKeyword = savedKeyword || title;
|
||||||
|
console.log(`[弹幕] 搜索关键词: ${searchKeyword}${savedKeyword ? ' (使用保存的关键词)' : ' (使用视频标题)'}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const searchResult = await searchAnime(title);
|
const searchResult = await searchAnime(searchKeyword);
|
||||||
|
|
||||||
if (searchResult.success && searchResult.animes.length > 0) {
|
if (searchResult.success && searchResult.animes.length > 0) {
|
||||||
// 应用智能过滤:优先匹配年份和标题
|
// 应用智能过滤:优先匹配年份和标题
|
||||||
@@ -727,7 +763,7 @@ function PlayPageClient() {
|
|||||||
// 没有记忆或记忆失效,让用户选择
|
// 没有记忆或记忆失效,让用户选择
|
||||||
console.log(`等待用户选择弹幕源`);
|
console.log(`等待用户选择弹幕源`);
|
||||||
setDanmakuMatches(filteredAnimes);
|
setDanmakuMatches(filteredAnimes);
|
||||||
setCurrentSearchKeyword(title);
|
setCurrentSearchKeyword(searchKeyword); // 保存当前搜索关键词
|
||||||
setShowDanmakuSourceSelector(true);
|
setShowDanmakuSourceSelector(true);
|
||||||
setDanmakuLoading(false);
|
setDanmakuLoading(false);
|
||||||
if (artPlayerRef.current) {
|
if (artPlayerRef.current) {
|
||||||
@@ -2998,6 +3034,15 @@ function PlayPageClient() {
|
|||||||
const episodeIndex = currentEpisodeIndexRef.current;
|
const episodeIndex = currentEpisodeIndexRef.current;
|
||||||
if (title && episodeIndex >= 0) {
|
if (title && episodeIndex >= 0) {
|
||||||
saveManualDanmakuSelection(title, episodeIndex, selection.episodeId);
|
saveManualDanmakuSelection(title, episodeIndex, selection.episodeId);
|
||||||
|
|
||||||
|
// 保存用户手动选择的动漫ID(用于换集时自动匹配)
|
||||||
|
saveDanmakuAnimeId(title, selection.animeId);
|
||||||
|
|
||||||
|
// 保存搜索关键词(如果有的话)
|
||||||
|
if (selection.searchKeyword) {
|
||||||
|
saveDanmakuSearchKeyword(title, selection.searchKeyword);
|
||||||
|
console.log(`[弹幕记忆] 保存手动搜索关键词: ${selection.searchKeyword}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取该动漫的所有剧集列表
|
// 获取该动漫的所有剧集列表
|
||||||
@@ -3211,9 +3256,10 @@ function PlayPageClient() {
|
|||||||
console.log('[弹幕] 缓存未命中,开始搜索');
|
console.log('[弹幕] 缓存未命中,开始搜索');
|
||||||
setDanmakuLoading(true);
|
setDanmakuLoading(true);
|
||||||
|
|
||||||
// 使用视频标题作为搜索关键词
|
// 优先使用保存的搜索关键词,否则使用视频标题
|
||||||
const searchKeyword = title;
|
const savedKeyword = getDanmakuSearchKeyword(title);
|
||||||
console.log('[弹幕] 搜索关键词:', searchKeyword, '(使用视频标题)');
|
const searchKeyword = savedKeyword || title;
|
||||||
|
console.log(`[弹幕] 搜索关键词: ${searchKeyword}${savedKeyword ? ' (使用保存的关键词)' : ' (使用视频标题)'}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const searchResult = await searchAnime(searchKeyword);
|
const searchResult = await searchAnime(searchKeyword);
|
||||||
|
|||||||
@@ -151,3 +151,86 @@ export function clearAllDanmakuSelectionMemory(): void {
|
|||||||
console.error('[弹幕记忆] 清除所有记忆失败:', error);
|
console.error('[弹幕记忆] 清除所有记忆失败:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存用户搜索的弹幕关键词
|
||||||
|
* @param title 视频标题
|
||||||
|
* @param keyword 搜索关键词
|
||||||
|
*/
|
||||||
|
export function saveDanmakuSearchKeyword(title: string, keyword: string): void {
|
||||||
|
if (typeof window === 'undefined') return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const key = `${STORAGE_KEY_PREFIX}keyword_${title}`;
|
||||||
|
sessionStorage.setItem(key, keyword);
|
||||||
|
console.log(`[弹幕记忆] 保存搜索关键词: ${title} -> ${keyword}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[弹幕记忆] 保存搜索关键词失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户搜索的弹幕关键词
|
||||||
|
* @param title 视频标题
|
||||||
|
* @returns 搜索关键词,如果没有记录则返回 null
|
||||||
|
*/
|
||||||
|
export function getDanmakuSearchKeyword(title: string): string | null {
|
||||||
|
if (typeof window === 'undefined') return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const key = `${STORAGE_KEY_PREFIX}keyword_${title}`;
|
||||||
|
const keyword = sessionStorage.getItem(key);
|
||||||
|
|
||||||
|
if (keyword) {
|
||||||
|
console.log(`[弹幕记忆] 读取搜索关键词: ${title} -> ${keyword}`);
|
||||||
|
return keyword;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[弹幕记忆] 读取搜索关键词失败:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存用户手动选择的弹幕动漫ID(用于换集时自动匹配)
|
||||||
|
* @param title 视频标题
|
||||||
|
* @param animeId 弹幕动漫ID
|
||||||
|
*/
|
||||||
|
export function saveDanmakuAnimeId(title: string, animeId: number): void {
|
||||||
|
if (typeof window === 'undefined') return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const key = `${STORAGE_KEY_PREFIX}anime_${title}`;
|
||||||
|
sessionStorage.setItem(key, animeId.toString());
|
||||||
|
console.log(`[弹幕记忆] 保存动漫ID: ${title} -> ${animeId}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[弹幕记忆] 保存动漫ID失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户手动选择的弹幕动漫ID
|
||||||
|
* @param title 视频标题
|
||||||
|
* @returns 弹幕动漫ID,如果没有记录则返回 null
|
||||||
|
*/
|
||||||
|
export function getDanmakuAnimeId(title: string): number | null {
|
||||||
|
if (typeof window === 'undefined') return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const key = `${STORAGE_KEY_PREFIX}anime_${title}`;
|
||||||
|
const value = sessionStorage.getItem(key);
|
||||||
|
|
||||||
|
if (value !== null) {
|
||||||
|
const animeId = parseInt(value, 10);
|
||||||
|
if (!isNaN(animeId)) {
|
||||||
|
console.log(`[弹幕记忆] 读取动漫ID: ${title} -> ${animeId}`);
|
||||||
|
return animeId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[弹幕记忆] 读取动漫ID失败:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user