@iptv/playlist
Version:
An extremely fast M3U playlist parser and generator for Node and the browser.
121 lines (120 loc) • 3.82 kB
JavaScript
const p = {
"tvg-id": "tvgId",
"tvg-name": "tvgName",
"tvg-language": "tvgLanguage",
"tvg-logo": "tvgLogo",
"tvg-url": "tvgUrl",
"tvg-rec,": "tvgRec",
"group-title": "groupTitle",
timeshift: "timeshift",
catchup: "catchup",
"catchup-days": "catchupDays",
"catchup-source": "catchupSource",
"x-tvg-url": "xTvgUrl",
"url-tvg": "urlTvg"
}, C = 32, x = 35, $ = 61, O = 58, I = 44, T = 45, U = 49, b = 50, l = 51, L = 52, N = 53, M = 54, w = 55, E = 56, S = 57, y = 48, f = 10, D = 9, R = 13, u = 69, A = 88, v = 84, X = 73, j = 78, k = 70, q = 77, H = 72, z = 104, P = 85, Q = [
y,
U,
b,
l,
L,
N,
M,
w,
E,
S,
T
];
function V(e) {
const r = [], c = {};
let t = 0, o = {}, s = "", d = null;
for (; t < e.length; ) {
const a = e.charCodeAt(t);
if (a === C || a === D || a === R || a === f) {
t++, a === f && (s = "");
continue;
}
let i = e.indexOf(`
`, t);
if (i === -1 && (i = e.length), Q.includes(a)) {
let h = e.indexOf(" ", t), g = e.indexOf(",", t), n = h;
h > -1 && g > -1 && h > g && (n = g), n === -1 && (n = i), o.duration = parseInt(
e.slice(t, n),
10
), t = n;
continue;
}
if (a === x)
if (d = null, /* E */
e.charCodeAt(t + 1) === u && /* X */
e.charCodeAt(t + 2) === A && /* T */
e.charCodeAt(t + 3) === v && /* M */
e.charCodeAt(t + 4) === q && /* 3 */
e.charCodeAt(t + 5) === l && /* U */
e.charCodeAt(t + 6) === P)
t += 6, d = "header";
else if (
/* E */
e.charCodeAt(t + 1) === u && /* X */
e.charCodeAt(t + 2) === A && /* T */
e.charCodeAt(t + 3) === v && /* I */
e.charCodeAt(t + 4) === X && /* N */
e.charCodeAt(t + 5) === j && /* F */
e.charCodeAt(t + 6) === k && /* : */
e.charCodeAt(t + 7) === O
)
t += 7, d = "channel", o = {};
else {
t = i;
continue;
}
if (a === z || a === H) {
d = "http", o.url = e.slice(t, i).trim(), t = i, r.push(o), o = {};
continue;
}
if (a === I) {
d = "channel", o.name = e.slice(t + 1, i).trim(), t = i, d = null;
continue;
}
if (a > 64 && a < 91 || a > 96 && a < 123 || a === 45) {
const h = e.indexOf("=", t);
s = e.slice(
t,
h
), t = h;
continue;
}
if (a === $) {
t = t + 2;
const h = e.indexOf('"', t), g = e.slice(
t,
h
);
t = h;
const n = p[s];
n ? d === "header" ? c[n] = g : o[n] = g : (o.extras = o.extras || {}, o.extras[s] = g), s = "";
}
t++;
}
return { channels: r, headers: c };
}
function B(e) {
let r = "#EXTM3U";
if (e.headers && Object.entries(e.headers))
for (const [c, t] of Object.entries(e.headers))
r += ` ${c}="${t}"`;
for (const c of e.channels)
if (c.url) {
if (r += `
#EXTINF:`, r += c != null && c.duration ? c.duration : "-1", c.tvgId && (r += ` tvg-id="${c.tvgId}"`), c.tvgName && (r += ` tvg-name="${c.tvgName}"`), c.tvgLanguage && (r += ` tvg-language="${c.tvgLanguage}"`), c.tvgLogo && (r += ` tvg-logo="${c.tvgLogo}"`), c.tvgRec && (r += ` tvg-rec="${c.tvgRec}"`), c.tvgChno && (r += ` tvg-chno="${c.tvgChno}"`), c.groupTitle && (r += ` group-title="${c.groupTitle}"`), c.tvgUrl && (r += ` tvg-url="${c.tvgUrl}"`), c.timeshift && (r += ` timeshift="${c.timeshift}"`), c.catchup && (r += ` catchup="${c.catchup}"`), c.catchupDays && (r += ` catchup-days="${c.catchupDays}"`), c.catchupSource && (r += ` catchup-source="${c.catchupSource}"`), c.extras)
for (const [t, o] of Object.entries(c.extras))
r += ` ${t}="${o}"`;
r += ",", c.name && (r += c.name), r += `
${c.url}`;
}
return r;
}
export {
V as parseM3U,
B as writeM3U
};