feat: concurrent refresh
This commit is contained in:
@@ -23,18 +23,20 @@ export async function POST(request: NextRequest) {
|
||||
}
|
||||
}
|
||||
|
||||
for (const liveInfo of config.LiveConfig || []) {
|
||||
if (liveInfo.disabled) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
const nums = await refreshLiveChannels(liveInfo);
|
||||
liveInfo.channelNumber = nums;
|
||||
} catch (error) {
|
||||
console.error('刷新直播源失败:', error);
|
||||
liveInfo.channelNumber = 0;
|
||||
}
|
||||
}
|
||||
// 并发刷新所有启用的直播源
|
||||
const refreshPromises = (config.LiveConfig || [])
|
||||
.filter(liveInfo => !liveInfo.disabled)
|
||||
.map(async (liveInfo) => {
|
||||
try {
|
||||
const nums = await refreshLiveChannels(liveInfo);
|
||||
liveInfo.channelNumber = nums;
|
||||
} catch (error) {
|
||||
liveInfo.channelNumber = 0;
|
||||
}
|
||||
});
|
||||
|
||||
// 等待所有刷新任务完成
|
||||
await Promise.all(refreshPromises);
|
||||
|
||||
// 保存配置
|
||||
await db.saveAdminConfig(config);
|
||||
|
||||
@@ -7,11 +7,11 @@ import Hls from 'hls.js';
|
||||
import { Radio, Tv } from 'lucide-react';
|
||||
import { Suspense, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { processImageUrl } from '@/lib/utils';
|
||||
import { parseCustomTimeFormat } from '@/lib/time';
|
||||
import { processImageUrl } from '@/lib/utils';
|
||||
|
||||
import PageLayout from '@/components/PageLayout';
|
||||
import EpgScrollableRow from '@/components/EpgScrollableRow';
|
||||
import PageLayout from '@/components/PageLayout';
|
||||
|
||||
// 扩展 HTMLVideoElement 类型以支持 hls 属性
|
||||
declare global {
|
||||
@@ -139,7 +139,7 @@ function LivePageClient() {
|
||||
|
||||
const cleanedPrograms: Array<{ start: string; end: string; title: string }> = [];
|
||||
let removedCount = 0;
|
||||
let dateFilteredCount = programs.length - todayPrograms.length;
|
||||
const dateFilteredCount = programs.length - todayPrograms.length;
|
||||
|
||||
for (let i = 0; i < sortedPrograms.length; i++) {
|
||||
const currentProgram = sortedPrograms[i];
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { Clock, Tv, Target } from 'lucide-react';
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
|
||||
import { Clock, Target, Tv } from 'lucide-react';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { parseCustomTimeFormat, formatTimeToHHMM } from '@/lib/time';
|
||||
|
||||
import { formatTimeToHHMM, parseCustomTimeFormat } from '@/lib/time';
|
||||
|
||||
interface EpgProgram {
|
||||
start: string;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* eslint-disable no-constant-condition */
|
||||
|
||||
import { getConfig } from "@/lib/config";
|
||||
import { db } from "@/lib/db";
|
||||
|
||||
@@ -99,14 +101,12 @@ async function parseEpg(epgUrl: string, ua: string, tvgIds: string[]): Promise<{
|
||||
},
|
||||
});
|
||||
if (!response.ok) {
|
||||
console.warn(`Failed to fetch EPG from ${epgUrl}: ${response.status}`);
|
||||
return {};
|
||||
}
|
||||
|
||||
// 使用 ReadableStream 逐行处理,避免将整个文件加载到内存
|
||||
const reader = response.body?.getReader();
|
||||
if (!reader) {
|
||||
console.warn('Response body is not readable');
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -175,11 +175,8 @@ async function parseEpg(epgUrl: string, ua: string, tvgIds: string[]): Promise<{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ReadableStream 会自动关闭,不需要手动调用 close
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error parsing EPG:', error);
|
||||
// ignore
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user