tmdb增加代理支持
This commit is contained in:
@@ -39,6 +39,7 @@
|
|||||||
"framer-motion": "^12.18.1",
|
"framer-motion": "^12.18.1",
|
||||||
"he": "^1.2.0",
|
"he": "^1.2.0",
|
||||||
"hls.js": "^1.6.10",
|
"hls.js": "^1.6.10",
|
||||||
|
"https-proxy-agent": "^7.0.6",
|
||||||
"lucide-react": "^0.438.0",
|
"lucide-react": "^0.438.0",
|
||||||
"media-icons": "^1.1.5",
|
"media-icons": "^1.1.5",
|
||||||
"mux.js": "^6.3.0",
|
"mux.js": "^6.3.0",
|
||||||
|
|||||||
Generated
+20
@@ -65,6 +65,9 @@ importers:
|
|||||||
hls.js:
|
hls.js:
|
||||||
specifier: ^1.6.10
|
specifier: ^1.6.10
|
||||||
version: 1.6.10
|
version: 1.6.10
|
||||||
|
https-proxy-agent:
|
||||||
|
specifier: ^7.0.6
|
||||||
|
version: 7.0.6
|
||||||
lucide-react:
|
lucide-react:
|
||||||
specifier: ^0.438.0
|
specifier: ^0.438.0
|
||||||
version: 0.438.0([email protected])
|
version: 0.438.0([email protected])
|
||||||
@@ -1889,6 +1892,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
|
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
|
||||||
engines: {node: '>= 6.0.0'}
|
engines: {node: '>= 6.0.0'}
|
||||||
|
|
||||||
|
[email protected]:
|
||||||
|
resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
|
||||||
|
engines: {node: '>= 14'}
|
||||||
|
|
||||||
[email protected]:
|
[email protected]:
|
||||||
resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
|
resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -3211,6 +3218,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
|
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
|
|
||||||
|
[email protected]:
|
||||||
|
resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
|
||||||
|
engines: {node: '>= 14'}
|
||||||
|
|
||||||
[email protected]:
|
[email protected]:
|
||||||
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
|
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
|
||||||
engines: {node: '>=10.17.0'}
|
engines: {node: '>=10.17.0'}
|
||||||
@@ -7539,6 +7550,8 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
[email protected]: {}
|
||||||
|
|
||||||
[email protected]:
|
[email protected]:
|
||||||
dependencies:
|
dependencies:
|
||||||
clean-stack: 2.2.0
|
clean-stack: 2.2.0
|
||||||
@@ -9088,6 +9101,13 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
[email protected]:
|
||||||
|
dependencies:
|
||||||
|
agent-base: 7.1.4
|
||||||
|
debug: 4.4.1([email protected])
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
[email protected]: {}
|
[email protected]: {}
|
||||||
|
|
||||||
[email protected]: {}
|
[email protected]: {}
|
||||||
|
|||||||
@@ -298,6 +298,7 @@ interface SiteConfig {
|
|||||||
DanmakuApiBase: string;
|
DanmakuApiBase: string;
|
||||||
DanmakuApiToken: string;
|
DanmakuApiToken: string;
|
||||||
TMDBApiKey?: string;
|
TMDBApiKey?: string;
|
||||||
|
TMDBProxy?: string;
|
||||||
EnableComments: boolean;
|
EnableComments: boolean;
|
||||||
EnableRegistration?: boolean;
|
EnableRegistration?: boolean;
|
||||||
RegistrationRequireTurnstile?: boolean;
|
RegistrationRequireTurnstile?: boolean;
|
||||||
@@ -4601,6 +4602,7 @@ const SiteConfigComponent = ({
|
|||||||
DanmakuApiBase: 'http://localhost:9321',
|
DanmakuApiBase: 'http://localhost:9321',
|
||||||
DanmakuApiToken: '87654321',
|
DanmakuApiToken: '87654321',
|
||||||
TMDBApiKey: '',
|
TMDBApiKey: '',
|
||||||
|
TMDBProxy: '',
|
||||||
EnableComments: false,
|
EnableComments: false,
|
||||||
EnableRegistration: false,
|
EnableRegistration: false,
|
||||||
RegistrationRequireTurnstile: false,
|
RegistrationRequireTurnstile: false,
|
||||||
@@ -4684,6 +4686,7 @@ const SiteConfigComponent = ({
|
|||||||
config.SiteConfig.DanmakuApiBase || 'http://localhost:9321',
|
config.SiteConfig.DanmakuApiBase || 'http://localhost:9321',
|
||||||
DanmakuApiToken: config.SiteConfig.DanmakuApiToken || '87654321',
|
DanmakuApiToken: config.SiteConfig.DanmakuApiToken || '87654321',
|
||||||
TMDBApiKey: config.SiteConfig.TMDBApiKey || '',
|
TMDBApiKey: config.SiteConfig.TMDBApiKey || '',
|
||||||
|
TMDBProxy: config.SiteConfig.TMDBProxy || '',
|
||||||
EnableComments: config.SiteConfig.EnableComments || false,
|
EnableComments: config.SiteConfig.EnableComments || false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -5242,6 +5245,28 @@ const SiteConfigComponent = ({
|
|||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* TMDB Proxy */}
|
||||||
|
<div>
|
||||||
|
<label className='block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2'>
|
||||||
|
TMDB 代理
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type='text'
|
||||||
|
placeholder='请输入代理地址(可选)'
|
||||||
|
value={siteSettings.TMDBProxy}
|
||||||
|
onChange={(e) =>
|
||||||
|
setSiteSettings((prev) => ({
|
||||||
|
...prev,
|
||||||
|
TMDBProxy: e.target.value,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
className='w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-green-500 focus:border-transparent'
|
||||||
|
/>
|
||||||
|
<p className='mt-1 text-xs text-gray-500 dark:text-gray-400'>
|
||||||
|
配置代理服务器地址,用于访问 TMDB API(可选)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 评论功能配置 */}
|
{/* 评论功能配置 */}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ export async function POST(request: NextRequest) {
|
|||||||
DanmakuApiBase,
|
DanmakuApiBase,
|
||||||
DanmakuApiToken,
|
DanmakuApiToken,
|
||||||
TMDBApiKey,
|
TMDBApiKey,
|
||||||
|
TMDBProxy,
|
||||||
EnableComments,
|
EnableComments,
|
||||||
CustomAdFilterCode,
|
CustomAdFilterCode,
|
||||||
CustomAdFilterVersion,
|
CustomAdFilterVersion,
|
||||||
@@ -74,6 +75,7 @@ export async function POST(request: NextRequest) {
|
|||||||
DanmakuApiBase: string;
|
DanmakuApiBase: string;
|
||||||
DanmakuApiToken: string;
|
DanmakuApiToken: string;
|
||||||
TMDBApiKey?: string;
|
TMDBApiKey?: string;
|
||||||
|
TMDBProxy?: string;
|
||||||
EnableComments: boolean;
|
EnableComments: boolean;
|
||||||
CustomAdFilterCode?: string;
|
CustomAdFilterCode?: string;
|
||||||
CustomAdFilterVersion?: number;
|
CustomAdFilterVersion?: number;
|
||||||
@@ -109,6 +111,7 @@ export async function POST(request: NextRequest) {
|
|||||||
typeof DanmakuApiBase !== 'string' ||
|
typeof DanmakuApiBase !== 'string' ||
|
||||||
typeof DanmakuApiToken !== 'string' ||
|
typeof DanmakuApiToken !== 'string' ||
|
||||||
(TMDBApiKey !== undefined && typeof TMDBApiKey !== 'string') ||
|
(TMDBApiKey !== undefined && typeof TMDBApiKey !== 'string') ||
|
||||||
|
(TMDBProxy !== undefined && typeof TMDBProxy !== 'string') ||
|
||||||
typeof EnableComments !== 'boolean' ||
|
typeof EnableComments !== 'boolean' ||
|
||||||
(CustomAdFilterCode !== undefined && typeof CustomAdFilterCode !== 'string') ||
|
(CustomAdFilterCode !== undefined && typeof CustomAdFilterCode !== 'string') ||
|
||||||
(CustomAdFilterVersion !== undefined && typeof CustomAdFilterVersion !== 'number') ||
|
(CustomAdFilterVersion !== undefined && typeof CustomAdFilterVersion !== 'number') ||
|
||||||
@@ -159,6 +162,7 @@ export async function POST(request: NextRequest) {
|
|||||||
DanmakuApiBase,
|
DanmakuApiBase,
|
||||||
DanmakuApiToken,
|
DanmakuApiToken,
|
||||||
TMDBApiKey,
|
TMDBApiKey,
|
||||||
|
TMDBProxy,
|
||||||
EnableComments,
|
EnableComments,
|
||||||
CustomAdFilterCode,
|
CustomAdFilterCode,
|
||||||
CustomAdFilterVersion,
|
CustomAdFilterVersion,
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ export async function GET(request: NextRequest) {
|
|||||||
// 缓存不存在或已过期,获取新数据
|
// 缓存不存在或已过期,获取新数据
|
||||||
const config = await getConfig();
|
const config = await getConfig();
|
||||||
const tmdbApiKey = config.SiteConfig?.TMDBApiKey;
|
const tmdbApiKey = config.SiteConfig?.TMDBApiKey;
|
||||||
|
const tmdbProxy = config.SiteConfig?.TMDBProxy;
|
||||||
|
|
||||||
if (!tmdbApiKey) {
|
if (!tmdbApiKey) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
@@ -36,7 +37,7 @@ export async function GET(request: NextRequest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 调用TMDB API获取数据
|
// 调用TMDB API获取数据
|
||||||
const result = await getTMDBUpcomingContent(tmdbApiKey);
|
const result = await getTMDBUpcomingContent(tmdbApiKey, tmdbProxy);
|
||||||
|
|
||||||
if (result.code !== 200) {
|
if (result.code !== 200) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ export interface AdminConfig {
|
|||||||
DanmakuApiToken: string;
|
DanmakuApiToken: string;
|
||||||
// TMDB配置
|
// TMDB配置
|
||||||
TMDBApiKey?: string;
|
TMDBApiKey?: string;
|
||||||
|
TMDBProxy?: string;
|
||||||
// 评论功能开关
|
// 评论功能开关
|
||||||
EnableComments: boolean;
|
EnableComments: boolean;
|
||||||
// 自定义去广告代码
|
// 自定义去广告代码
|
||||||
|
|||||||
@@ -223,6 +223,7 @@ async function getInitConfig(configFile: string, subConfig: {
|
|||||||
DanmakuApiToken: process.env.DANMAKU_API_TOKEN || '87654321',
|
DanmakuApiToken: process.env.DANMAKU_API_TOKEN || '87654321',
|
||||||
// TMDB配置
|
// TMDB配置
|
||||||
TMDBApiKey: '',
|
TMDBApiKey: '',
|
||||||
|
TMDBProxy: '',
|
||||||
// 评论功能开关
|
// 评论功能开关
|
||||||
EnableComments: false,
|
EnableComments: false,
|
||||||
},
|
},
|
||||||
|
|||||||
+21
-11
@@ -1,5 +1,7 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any,no-console */
|
/* eslint-disable @typescript-eslint/no-explicit-any,no-console */
|
||||||
|
|
||||||
|
import { HttpsProxyAgent } from 'https-proxy-agent';
|
||||||
|
|
||||||
export interface TMDBMovie {
|
export interface TMDBMovie {
|
||||||
id: number;
|
id: number;
|
||||||
title: string;
|
title: string;
|
||||||
@@ -48,21 +50,24 @@ interface TMDBTVAiringTodayResponse {
|
|||||||
* @param apiKey - TMDB API Key
|
* @param apiKey - TMDB API Key
|
||||||
* @param page - 页码
|
* @param page - 页码
|
||||||
* @param region - 地区代码,默认 CN (中国)
|
* @param region - 地区代码,默认 CN (中国)
|
||||||
|
* @param proxy - 代理服务器地址
|
||||||
* @returns 即将上映的电影列表
|
* @returns 即将上映的电影列表
|
||||||
*/
|
*/
|
||||||
export async function getTMDBUpcomingMovies(
|
export async function getTMDBUpcomingMovies(
|
||||||
apiKey: string,
|
apiKey: string,
|
||||||
page: number = 1,
|
page: number = 1,
|
||||||
region: string = 'CN'
|
region: string = 'CN',
|
||||||
|
proxy?: string
|
||||||
): Promise<{ code: number; list: TMDBMovie[] }> {
|
): Promise<{ code: number; list: TMDBMovie[] }> {
|
||||||
try {
|
try {
|
||||||
if (!apiKey) {
|
if (!apiKey) {
|
||||||
return { code: 400, list: [] };
|
return { code: 400, list: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch(
|
const url = `https://api.themoviedb.org/3/movie/upcoming?api_key=${apiKey}&language=zh-CN&page=${page}®ion=${region}`;
|
||||||
`https://api.themoviedb.org/3/movie/upcoming?api_key=${apiKey}&language=zh-CN&page=${page}®ion=${region}`
|
const fetchOptions: RequestInit = proxy ? { agent: new HttpsProxyAgent(proxy) as any } : {};
|
||||||
);
|
|
||||||
|
const response = await fetch(url, fetchOptions);
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
console.error('TMDB API 请求失败:', response.status, response.statusText);
|
console.error('TMDB API 请求失败:', response.status, response.statusText);
|
||||||
@@ -85,11 +90,13 @@ export async function getTMDBUpcomingMovies(
|
|||||||
* 获取正在播出的电视剧
|
* 获取正在播出的电视剧
|
||||||
* @param apiKey - TMDB API Key
|
* @param apiKey - TMDB API Key
|
||||||
* @param page - 页码
|
* @param page - 页码
|
||||||
|
* @param proxy - 代理服务器地址
|
||||||
* @returns 正在播出的电视剧列表
|
* @returns 正在播出的电视剧列表
|
||||||
*/
|
*/
|
||||||
export async function getTMDBUpcomingTVShows(
|
export async function getTMDBUpcomingTVShows(
|
||||||
apiKey: string,
|
apiKey: string,
|
||||||
page: number = 1
|
page: number = 1,
|
||||||
|
proxy?: string
|
||||||
): Promise<{ code: number; list: TMDBTVShow[] }> {
|
): Promise<{ code: number; list: TMDBTVShow[] }> {
|
||||||
try {
|
try {
|
||||||
if (!apiKey) {
|
if (!apiKey) {
|
||||||
@@ -97,9 +104,10 @@ export async function getTMDBUpcomingTVShows(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 使用 on_the_air 接口获取正在播出的电视剧
|
// 使用 on_the_air 接口获取正在播出的电视剧
|
||||||
const response = await fetch(
|
const url = `https://api.themoviedb.org/3/tv/on_the_air?api_key=${apiKey}&language=zh-CN&page=${page}`;
|
||||||
`https://api.themoviedb.org/3/tv/on_the_air?api_key=${apiKey}&language=zh-CN&page=${page}`
|
const fetchOptions: RequestInit = proxy ? { agent: new HttpsProxyAgent(proxy) as any } : {};
|
||||||
);
|
|
||||||
|
const response = await fetch(url, fetchOptions);
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
console.error('TMDB TV API 请求失败:', response.status, response.statusText);
|
console.error('TMDB TV API 请求失败:', response.status, response.statusText);
|
||||||
@@ -121,10 +129,12 @@ export async function getTMDBUpcomingTVShows(
|
|||||||
/**
|
/**
|
||||||
* 获取即将上映/播出的内容(电影+电视剧)
|
* 获取即将上映/播出的内容(电影+电视剧)
|
||||||
* @param apiKey - TMDB API Key
|
* @param apiKey - TMDB API Key
|
||||||
|
* @param proxy - 代理服务器地址
|
||||||
* @returns 统一格式的即将上映/播出列表
|
* @returns 统一格式的即将上映/播出列表
|
||||||
*/
|
*/
|
||||||
export async function getTMDBUpcomingContent(
|
export async function getTMDBUpcomingContent(
|
||||||
apiKey: string
|
apiKey: string,
|
||||||
|
proxy?: string
|
||||||
): Promise<{ code: number; list: TMDBItem[] }> {
|
): Promise<{ code: number; list: TMDBItem[] }> {
|
||||||
try {
|
try {
|
||||||
if (!apiKey) {
|
if (!apiKey) {
|
||||||
@@ -133,8 +143,8 @@ export async function getTMDBUpcomingContent(
|
|||||||
|
|
||||||
// 并行获取电影和电视剧数据
|
// 并行获取电影和电视剧数据
|
||||||
const [moviesResult, tvShowsResult] = await Promise.all([
|
const [moviesResult, tvShowsResult] = await Promise.all([
|
||||||
getTMDBUpcomingMovies(apiKey),
|
getTMDBUpcomingMovies(apiKey, 1, 'CN', proxy),
|
||||||
getTMDBUpcomingTVShows(apiKey),
|
getTMDBUpcomingTVShows(apiKey, 1, proxy),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 检查是否有错误
|
// 检查是否有错误
|
||||||
|
|||||||
Reference in New Issue
Block a user