From 1c2b1b3c4a58a3b4e1cf4261249911b6394d7095 Mon Sep 17 00:00:00 2001 From: mtvpls Date: Fri, 2 Jan 2026 01:50:16 +0800 Subject: [PATCH] =?UTF-8?q?tmdb=E8=BD=AE=E6=92=AD=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E9=A2=84=E5=91=8A=E7=89=87=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/tmdb/trending/route.ts | 14 +++++- src/components/BannerCarousel.tsx | 73 ++++++++++++++++++++++++++---- src/components/UserMenu.tsx | 41 +++++++++++++++++ src/lib/tmdb.client.ts | 55 ++++++++++++++++++++++ 4 files changed, 173 insertions(+), 10 deletions(-) diff --git a/src/app/api/tmdb/trending/route.ts b/src/app/api/tmdb/trending/route.ts index a9ec969..997a635 100644 --- a/src/app/api/tmdb/trending/route.ts +++ b/src/app/api/tmdb/trending/route.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { NextResponse } from 'next/server'; -import { getTMDBTrendingContent } from '@/lib/tmdb.client'; +import { getTMDBTrendingContent, getTMDBVideos } from '@/lib/tmdb.client'; import { getConfig } from '@/lib/config'; // 缓存配置 - 服务器内存缓存3小时 @@ -54,6 +54,18 @@ export async function GET() { // 获取热门内容 result = await getTMDBTrendingContent(apiKey, proxy); + + // 为每个项目获取视频数据 + if (result.code === 200 && result.list) { + const itemsWithVideos = await Promise.all( + result.list.map(async (item: any) => { + const videoKey = await getTMDBVideos(apiKey, item.media_type, item.id, proxy); + return { ...item, video_key: videoKey }; + }) + ); + result.list = itemsWithVideos; + } + // 添加数据源标识 result.source = 'TMDB'; // 更新TMDB缓存 diff --git a/src/components/BannerCarousel.tsx b/src/components/BannerCarousel.tsx index 652ccbb..349bd62 100644 --- a/src/components/BannerCarousel.tsx +++ b/src/components/BannerCarousel.tsx @@ -23,6 +23,8 @@ export default function BannerCarousel({ autoPlayInterval = 5000 }: BannerCarous const [isLoading, setIsLoading] = useState(true); const [isPaused, setIsPaused] = useState(false); const [skipNextAutoPlay, setSkipNextAutoPlay] = useState(false); // 跳过下一次自动播放 + const [isYouTubeAccessible, setIsYouTubeAccessible] = useState(false); // YouTube连通性(默认false,检查后再决定) + const [enableTrailers, setEnableTrailers] = useState(false); // 是否启用预告片(默认关闭) const touchStartX = useRef(0); const touchEndX = useRef(0); const isManualChange = useRef(false); // 标记是否为手动切换 @@ -51,6 +53,39 @@ export default function BannerCarousel({ autoPlayInterval = 5000 }: BannerCarous return getTMDBImageUrl(path, 'original'); }; + // 读取本地设置 + useEffect(() => { + const setting = localStorage.getItem('enableTrailers'); + if (setting !== null) { + setEnableTrailers(setting === 'true'); + } + }, []); + + // 检测YouTube连通性 + useEffect(() => { + const checkYouTubeAccess = () => { + const img = document.createElement('img'); + const timeout = setTimeout(() => { + img.src = ''; + setIsYouTubeAccessible(false); + }, 3000); + + img.onload = () => { + clearTimeout(timeout); + setIsYouTubeAccessible(true); + }; + + img.onerror = () => { + clearTimeout(timeout); + setIsYouTubeAccessible(false); + }; + + img.src = 'https://i.ytimg.com/vi/dQw4w9WgXcQ/default.jpg'; + }; + + checkYouTubeAccess(); + }, []); + // 获取热门内容 useEffect(() => { const fetchTrending = async () => { @@ -234,7 +269,7 @@ export default function BannerCarousel({ autoPlayInterval = 5000 }: BannerCarous } }} > - {/* 背景图片 */} + {/* 背景图片或视频 */}
{items.map((item, index) => (
- {item.title} + {item.video_key && isYouTubeAccessible && enableTrailers ? ( + /* 显示YouTube视频 */ +
+