From 91d3fe7da09386209ec69c282c35918acd230bdf Mon Sep 17 00:00:00 2001 From: mtvpls Date: Tue, 14 Apr 2026 23:28:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8D=A2=E6=BA=90=E9=9B=86=E6=95=B0=E4=B8=8D?= =?UTF-8?q?=E4=B8=80=E8=87=B4=E6=97=B6=E6=B8=85=E7=A9=BA=E5=BC=B9=E5=B9=95?= =?UTF-8?q?=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/play/page.tsx | 12 +++++++++++ src/lib/danmaku/api.ts | 2 ++ src/lib/danmaku/cache.ts | 45 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/src/app/play/page.tsx b/src/app/play/page.tsx index f1bbbec..11b7327 100644 --- a/src/app/play/page.tsx +++ b/src/app/play/page.tsx @@ -9,6 +9,7 @@ import { Suspense, useEffect, useRef, useState } from 'react'; import { getAuthInfoFromBrowserCookie } from '@/lib/auth'; import { convertDanmakuFormat, + clearDanmakuCacheByTitle, getDanmakuById, getDanmakuFromCache, getEpisodes, @@ -4255,6 +4256,17 @@ function PlayPageClient() { // 尝试跳转到当前正在播放的集数 let targetIndex = currentEpisodeIndex; + // 如果新源的集数跟旧源的集数不一致,清除当前剧集的所有弹幕缓存 + const oldEpisodeCount = detail?.episodes?.length || 0; + const newEpisodeCount = newDetail.episodes?.length || 0; + if (oldEpisodeCount > 0 && newEpisodeCount > 0 && oldEpisodeCount !== newEpisodeCount) { + const titleForCache = detail?.title || videoTitle; + console.log(`换源集数不一致 (${oldEpisodeCount} -> ${newEpisodeCount}),清除弹幕缓存: ${titleForCache}`); + clearDanmakuCacheByTitle(titleForCache).catch((err) => { + console.error('清除弹幕缓存失败:', err); + }); + } + // 如果当前集数超出新源的范围,则跳转到第一集 if (!newDetail.episodes || targetIndex >= newDetail.episodes.length) { targetIndex = 0; diff --git a/src/lib/danmaku/api.ts b/src/lib/danmaku/api.ts index 78c1e64..1f59270 100644 --- a/src/lib/danmaku/api.ts +++ b/src/lib/danmaku/api.ts @@ -2,6 +2,7 @@ import { clearAllDanmakuCache, clearDanmakuCache, + clearDanmakuCacheByTitle, clearExpiredDanmakuCache, generateCacheKey, getDanmakuCacheStats, @@ -43,6 +44,7 @@ export function initDanmakuModule(): void { export { clearAllDanmakuCache, clearDanmakuCache, + clearDanmakuCacheByTitle, clearExpiredDanmakuCache, generateCacheKey, getDanmakuCacheStats, diff --git a/src/lib/danmaku/cache.ts b/src/lib/danmaku/cache.ts index 928ab51..b36c2b9 100644 --- a/src/lib/danmaku/cache.ts +++ b/src/lib/danmaku/cache.ts @@ -276,6 +276,51 @@ export async function clearDanmakuCache(title: string, episodeIndex: number): Pr } } +// 清除指定标题的所有弹幕缓存(所有集数) +export async function clearDanmakuCacheByTitle(title: string): Promise { + try { + const db = await openDB(); + const transaction = db.transaction([STORE_NAME], 'readwrite'); + const objectStore = transaction.objectStore(STORE_NAME); + + return new Promise((resolve, reject) => { + const request = objectStore.openCursor(); + let deletedCount = 0; + + request.onsuccess = (event) => { + const cursor = (event.target as IDBRequest).result; + + if (cursor) { + const data = cursor.value as DanmakuCacheData; + + if (data.title === title) { + cursor.delete(); + deletedCount++; + } + + cursor.continue(); + } else { + if (deletedCount > 0) { + console.log(`已清除标题"${title}"的 ${deletedCount} 个弹幕缓存`); + } + resolve(deletedCount); + } + }; + + request.onerror = () => { + reject(new Error('清除弹幕缓存失败')); + }; + + transaction.oncomplete = () => { + db.close(); + }; + }); + } catch (error) { + console.error('清除弹幕缓存失败:', error); + return 0; + } +} + // 清除所有过期缓存 export async function clearExpiredDanmakuCache(): Promise { try {