增加play页背景图渲染

This commit is contained in:
mtvpls
2025-12-28 00:51:02 +08:00
parent cc6d1e95f3
commit 0cf4db35f9
4 changed files with 443 additions and 0 deletions
+128
View File
@@ -95,6 +95,9 @@ function PlayPageClient() {
const [error, setError] = useState<string | null>(null);
const [detail, setDetail] = useState<SearchResult | null>(null);
// TMDB背景图
const [tmdbBackdrop, setTmdbBackdrop] = useState<string | null>(null);
// 收藏状态
const [favorited, setFavorited] = useState(false);
@@ -562,6 +565,118 @@ function PlayPageClient() {
fetchDoubanRating();
}, [videoDoubanId]);
// 获取TMDB背景图
useEffect(() => {
const fetchTMDBBackdrop = async () => {
// 检查是否禁用背景图
if (typeof window !== 'undefined') {
const disabled = localStorage.getItem('tmdb_backdrop_disabled');
if (disabled === 'true') {
setTmdbBackdrop(null);
return;
}
}
if (!videoTitle) {
setTmdbBackdrop(null);
return;
}
try {
// 检查title到tmdbId的映射缓存(1个月)
const mappingCacheKey = `tmdb_title_mapping_${videoTitle}`;
const mappingCache = localStorage.getItem(mappingCacheKey);
let cachedId: string | null = null;
if (mappingCache) {
try {
const { tmdbId, timestamp } = JSON.parse(mappingCache);
const cacheAge = Date.now() - timestamp;
const cacheMaxAge = 30 * 24 * 60 * 60 * 1000; // 1个月
if (cacheAge < cacheMaxAge && tmdbId) {
console.log('使用缓存的TMDB ID映射');
cachedId = tmdbId;
// 检查TMDB详情缓存(1天)
const detailsCacheKey = `tmdb_details_${tmdbId}`;
const detailsCache = localStorage.getItem(detailsCacheKey);
if (detailsCache) {
try {
const { data, timestamp: detTimestamp } = JSON.parse(detailsCache);
const detCacheAge = Date.now() - detTimestamp;
const detCacheMaxAge = 24 * 60 * 60 * 1000; // 1天
if (detCacheAge < detCacheMaxAge && data && data.backdrop) {
console.log('使用缓存的TMDB详情数据');
setTmdbBackdrop(data.backdrop);
return;
}
} catch (e) {
console.error('解析详情缓存失败:', e);
}
}
}
} catch (e) {
console.error('解析映射缓存失败:', e);
}
}
// 构建请求URL
const url = cachedId
? `/api/tmdb-details?cachedId=${encodeURIComponent(cachedId)}`
: `/api/tmdb-details?title=${encodeURIComponent(videoTitle)}`;
const response = await fetch(url);
if (!response.ok) {
console.log('获取TMDB详情失败');
setTmdbBackdrop(null);
return;
}
const result = await response.json();
if (result.backdrop) {
setTmdbBackdrop(result.backdrop);
// 保存title到tmdbId的映射到localStorage1个月)
if (result.tmdbId) {
try {
localStorage.setItem(
mappingCacheKey,
JSON.stringify({
tmdbId: result.tmdbId,
timestamp: Date.now(),
})
);
// 保存TMDB详情数据到localStorage1天)
const detailsCacheKey = `tmdb_details_${result.tmdbId}`;
localStorage.setItem(
detailsCacheKey,
JSON.stringify({
data: result,
timestamp: Date.now(),
})
);
} catch (e) {
console.error('保存缓存失败:', e);
}
}
} else {
setTmdbBackdrop(null);
}
} catch (error) {
console.error('获取TMDB背景图失败:', error);
setTmdbBackdrop(null);
}
};
fetchTMDBBackdrop();
}, [videoTitle]);
// 视频播放地址
const [videoUrl, setVideoUrl] = useState('');
@@ -4405,6 +4520,19 @@ function PlayPageClient() {
return (
<PageLayout activePath='/play'>
{/* TMDB背景图 */}
{tmdbBackdrop && (
<div
className='fixed inset-0 z-0'
style={{
backgroundImage: `url(${tmdbBackdrop})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
backgroundRepeat: 'no-repeat',
filter: 'blur(5px) brightness(0.7)',
}}
/>
)}
{/* 弹幕源选择对话框 */}
{showDanmakuSourceSelector && danmakuMatches.length > 0 && (
<div className='fixed inset-0 z-[1000] flex items-center justify-center bg-black/60 backdrop-blur-sm'>