58 lines
1.9 KiB
JavaScript
58 lines
1.9 KiB
JavaScript
// ── M3U PARSER ────────────────────────────────────────────────────────────────
|
|
function slugify(str) {
|
|
return str.toLowerCase()
|
|
.replace(/^\d+\s*/, '') // virer le numéro de chaîne en début
|
|
.replace(/[^a-z0-9]/g, ''); // garder que alphanum
|
|
}
|
|
|
|
async function loadM3U(url) {
|
|
if (!url) return;
|
|
try {
|
|
let text;
|
|
try {
|
|
const r = await fetch(url); text = await r.text();
|
|
} catch(e) {
|
|
const r = await fetch(CORS_PROXY + encodeURIComponent(url)); text = await r.text();
|
|
}
|
|
parseM3U(text);
|
|
} catch(e) { console.warn('M3U load failed:', e); }
|
|
}
|
|
|
|
function parseM3U(text) {
|
|
m3uStreams = {};
|
|
const lines = text.split('\n');
|
|
let currentName = null;
|
|
for (let i = 0; i < lines.length; i++) {
|
|
const line = lines[i].trim();
|
|
if (line.startsWith('#EXTINF')) {
|
|
// Extraire le nom : dernière partie après la virgule
|
|
const comma = line.lastIndexOf(',');
|
|
currentName = comma !== -1 ? line.slice(comma + 1).trim() : null;
|
|
} else if (line && !line.startsWith('#') && currentName) {
|
|
m3uStreams[slugify(currentName)] = line;
|
|
currentName = null;
|
|
}
|
|
}
|
|
console.log(`M3U: ${Object.keys(m3uStreams).length} streams chargés`);
|
|
}
|
|
|
|
function getStreamUrl(channelName) {
|
|
const slug = slugify(channelName);
|
|
let url = null;
|
|
if (m3uStreams[slug]) {
|
|
url = m3uStreams[slug];
|
|
} else {
|
|
// Fallback : chercher une clé qui contient le slug ou l'inverse
|
|
for (const [key, u] of Object.entries(m3uStreams)) {
|
|
if (key.includes(slug) || slug.includes(key)) { url = u; break; }
|
|
}
|
|
}
|
|
if (!url) return null;
|
|
// Passer par proxy.php pour éviter le mixed content HTTP/HTTPS
|
|
if (url.startsWith('http://')) {
|
|
return 'proxy.php?url=' + encodeURIComponent(url);
|
|
}
|
|
return url;
|
|
}
|
|
|