47 lines
1.4 KiB
TypeScript
47 lines
1.4 KiB
TypeScript
import { NextResponse } from 'next/server'
|
|
|
|
const RADIO_GARDEN_API = 'https://radio.garden/api'
|
|
const HEADERS = {
|
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
'Referer': 'https://radio.garden/',
|
|
}
|
|
|
|
export async function GET(
|
|
_request: Request,
|
|
{ params }: { params: Promise<{ channelId: string }> }
|
|
) {
|
|
const { channelId } = await params
|
|
|
|
try {
|
|
// Follow the 302 redirect to get the actual stream URL
|
|
const res = await fetch(
|
|
`${RADIO_GARDEN_API}/ara/content/listen/${channelId}/channel.mp3`,
|
|
{
|
|
headers: HEADERS,
|
|
redirect: 'manual', // Don't auto-follow — we want the Location header
|
|
signal: AbortSignal.timeout(10000),
|
|
}
|
|
)
|
|
|
|
if (res.status === 302) {
|
|
const streamUrl = res.headers.get('location')
|
|
if (streamUrl) {
|
|
return NextResponse.json({ url: streamUrl })
|
|
}
|
|
}
|
|
|
|
// Some stations return 301 or other redirects
|
|
if (res.status >= 300 && res.status < 400) {
|
|
const streamUrl = res.headers.get('location')
|
|
if (streamUrl) {
|
|
return NextResponse.json({ url: streamUrl })
|
|
}
|
|
}
|
|
|
|
throw new Error(`Unexpected status ${res.status}`)
|
|
} catch (error) {
|
|
console.error(`Failed to resolve stream for ${channelId}:`, error)
|
|
return NextResponse.json({ error: 'Failed to resolve stream URL' }, { status: 502 })
|
|
}
|
|
}
|