- Introduced a new HTML documentation page for the oradio API, including a JavaScript file to handle dynamic content and API requests. - Added a CSS file for styling the documentation page. - Implemented an underground station importer script that fetches data from Radio-Browser and writes it to a JSON file. - Created a stats module to compute and manage vote and play statistics for radio stations. - Added a polyfill for modulepreload to ensure compatibility with older browsers.
41 lines
1.5 KiB
JavaScript
41 lines
1.5 KiB
JavaScript
// 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 };
|
|
}
|