|
1 | | -import { NextRequest, NextResponse } from 'next/server'; |
2 | | - |
3 | | -import { getStorage } from '@/lib/db'; |
4 | | -import { fetchAndParseM3U } from '@/lib/m3u-parser'; |
5 | | - |
6 | | -// 针对不同部署模式的配置 |
7 | | -export const runtime = process.env.CLOUDFLARE_PAGES === '1' ? 'edge' : 'nodejs'; |
8 | | - |
9 | | -export async function GET(request: NextRequest) { |
10 | | - try { |
11 | | - const url = new URL(request.url); |
12 | | - const sourceKey = url.searchParams.get('source'); |
13 | | - |
14 | | - if (!sourceKey) { |
15 | | - return NextResponse.json({ error: '缺少直播源参数' }, { status: 400 }); |
16 | | - } |
17 | | - |
18 | | - const storage = getStorage(); |
19 | | - |
20 | | - // 获取直播源配置 |
21 | | - const liveConfigs = await storage.getLiveConfigs(); |
22 | | - const liveSource = liveConfigs.find(config => config.key === sourceKey); |
23 | | - |
24 | | - if (!liveSource) { |
25 | | - return NextResponse.json({ error: '直播源不存在' }, { status: 404 }); |
26 | | - } |
27 | | - |
28 | | - if (liveSource.disabled) { |
29 | | - return NextResponse.json({ error: '直播源已禁用' }, { status: 400 }); |
30 | | - } |
31 | | - |
32 | | - // 检查缓存 |
33 | | - const cached = await storage.getCachedLiveChannels(sourceKey); |
34 | | - const now = Date.now(); |
35 | | - |
36 | | - if (cached && cached.expireTime > now) { |
37 | | - return NextResponse.json({ |
38 | | - success: true, |
39 | | - source: { |
40 | | - key: liveSource.key, |
41 | | - name: liveSource.name, |
42 | | - }, |
43 | | - channels: cached.channels, |
44 | | - cached: true, |
45 | | - updateTime: cached.updateTime, |
46 | | - }); |
47 | | - } |
48 | | - |
49 | | - // 获取并解析频道 |
50 | | - try { |
51 | | - const channels = await fetchAndParseM3U(liveSource.url, liveSource.ua); |
52 | | - |
53 | | - // 更新缓存(缓存30分钟) |
54 | | - const cacheData = { |
55 | | - channels, |
56 | | - updateTime: now, |
57 | | - expireTime: now + 30 * 60 * 1000, // 30分钟后过期 |
58 | | - }; |
59 | | - |
60 | | - await storage.setCachedLiveChannels(sourceKey, cacheData); |
61 | | - |
62 | | - // 更新频道数量 |
63 | | - const updatedConfigs = liveConfigs.map(config => |
64 | | - config.key === sourceKey |
65 | | - ? { ...config, channelNumber: channels.length } |
66 | | - : config |
67 | | - ); |
68 | | - await storage.setLiveConfigs(updatedConfigs); |
69 | | - |
70 | | - return NextResponse.json({ |
71 | | - success: true, |
72 | | - source: { |
73 | | - key: liveSource.key, |
74 | | - name: liveSource.name, |
75 | | - }, |
76 | | - channels, |
77 | | - cached: false, |
78 | | - updateTime: now, |
79 | | - }); |
80 | | - } catch (parseError) { |
81 | | - return NextResponse.json( |
82 | | - { |
83 | | - error: `解析失败: ${parseError instanceof Error ? parseError.message : '未知错误'}` |
84 | | - }, |
85 | | - { status: 500 } |
86 | | - ); |
87 | | - } |
88 | | - } catch (error) { |
89 | | - // eslint-disable-next-line no-console |
90 | | - console.error('Live channels API error:', error); |
91 | | - return NextResponse.json( |
92 | | - { error: '获取频道列表失败' }, |
93 | | - { status: 500 } |
94 | | - ); |
95 | | - } |
96 | | -} |
0 commit comments