@iptv/playlist
Version:
An extremely fast M3U playlist parser and generator for Node and the browser.
5 lines (4 loc) • 3.28 kB
JavaScript
(function(s,u){typeof exports=="object"&&typeof module<"u"?u(exports):typeof define=="function"&&define.amd?define(["exports"],u):(s=typeof globalThis<"u"?globalThis:s||self,u(s.playlist={}))})(this,(function(s){"use strict";const u={"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"},O=32,U=35,T=61,b=58,I=44,M=45,w=49,y=50,v=51,N=52,L=53,S=54,E=55,j=56,P=57,D=48,l=10,R=9,X=13,p=69,C=88,A=84,k=73,q=78,H=70,z=77,Q=72,V=80,B=85,G=104,J=112,x=116,K=[D,w,y,v,N,L,S,E,j,P,M];function W(c){const r=[],e={};let t=0,o={},g="",f=null,$=null;for(;t<c.length;){const a=c.charCodeAt(t);if(t===$)throw new Error("Infinite loop detected while parsing M3U file");if($=t,a===O||a===R||a===X||a===l){t++,a===l&&(g="");continue}let i=c.indexOf(`
`,t);if(i===-1&&(i=c.length),K.includes(a)){let n=c.indexOf(" ",t),d=c.indexOf(",",t),h=-1;d>-1&&(h=d),n>-1&&d>-1&&n<d&&(h=n),d===-1&&n>-1&&(h=n),h===-1&&(h=i),o.duration=parseInt(c.slice(t,h),10),t=h;continue}if(a===U)if(f=null,c.charCodeAt(t+1)===p&&c.charCodeAt(t+2)===C&&c.charCodeAt(t+3)===A&&c.charCodeAt(t+4)===z&&c.charCodeAt(t+5)===v&&c.charCodeAt(t+6)===B)t+=6,f="header";else if(c.charCodeAt(t+1)===p&&c.charCodeAt(t+2)===C&&c.charCodeAt(t+3)===A&&c.charCodeAt(t+4)===k&&c.charCodeAt(t+5)===q&&c.charCodeAt(t+6)===H&&c.charCodeAt(t+7)===b)t+=7,f="channel",o={};else{t=i;continue}if(a===G||a===Q){if(!((c.charCodeAt(t+1)===x||c.charCodeAt(t+1)===A)&&(c.charCodeAt(t+2)===x||c.charCodeAt(t+2)===A)&&(c.charCodeAt(t+3)===J||c.charCodeAt(t+3)===V))||!(o.name||o.tvgName||o.tvgId)){t=i;continue}f="http";const n=c.slice(t,i).trim();o.url||(o.url=n),o.urls||(o.urls=[]),o.urls=[...o.urls,n],t=i,r.indexOf(o)===-1&&r.push(o);continue}if(a===I){f="channel",o.name=c.slice(t+1,i).trim(),t=i,f=null;continue}if(a>64&&a<91||a>96&&a<123||a===45){const n=c.indexOf("=",t);if(n===-1||n>i){t=i,g="";continue}g=c.slice(t,n),t=n;continue}if(a===T){t=t+2;const n=c.indexOf('"',t),d=c.slice(t,n);t=n;const h=u[g];h?f==="header"?e[h]=d:o[h]=d:(o.extras=o.extras||{},o.extras[g]=d),g=""}t++}return{channels:r,headers:e}}function Y(c){let r="#EXTM3U";if(c.headers&&Object.entries(c.headers))for(const[e,t]of Object.entries(c.headers))r+=` ${e}="${t}"`;for(const e of c.channels)if(e.url){if(r+=`
#EXTINF:`,r+=e!=null&&e.duration?e.duration:"-1",e.tvgId&&(r+=` tvg-id="${e.tvgId}"`),e.tvgName&&(r+=` tvg-name="${e.tvgName}"`),e.tvgLanguage&&(r+=` tvg-language="${e.tvgLanguage}"`),e.tvgLogo&&(r+=` tvg-logo="${e.tvgLogo}"`),e.tvgRec&&(r+=` tvg-rec="${e.tvgRec}"`),e.tvgChno&&(r+=` tvg-chno="${e.tvgChno}"`),e.groupTitle&&(r+=` group-title="${e.groupTitle}"`),e.tvgUrl&&(r+=` tvg-url="${e.tvgUrl}"`),e.timeshift&&(r+=` timeshift="${e.timeshift}"`),e.catchup&&(r+=` catchup="${e.catchup}"`),e.catchupDays&&(r+=` catchup-days="${e.catchupDays}"`),e.catchupSource&&(r+=` catchup-source="${e.catchupSource}"`),e.extras)for(const[t,o]of Object.entries(e.extras))r+=` ${t}="${o}"`;r+=",",e.name&&(r+=e.name),r+=`
${e.url}`}return r}s.parseM3U=W,s.writeM3U=Y,Object.defineProperty(s,Symbol.toStringTag,{value:"Module"})}));