// Resolve playlist files (.pls / .m3u) to a direct stream URL. // HLS (.m3u8) is left as-is so hls.js can fetch it. export function detectFormatFromUrl(url) { const u = url.toLowerCase().split('?')[0]; if (u.endsWith('.m3u8')) return 'hls'; if (u.endsWith('.m3u')) return 'm3u'; if (u.endsWith('.pls')) return 'pls'; if (u.endsWith('.aac')) return 'aac'; if (u.endsWith('.mp3')) return 'mp3'; if (u.endsWith('.ogg') || u.endsWith('.opus')) return 'ogg'; return 'unknown'; } function parsePls(text) { const m = text.match(/^File\d+\s*=\s*(.+)$/im); return m ? m[1].trim() : null; } function parseM3u(text) { const lines = text.split(/\r?\n/).map((l) => l.trim()).filter(Boolean); return lines.find((l) => !l.startsWith('#')) || null; } export async function resolveStream({ url, format }) { const fmt = format && format !== 'unknown' ? format : detectFormatFromUrl(url); if (fmt === 'pls' || fmt === 'm3u') { try { const res = await fetch(url, { redirect: 'follow' }); if (!res.ok) throw new Error(`HTTP ${res.status}`); const text = await res.text(); const direct = fmt === 'pls' ? parsePls(text) : parseM3u(text); if (!direct) throw new Error('No direct URL found in playlist'); return { url: direct, format: detectFormatFromUrl(direct) }; } catch (err) { return { url, format: fmt, error: String(err.message || err) }; } } return { url, format: fmt }; }