From 30278b3ac14a5fda7e98603bb344e38df4b75acd Mon Sep 17 00:00:00 2001 From: mtvpls Date: Sun, 11 Jan 2026 22:05:32 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=8F=E9=9B=85=E5=AF=B9id=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?base58?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/source-detail/route.ts | 25 +++++++++++++++--- src/app/api/xiaoya/play/route.ts | 9 +++++-- src/app/private-library/page.tsx | 12 ++++++--- src/lib/utils.ts | 41 ++++++++++++++++++++++++++++++ src/lib/xiaoya-metadata.ts | 23 +++++++++++++++-- 5 files changed, 99 insertions(+), 11 deletions(-) diff --git a/src/app/api/source-detail/route.ts b/src/app/api/source-detail/route.ts index 307842a..57f6f1f 100644 --- a/src/app/api/source-detail/route.ts +++ b/src/app/api/source-detail/route.ts @@ -140,6 +140,7 @@ export async function GET(request: NextRequest) { const { XiaoyaClient } = await import('@/lib/xiaoya.client'); const { getXiaoyaMetadata, getXiaoyaEpisodes } = await import('@/lib/xiaoya-metadata'); + const { base58Decode, base58Encode } = await import('@/lib/utils'); const client = new XiaoyaClient( xiaoyaConfig.ServerURL, @@ -148,27 +149,42 @@ export async function GET(request: NextRequest) { xiaoyaConfig.Token ); + // 对id进行base58解码得到真实路径 + let decodedPath: string; + try { + decodedPath = base58Decode(id); + console.log('[xiaoya] 解码路径:', decodedPath); + } catch (decodeError) { + console.error('[xiaoya] Base58解码失败:', decodeError); + throw new Error('无效的视频ID'); + } + + // 验证解码后的路径 + if (!decodedPath || decodedPath.trim() === '') { + throw new Error('解码后的路径为空'); + } + // 获取元数据 const metadata = await getXiaoyaMetadata( client, - id, // id 就是视频路径 + decodedPath, // 使用解码后的路径 config.SiteConfig.TMDBApiKey, config.SiteConfig.TMDBProxy ); // 获取集数列表 - const episodes = await getXiaoyaEpisodes(client, id); + const episodes = await getXiaoyaEpisodes(client, decodedPath); const result = { source: 'xiaoya', source_name: '小雅', - id: id, + id: id, // 保持编码后的id title: metadata.title, poster: metadata.poster || '', year: metadata.year || '', douban_id: 0, desc: metadata.plot || '', - episodes: episodes.map(ep => `/api/xiaoya/play?path=${encodeURIComponent(ep.path)}`), + episodes: episodes.map(ep => `/api/xiaoya/play?path=${encodeURIComponent(base58Encode(ep.path))}`), episodes_titles: episodes.map(ep => ep.title), subtitles: [], proxyMode: false, @@ -176,6 +192,7 @@ export async function GET(request: NextRequest) { return NextResponse.json(result); } catch (error) { + console.error('[xiaoya] 获取详情失败:', error); return NextResponse.json( { error: (error as Error).message }, { status: 500 } diff --git a/src/app/api/xiaoya/play/route.ts b/src/app/api/xiaoya/play/route.ts index bc59c03..e564dd3 100644 --- a/src/app/api/xiaoya/play/route.ts +++ b/src/app/api/xiaoya/play/route.ts @@ -60,6 +60,7 @@ async function getFinalUrl(url: string, maxRedirects = 5): Promise { /** * GET /api/xiaoya/play?path= * 获取小雅视频的播放链接(优先使用视频预览流,失败时降级到直连) + * path参数为base58编码的路径 */ export async function GET(request: NextRequest) { try { @@ -69,12 +70,16 @@ export async function GET(request: NextRequest) { } const { searchParams } = new URL(request.url); - const path = searchParams.get('path'); + const encodedPath = searchParams.get('path'); - if (!path) { + if (!encodedPath) { return NextResponse.json({ error: '缺少参数' }, { status: 400 }); } + // 对path进行base58解码 + const { base58Decode } = await import('@/lib/utils'); + const path = base58Decode(encodedPath); + const config = await getConfig(); const xiaoyaConfig = config.XiaoyaConfig; diff --git a/src/app/private-library/page.tsx b/src/app/private-library/page.tsx index e7949db..72561c9 100644 --- a/src/app/private-library/page.tsx +++ b/src/app/private-library/page.tsx @@ -8,6 +8,7 @@ import { useEffect, useState, useRef, useMemo } from 'react'; import CapsuleSwitch from '@/components/CapsuleSwitch'; import PageLayout from '@/components/PageLayout'; import VideoCard from '@/components/VideoCard'; +import { base58Encode } from '@/lib/utils'; type LibrarySourceType = 'openlist' | 'emby' | 'xiaoya' | `emby:${string}` | `emby_${string}`; @@ -692,8 +693,9 @@ export default function PrivateLibraryPage() { key={item.path} onClick={() => { if (isVideoFile) { - // 视频文件:直接播放 - router.push(`/play?source=xiaoya&id=${encodeURIComponent(item.path)}&title=${encodeURIComponent(title)}`); + // 视频文件:直接播放,对path进行base58编码 + const encodedPath = base58Encode(item.path); + router.push(`/play?source=xiaoya&id=${encodeURIComponent(encodedPath)}&title=${encodeURIComponent(title)}`); } else { // 文件夹:进入浏览 setXiaoyaPath(item.path); @@ -792,7 +794,11 @@ export default function PrivateLibraryPage() { return (