jefflix-website/app/api/radio/stream/[channelId]/route.ts

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 })
}
}