openlist和小雅增加禁用预览

This commit is contained in:
mtvpls
2026-01-14 17:02:21 +08:00
parent 6d7a3b551b
commit 2dd2c007a9
6 changed files with 121 additions and 1 deletions

View File

@@ -2781,6 +2781,7 @@ const OpenListConfigComponent = ({
const [offlineDownloadPath, setOfflineDownloadPath] = useState('/');
const [scanInterval, setScanInterval] = useState(0);
const [scanMode, setScanMode] = useState<'torrent' | 'name' | 'hybrid'>('hybrid');
const [disableVideoPreview, setDisableVideoPreview] = useState(false);
const [videos, setVideos] = useState<any[]>([]);
const [refreshing, setRefreshing] = useState(false);
const [scanProgress, setScanProgress] = useState<{
@@ -2801,6 +2802,7 @@ const OpenListConfigComponent = ({
setOfflineDownloadPath(config.OpenListConfig.OfflineDownloadPath || '/');
setScanInterval(config.OpenListConfig.ScanInterval || 0);
setScanMode(config.OpenListConfig.ScanMode || 'hybrid');
setDisableVideoPreview(config.OpenListConfig.DisableVideoPreview || false);
}
}, [config]);
@@ -2842,6 +2844,7 @@ const OpenListConfigComponent = ({
OfflineDownloadPath: offlineDownloadPath,
ScanInterval: scanInterval,
ScanMode: scanMode,
DisableVideoPreview: disableVideoPreview,
}),
});
@@ -3218,6 +3221,30 @@ const OpenListConfigComponent = ({
</p>
</div>
<div className='flex items-center justify-between py-3 border-b border-gray-200 dark:border-gray-700'>
<div>
<h3 className='text-sm font-medium text-gray-900 dark:text-white'>
</h3>
<p className='text-xs text-gray-500 dark:text-gray-400 mt-1'>
使
</p>
</div>
<button
onClick={() => setDisableVideoPreview(!disableVideoPreview)}
disabled={!enabled}
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${
disableVideoPreview ? 'bg-blue-600' : 'bg-gray-200 dark:bg-gray-700'
} ${!enabled ? 'opacity-50 cursor-not-allowed' : ''}`}
>
<span
className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
disableVideoPreview ? 'translate-x-6' : 'translate-x-1'
}`}
/>
</button>
</div>
<div className='flex gap-3'>
<button
onClick={handleCheckConnectivity}
@@ -8605,6 +8632,7 @@ const XiaoyaConfigComponent = ({
const [token, setToken] = useState('');
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [disableVideoPreview, setDisableVideoPreview] = useState(false);
useEffect(() => {
if (config?.XiaoyaConfig) {
@@ -8613,6 +8641,7 @@ const XiaoyaConfigComponent = ({
setToken(config.XiaoyaConfig.Token || '');
setUsername(config.XiaoyaConfig.Username || '');
setPassword(config.XiaoyaConfig.Password || '');
setDisableVideoPreview(config.XiaoyaConfig.DisableVideoPreview || false);
}
}, [config]);
@@ -8629,6 +8658,7 @@ const XiaoyaConfigComponent = ({
Token: token,
Username: username,
Password: password,
DisableVideoPreview: disableVideoPreview,
}),
});
@@ -8741,6 +8771,29 @@ const XiaoyaConfigComponent = ({
/>
</div>
<div className='flex items-center justify-between py-3 border-b border-gray-200 dark:border-gray-700'>
<div>
<h3 className='text-sm font-medium text-gray-900 dark:text-white'>
</h3>
<p className='text-xs text-gray-500 dark:text-gray-400 mt-1'>
使
</p>
</div>
<button
onClick={() => setDisableVideoPreview(!disableVideoPreview)}
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${
disableVideoPreview ? 'bg-blue-600' : 'bg-gray-200 dark:bg-gray-700'
}`}
>
<span
className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
disableVideoPreview ? 'translate-x-6' : 'translate-x-1'
}`}
/>
</button>
</div>
<div className='grid grid-cols-2 gap-4'>
<div>
<label className='block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2'>

View File

@@ -26,7 +26,7 @@ export async function POST(request: NextRequest) {
try {
const body = await request.json();
const { action, Enabled, URL, Username, Password, RootPaths, OfflineDownloadPath, ScanInterval, ScanMode } = body;
const { action, Enabled, URL, Username, Password, RootPaths, OfflineDownloadPath, ScanInterval, ScanMode, DisableVideoPreview } = body;
const authInfo = getAuthInfoFromCookie(request);
if (!authInfo || !authInfo.username) {
@@ -59,6 +59,7 @@ export async function POST(request: NextRequest) {
ResourceCount: adminConfig.OpenListConfig?.ResourceCount,
ScanInterval: 0,
ScanMode: ScanMode || 'hybrid',
DisableVideoPreview: DisableVideoPreview || false,
};
await db.saveAdminConfig(adminConfig);
@@ -118,6 +119,7 @@ export async function POST(request: NextRequest) {
ResourceCount: adminConfig.OpenListConfig?.ResourceCount,
ScanInterval: scanInterval,
ScanMode: ScanMode || 'hybrid',
DisableVideoPreview: DisableVideoPreview || false,
};
await db.saveAdminConfig(adminConfig);

View File

@@ -55,6 +55,7 @@ export async function POST(request: NextRequest) {
Token: configData.Token,
Username: configData.Username,
Password: configData.Password,
DisableVideoPreview: configData.DisableVideoPreview || false,
};
await db.saveAdminConfig(config);

View File

@@ -102,6 +102,43 @@ export async function GET(request: NextRequest) {
openListConfig.Password
);
// 如果启用了禁用预览视频,直接使用直连方法
if (openListConfig.DisableVideoPreview) {
const fileResponse = await client.getFile(filePath);
if (fileResponse.code !== 200 || !fileResponse.data.raw_url) {
console.error('[OpenList Play] 获取播放URL失败:', {
fileName,
code: fileResponse.code,
message: fileResponse.message,
});
return NextResponse.json(
{ error: '获取播放链接失败' },
{ status: 500 }
);
}
// 如果指定了 format=json使用 getFinalUrl 并返回 JSON
if (format === 'json') {
const finalUrl = await getFinalUrl(fileResponse.data.raw_url);
// 检查URL是否为空
if (!finalUrl || finalUrl.trim() === '') {
throw new Error('获取到的播放链接为空');
}
return NextResponse.json({ url: finalUrl });
}
// 检查URL是否为空
if (!fileResponse.data.raw_url || fileResponse.data.raw_url.trim() === '') {
throw new Error('获取到的播放链接为空');
}
// 默认返回重定向(用于 tvbox
return NextResponse.redirect(fileResponse.data.raw_url);
}
// 优先尝试视频预览流方法
try {
const data = await client.getVideoPreview(filePath);

View File

@@ -101,6 +101,31 @@ export async function GET(request: NextRequest) {
xiaoyaConfig.Token
);
// 如果启用了禁用预览视频,直接使用直连方法
if (xiaoyaConfig.DisableVideoPreview) {
const playUrl = await client.getDownloadUrl(path);
// 如果指定了 format=json使用 getFinalUrl 并返回 JSON
if (format === 'json') {
const finalUrl = await getFinalUrl(playUrl);
// 检查URL是否为空
if (!finalUrl || finalUrl.trim() === '') {
throw new Error('获取到的播放链接为空');
}
return NextResponse.json({ url: finalUrl });
}
// 检查URL是否为空
if (!playUrl || playUrl.trim() === '') {
throw new Error('获取到的播放链接为空');
}
// 默认返回重定向(用于 tvbox
return NextResponse.redirect(playUrl);
}
// 优先尝试视频预览流方法
try {
const token = await client.getToken();

View File

@@ -116,6 +116,7 @@ export interface AdminConfig {
ResourceCount?: number; // 资源数量
ScanInterval?: number; // 定时扫描间隔分钟0表示关闭最低60分钟
ScanMode?: 'torrent' | 'name' | 'hybrid'; // 扫描模式torrent=种子库匹配name=名字匹配hybrid=混合模式(默认)
DisableVideoPreview?: boolean; // 禁用预览视频,直接返回直连链接
};
AIConfig?: {
Enabled: boolean; // 是否启用AI问片功能
@@ -203,6 +204,7 @@ export interface AdminConfig {
Token?: string; // Token 认证(推荐)
Username?: string; // 用户名认证(备选)
Password?: string; // 密码认证(备选)
DisableVideoPreview?: boolean; // 禁用预览视频,直接返回直连链接
};
}