小雅id改为目录
This commit is contained in:
@@ -22,6 +22,7 @@ export async function GET(request: NextRequest) {
|
|||||||
const id = searchParams.get('id');
|
const id = searchParams.get('id');
|
||||||
const sourceCode = searchParams.get('source');
|
const sourceCode = searchParams.get('source');
|
||||||
const title = searchParams.get('title'); // 用于搜索的标题
|
const title = searchParams.get('title'); // 用于搜索的标题
|
||||||
|
const fileName = searchParams.get('fileName'); // 小雅源:用户点击的文件名
|
||||||
|
|
||||||
if (!id || !sourceCode || !title) {
|
if (!id || !sourceCode || !title) {
|
||||||
return NextResponse.json({ error: '缺少必要参数' }, { status: 400 });
|
return NextResponse.json({ error: '缺少必要参数' }, { status: 400 });
|
||||||
@@ -149,41 +150,52 @@ export async function GET(request: NextRequest) {
|
|||||||
xiaoyaConfig.Token
|
xiaoyaConfig.Token
|
||||||
);
|
);
|
||||||
|
|
||||||
// 对id进行base58解码得到真实路径
|
// 对id进行base58解码得到目录路径
|
||||||
let decodedPath: string;
|
let decodedDirPath: string;
|
||||||
try {
|
try {
|
||||||
decodedPath = base58Decode(id);
|
decodedDirPath = base58Decode(id);
|
||||||
console.log('[xiaoya] 解码路径:', decodedPath);
|
console.log('[xiaoya] 解码目录路径:', decodedDirPath);
|
||||||
} catch (decodeError) {
|
} catch (decodeError) {
|
||||||
console.error('[xiaoya] Base58解码失败:', decodeError);
|
console.error('[xiaoya] Base58解码失败:', decodeError);
|
||||||
throw new Error('无效的视频ID');
|
throw new Error('无效的视频ID');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验证解码后的路径
|
// 验证解码后的路径
|
||||||
if (!decodedPath || decodedPath.trim() === '') {
|
if (!decodedDirPath || decodedDirPath.trim() === '') {
|
||||||
throw new Error('解码后的路径为空');
|
throw new Error('解码后的路径为空');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取元数据
|
// 如果有fileName参数,拼接完整文件路径
|
||||||
|
let clickedFilePath: string | undefined;
|
||||||
|
if (fileName) {
|
||||||
|
// 拼接目录路径和文件名
|
||||||
|
clickedFilePath = `${decodedDirPath}${decodedDirPath.endsWith('/') ? '' : '/'}${fileName}`;
|
||||||
|
console.log('[xiaoya] 用户点击的文件路径:', clickedFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取元数据(使用目录路径或点击的文件路径)
|
||||||
|
const metadataPath = clickedFilePath || decodedDirPath;
|
||||||
const metadata = await getXiaoyaMetadata(
|
const metadata = await getXiaoyaMetadata(
|
||||||
client,
|
client,
|
||||||
decodedPath, // 使用解码后的路径
|
metadataPath,
|
||||||
config.SiteConfig.TMDBApiKey,
|
config.SiteConfig.TMDBApiKey,
|
||||||
config.SiteConfig.TMDBProxy
|
config.SiteConfig.TMDBProxy
|
||||||
);
|
);
|
||||||
|
|
||||||
// 获取集数列表
|
// 获取集数列表(使用目录路径或点击的文件路径)
|
||||||
const episodes = await getXiaoyaEpisodes(client, decodedPath);
|
const episodes = await getXiaoyaEpisodes(client, metadataPath);
|
||||||
|
|
||||||
// 找到用户点击的文件在集数列表中的索引
|
// 如果有点击的文件路径,找到对应的集数索引
|
||||||
const clickedFileIndex = episodes.findIndex(ep => ep.path === decodedPath);
|
let clickedFileIndex = -1;
|
||||||
console.log('[xiaoya] 用户点击的文件:', decodedPath);
|
if (clickedFilePath) {
|
||||||
console.log('[xiaoya] 文件在集数列表中的索引:', clickedFileIndex);
|
clickedFileIndex = episodes.findIndex(ep => ep.path === clickedFilePath);
|
||||||
|
console.log('[xiaoya] 文件在集数列表中的索引:', clickedFileIndex);
|
||||||
|
}
|
||||||
|
|
||||||
const result = {
|
const result = {
|
||||||
source: 'xiaoya',
|
source: 'xiaoya',
|
||||||
source_name: '小雅',
|
source_name: '小雅',
|
||||||
id: id, // 保持编码后的id
|
id: id, // 保持编码后的目录id
|
||||||
title: metadata.title,
|
title: metadata.title,
|
||||||
poster: metadata.poster || '',
|
poster: metadata.poster || '',
|
||||||
year: metadata.year || '',
|
year: metadata.year || '',
|
||||||
|
|||||||
+18
-5
@@ -475,6 +475,7 @@ function PlayPageClient() {
|
|||||||
// 当前源和ID - source 直接存储完整格式(如 'emby_wumei' 或 'emby')
|
// 当前源和ID - source 直接存储完整格式(如 'emby_wumei' 或 'emby')
|
||||||
const [currentSource, setCurrentSource] = useState(searchParams.get('source') || '');
|
const [currentSource, setCurrentSource] = useState(searchParams.get('source') || '');
|
||||||
const [currentId, setCurrentId] = useState(searchParams.get('id') || '');
|
const [currentId, setCurrentId] = useState(searchParams.get('id') || '');
|
||||||
|
const [fileName] = useState(searchParams.get('fileName') || ''); // 小雅源:用户点击的文件名
|
||||||
|
|
||||||
// 解析 source 参数以获取 embyKey(仅用于 API 调用)
|
// 解析 source 参数以获取 embyKey(仅用于 API 调用)
|
||||||
const parseSourceForApi = (source: string): { source: string; embyKey?: string } => {
|
const parseSourceForApi = (source: string): { source: string; embyKey?: string } => {
|
||||||
@@ -2353,12 +2354,16 @@ function PlayPageClient() {
|
|||||||
const fetchSourceDetail = async (
|
const fetchSourceDetail = async (
|
||||||
source: string,
|
source: string,
|
||||||
id: string,
|
id: string,
|
||||||
title: string
|
title: string,
|
||||||
|
fileNameParam?: string
|
||||||
): Promise<SearchResult[]> => {
|
): Promise<SearchResult[]> => {
|
||||||
try {
|
try {
|
||||||
const detailResponse = await fetch(
|
let url = `/api/source-detail?source=${source}&id=${id}&title=${encodeURIComponent(title)}`;
|
||||||
`/api/source-detail?source=${source}&id=${id}&title=${encodeURIComponent(title)}`
|
// 如果有fileName参数(小雅源),添加到URL
|
||||||
);
|
if (fileNameParam) {
|
||||||
|
url += `&fileName=${encodeURIComponent(fileNameParam)}`;
|
||||||
|
}
|
||||||
|
const detailResponse = await fetch(url);
|
||||||
if (!detailResponse.ok) {
|
if (!detailResponse.ok) {
|
||||||
throw new Error('获取视频详情失败');
|
throw new Error('获取视频详情失败');
|
||||||
}
|
}
|
||||||
@@ -2515,7 +2520,13 @@ function PlayPageClient() {
|
|||||||
// 先快速获取当前源的详情
|
// 先快速获取当前源的详情
|
||||||
try {
|
try {
|
||||||
// currentSource 已经是完整格式(如 'emby_wumei')
|
// currentSource 已经是完整格式(如 'emby_wumei')
|
||||||
const currentSourceDetail = await fetchSourceDetail(currentSource, currentId, searchTitle || videoTitle);
|
// 如果是小雅源且有fileName参数,传递给API
|
||||||
|
const currentSourceDetail = await fetchSourceDetail(
|
||||||
|
currentSource,
|
||||||
|
currentId,
|
||||||
|
searchTitle || videoTitle,
|
||||||
|
currentSource === 'xiaoya' ? fileName : undefined
|
||||||
|
);
|
||||||
if (currentSourceDetail.length > 0) {
|
if (currentSourceDetail.length > 0) {
|
||||||
detailData = currentSourceDetail[0];
|
detailData = currentSourceDetail[0];
|
||||||
sourcesInfo = currentSourceDetail;
|
sourcesInfo = currentSourceDetail;
|
||||||
@@ -2666,6 +2677,8 @@ function PlayPageClient() {
|
|||||||
newUrl.searchParams.set('year', detailData.year);
|
newUrl.searchParams.set('year', detailData.year);
|
||||||
// 保持原有的 title,不更新
|
// 保持原有的 title,不更新
|
||||||
newUrl.searchParams.delete('prefer');
|
newUrl.searchParams.delete('prefer');
|
||||||
|
// 删除fileName参数,避免换集后刷新跳回到最初点击的那一集
|
||||||
|
newUrl.searchParams.delete('fileName');
|
||||||
window.history.replaceState({}, '', newUrl.toString());
|
window.history.replaceState({}, '', newUrl.toString());
|
||||||
|
|
||||||
setLoadingStage('ready');
|
setLoadingStage('ready');
|
||||||
|
|||||||
@@ -693,9 +693,12 @@ export default function PrivateLibraryPage() {
|
|||||||
key={item.path}
|
key={item.path}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (isVideoFile) {
|
if (isVideoFile) {
|
||||||
// 视频文件:直接播放,对path进行base58编码
|
// 视频文件:提取父目录作为ID,传递文件名
|
||||||
const encodedPath = base58Encode(item.path);
|
const pathParts = item.path.split('/').filter(Boolean);
|
||||||
router.push(`/play?source=xiaoya&id=${encodeURIComponent(encodedPath)}&title=${encodeURIComponent(title)}`);
|
const parentDir = '/' + pathParts.slice(0, -1).join('/');
|
||||||
|
const fileName = pathParts[pathParts.length - 1];
|
||||||
|
const encodedDirPath = base58Encode(parentDir);
|
||||||
|
router.push(`/play?source=xiaoya&id=${encodeURIComponent(encodedDirPath)}&fileName=${encodeURIComponent(fileName)}&title=${encodeURIComponent(title)}`);
|
||||||
} else {
|
} else {
|
||||||
// 文件夹:进入浏览
|
// 文件夹:进入浏览
|
||||||
setXiaoyaPath(item.path);
|
setXiaoyaPath(item.path);
|
||||||
@@ -795,9 +798,9 @@ export default function PrivateLibraryPage() {
|
|||||||
<button
|
<button
|
||||||
key={file.path}
|
key={file.path}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
// 对path进行base58编码
|
// ID使用目录路径,额外传递文件名(不需要编码)
|
||||||
const encodedPath = base58Encode(file.path);
|
const encodedDirPath = base58Encode(xiaoyaPath);
|
||||||
router.push(`/play?source=xiaoya&id=${encodeURIComponent(encodedPath)}&title=${encodeURIComponent(title)}`);
|
router.push(`/play?source=xiaoya&id=${encodeURIComponent(encodedDirPath)}&fileName=${encodeURIComponent(file.name)}&title=${encodeURIComponent(title)}`);
|
||||||
}}
|
}}
|
||||||
className='flex items-center gap-2 p-3 bg-gray-100 dark:bg-gray-800 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors text-left'
|
className='flex items-center gap-2 p-3 bg-gray-100 dark:bg-gray-800 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors text-left'
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user