{"id":22882678,"url":"https://github.com/nimitzdev/m3u8-file-parser","last_synced_at":"2025-05-07T05:01:21.861Z","repository":{"id":30949795,"uuid":"126471298","full_name":"NimitzDEV/m3u8-file-parser","owner":"NimitzDEV","description":"A M3U/M3U8 file parser build agasint RFC8216","archived":false,"fork":false,"pushed_at":"2024-01-19T10:58:46.000Z","size":478,"stargazers_count":17,"open_issues_count":12,"forks_count":6,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-15T04:11:23.214Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NimitzDEV.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-23T10:41:14.000Z","updated_at":"2024-09-10T08:31:40.000Z","dependencies_parsed_at":"2024-06-18T18:18:57.723Z","dependency_job_id":"9888ca22-e908-43e2-bdf9-1b004fd50936","html_url":"https://github.com/NimitzDEV/m3u8-file-parser","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NimitzDEV%2Fm3u8-file-parser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NimitzDEV%2Fm3u8-file-parser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NimitzDEV%2Fm3u8-file-parser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NimitzDEV%2Fm3u8-file-parser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NimitzDEV","download_url":"https://codeload.github.com/NimitzDEV/m3u8-file-parser/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252816937,"owners_count":21808704,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-13T18:19:02.018Z","updated_at":"2025-05-07T05:01:20.768Z","avatar_url":"https://github.com/NimitzDEV.png","language":"JavaScript","readme":"# m3u8-file-parser\n\nA m3u/m3u8 file parser build against [RFC8216](https://tools.ietf.org/html/rfc8216) specs.\n\n## Installation\n\n`npm install m3u8-file-parser --save` or `yarn add m3u8-file-parser`\n\n## Usage\n\nIn Node.js\n\n```javascript\nconst M3U8FileParser = require('m3u8-file-parser');\nconst fs = require('fs');\nconst content = fs.readFileSync('./example.m3u8', { encoding: 'utf-8'});\n\nconst reader = new M3U8FileParser();\nreader.read(content);\nreader.getResult(); // Get the parse result\nreader.reset(); // Optional, If you want to parse a new file, call reset()\n```\n\nIn Node.js read line by line\n\n```javascript\nconst M3U8FileParser = require('m3u8-file-parser');\nconst fs = require('fs');\nconst content = fs.readFileSync('./example.m3u8', { encoding: 'utf-8'});\nconst readline = require('readline');\n\nconst reader = new M3U8FileParser();\nconst stream = fs.createReadStream('./example.m3u8', { encoding: 'utf-8' });\nconst interface = readline.createInterface({ input: stream });\n\ninterface.on('line', line =\u003e reader.read(line)); // Read line by line\ninterface.on('close', () =\u003e reader.getResult()); // Get result after file ends.\n```\n\nIn browser, use the file in dist instead.\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n  \u003cmeta charset=\"utf-8\" /\u003e\n  \u003ctitle\u003eM3U8FileParser Browser Example\u003c/title\u003e\n  \u003cscript src=\"../../dist/m3u8-file-parser.min.js\"\u003e\u003c/script\u003e\n  \u003cscript\u003e\n    var reader = new M3U8FileParser();\n    var m3u8Content = `\n      #EXTM3U\n      #EXTINF:10, Sample Title\n      https://example.com/sample1.mp3\n\n      #EXTINF:10, Sample Title 2\\n\n      https://example.com/sample2.mp3\n    `;\n\n    reader.read(m3u8Content);\n    console.log('result', reader.getResult());\n  \u003c/script\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n  \u003ch2\u003eSee console for result\u003c/h2\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\nAlso, you can parse file line by line if you want, for example, in Node.js, parsing a large file using `readline`\n\n## Supported Tags\n\n### Basic Tags\n\nEXTM3U\n\nEXT-X-VERSION\n\n### Media Segment Tags\n\nEXTINF\n\nEXT-X-BYTERANGE\n\nEXT-X-DISCONTINUITY\n\nEXT-X-KEY\n\nEXT-X-MAP\n\nEXT-X-PROGRAM-DATE-TIME\n\nEXT-X-DATERANGE\n\n### Media Playlist Tags\n\nEXT-X-TARGETDURATION\n\nEXT-X-MEDIA-SEQUENCE\n\nEXT-X-DISCONTINUITY-SEQUENCE\n\nEXT-X-ENDLIST\n\nEXT-X-PLAYLIST-TYPE\n\nEXT-X-I-FRAMES-ONLY\n\n### Master Playlist Tags\n\nEXT-X-MEDIA\n\nEXT-X-STREAM-INF\n\nEXT-X-I-FRAME-STREAM-INF\n\nEXT-X-SESSION-DATA\n\nEXT-X-SESSION-KEY\n\n### Media or Master Playlist Tags\n\nEXT-X-INDEPENDENT-SEGMENTS\n\nEXT-X-START\n\n### Extended Features\n\n- Attributes in EXTINF, For example: `#EXTINF:10 example=\"hah\", title`\n- Camel case conversion for attribute list\n\n## APIs\n\n#### read(str: String)\n\nRead the M3U/M3U8 content and parse it, you can pass a whole M3U/M3U8 content or just one line of the content.\n\n#### getResult(): Object\n\nGet the current parsed result\n\n#### reset()\n\nReset the parsed result\n\n## Custom Parsers\n\nNo support currently.\n\n## File an issue if the parsing strategy is wrong\n\nFeel free to file any issues\n\n## Other\n\nCurrently the parser do not support validation checks for M3U/M3U8 file, like the example given below, are violating Section [4.3.5](https://tools.ietf.org/html/rfc8216#section-4.3.5), but the parser will parse it anyway.\n\n## Parsing Example\n\n```h\n#EXTM3U\n#EXT-X-VERSION:2\n#EXT-X-TARGETDURATION:6\n#EXT-X-PLAYLIST-TYPE:VOD\n#EXT-X-DISCONTINUITY-SEQUENCE:1\n#EXT-X-START:PERCISE=NO,TIME-OFFSET=2.11\n#EXT-X-MEDIA-SEQUENCE:1\n#EXT-X-INDEPENDENT-SEGMENTS\n#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"English\",DEFAULT=YES,AUTOSELECT=YES,FORCED=NO,LANGUAGE=\"en\",CHARACTERISTICS=\"public.accessibility.transcribes-spoken-dialog, public.accessibility.describes-music-and-sound\",URI=\"subtitles/eng/prog_index.m3u8\"\n#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"English (Forced)\",DEFAULT=NO,AUTOSELECT=NO,FORCED=YES,LANGUAGE=\"en\",URI=\"subtitles/eng_forced/prog_index.m3u8\"\n#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"Français\",DEFAULT=NO,AUTOSELECT=YES,FORCED=NO,LANGUAGE=\"fr\",CHARACTERISTICS=\"public.accessibility.transcribes-spoken-dialog, public.accessibility.describes-music-and-sound\",URI=\"subtitles/fra/prog_index.m3u8\"\n#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"Français (Forced)\",DEFAULT=NO,AUTOSELECT=NO,FORCED=YES,LANGUAGE=\"fr\",URI=\"subtitles/fra_forced/prog_index.m3u8\"\n#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"Español\",DEFAULT=NO,AUTOSELECT=YES,FORCED=NO,LANGUAGE=\"es\",CHARACTERISTICS=\"public.accessibility.transcribes-spoken-dialog, public.accessibility.describes-music-and-sound\",URI=\"subtitles/spa/prog_index.m3u8\"\n#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"Español (Forced)\",DEFAULT=NO,AUTOSELECT=NO,FORCED=YES,LANGUAGE=\"es\",URI=\"subtitles/spa_forced/prog_index.m3u8\"\n#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"日本語\",DEFAULT=NO,AUTOSELECT=YES,FORCED=NO,LANGUAGE=\"ja\",CHARACTERISTICS=\"public.accessibility.transcribes-spoken-dialog, public.accessibility.describes-music-and-sound\",URI=\"subtitles/jpn/prog_index.m3u8\"\n#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"日本語 (Forced)\",DEFAULT=NO,AUTOSELECT=NO,FORCED=YES,LANGUAGE=\"ja\",URI=\"subtitles/jpn_forced/prog_index.m3u8\"\n#EXT-X-SESSION-DATA:DATA-ID=\"com.example.lyrics\",URI=\"lyrics.json\"\n#EXT-X-SESSION-DATA:DATA-ID=\"com.example.title\",LANGUAGE=\"en\", \\\n        VALUE=\"This is an example\"\n#EXT-X-SESSION-DATA:DATA-ID=\"com.example.title\",LANGUAGE=\"es\", \\\n        VALUE=\"Este es un ejemplo\"\n#EXT-X-SESSION-KEY:METHOD=AES-128,URI=\"https://priv.example.com/key.php?r=52\",IV=0x9c7db8778570d05c3177c349fd9236aa\n#EXT-X-STREAM-INF:BANDWIDTH=100,AVERAGE-BANDWIDTH=128,CODECS=\"MPEG-4;MPEG-2\",RESOLUTION=1080,FRAME-RATE=29.97,HDCP-LEVEL=\"TYPE-0\",AUDIO=\"AUDIO\",VIDEO=\"VIDEO\"\n#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=120,URI=\"THATFILE.M3U8\"\n#EXT-X-BYTERANGE:100@10\n#EXT-X-DISCONTINUITY\n#EXT-X-KEY:METHOD=AES-128,URI=\"https://priv.example.com/key.php?r=52\",IV=0x9c7db8778570d05c3177c349fd9236aa\n#EXT-X-MAP:URI=\"https://example.map.uri\",BYTERANGE=\"300@0\"\n#EXT-X-PROGRAM-DATE-TIME:2010-02-19T14:54:23.031+08:00\n#EXT-X-DATERANGE:ID=\"ITS ID\",CLASS=\"ITS CLASS\",START-DATE=\"2010-02-19T14:54:23.031+08:00\",END-DATE=\"2010-02-19T14:54:23.031+08:00\",DURATION=1.33,PLANNED-DURATION=2.33\n#EXTINF:23.222 tvg-logo=\"haha,  ddd\" tvg-aa=\"sb@\" tag=sa, Sample artist, : - Sample title\nC:\\Documents and Settings\\I\\My Music\\Sample.mp3\n#EXT-X-ENDLIST\n#COMMENT YAS\n```\n\nParsed result:\n\n```json\n{\n  \"isExtendedM3U\": true,\n  \"segments\": [\n    {\n      \"isMasterPlaylist\": true,\n      \"sessionKey\": {\n        \"method\": \"AES-128\",\n        \"uri\": \"https://priv.example.com/key.php?r=52\",\n        \"iv\": \"0x9c7db8778570d05c3177c349fd9236aa\"\n      },\n      \"streamInf\": {\n        \"bandwidth\": 100,\n        \"averageBandwidth\": 128,\n        \"codecs\": [\n          \"MPEG-4\",\n          \"MPEG-2\"\n        ],\n        \"resolution\": 1080,\n        \"frameRate\": 29.97,\n        \"hdcpLevel\": \"TYPE-0\",\n        \"audio\": \"AUDIO\",\n        \"video\": \"VIDEO\"\n      },\n      \"iFrameStreamInf\": {\n        \"bandwidth\": 120,\n        \"uri\": \"THATFILE.M3U8\"\n      },\n      \"byteRange\": {\n        \"length\": 100,\n        \"offset\": 10\n      },\n      \"discontinuity\": true,\n      \"key\": {\n        \"method\": \"AES-128\",\n        \"uri\": \"https://priv.example.com/key.php?r=52\",\n        \"iv\": \"0x9c7db8778570d05c3177c349fd9236aa\"\n      },\n      \"map\": {\n        \"uri\": \"https://example.map.uri\",\n        \"byterange\": {\n          \"length\": 300,\n          \"offset\": 0\n        }\n      },\n      \"programDateTime\": \"2010-02-19T06:54:23.031Z\",\n      \"dateRange\": {\n        \"id\": \"ITS ID\",\n        \"class\": \"ITS CLASS\",\n        \"startDate\": \"2010-02-19T06:54:23.031Z\",\n        \"endDate\": \"2010-02-19T06:54:23.031Z\",\n        \"duration\": 1.33,\n        \"plannedDuration\": 2.33\n      },\n      \"inf\": {\n        \"duration\": 23.222,\n        \"title\": \"Sample artist, : - Sample title\",\n        \"tvg-logo\": \"haha,  ddd\",\n        \"tvg-aa\": \"sb@\",\n        \"tag\": \"sa\"\n      },\n      \"url\": \"C:\\\\Documents and Settings\\\\I\\\\My Music\\\\Sample.mp3\"\n    }\n  ],\n  \"version\": 2,\n  \"targetDuration\": 6,\n  \"playlistType\": \"VOD\",\n  \"discontinuitySequence\": 1,\n  \"start\": {\n    \"percise\": true,\n    \"timeOffset\": 2.11\n  },\n  \"mediaSequence\": 1,\n  \"independentSegments\": true,\n  \"media\": {\n    \"SUBTITLES\": {\n      \"subs\": {\n        \"English\": {\n          \"groupId\": \"subs\",\n          \"type\": \"SUBTITLES\",\n          \"name\": \"English\",\n          \"default\": true,\n          \"autoselect\": true,\n          \"forced\": true,\n          \"language\": \"en\",\n          \"characteristics\": \"public.accessibility.transcribes-spoken-dialog, public.accessibility.describes-music-and-sound\",\n          \"uri\": \"subtitles/eng/prog_index.m3u8\"\n        },\n        \"English (Forced)\": {\n          \"groupId\": \"subs\",\n          \"type\": \"SUBTITLES\",\n          \"name\": \"English (Forced)\",\n          \"default\": true,\n          \"autoselect\": true,\n          \"forced\": true,\n          \"language\": \"en\",\n          \"uri\": \"subtitles/eng_forced/prog_index.m3u8\"\n        },\n        \"Français\": {\n          \"groupId\": \"subs\",\n          \"type\": \"SUBTITLES\",\n          \"name\": \"Français\",\n          \"default\": true,\n          \"autoselect\": true,\n          \"forced\": true,\n          \"language\": \"fr\",\n          \"characteristics\": \"public.accessibility.transcribes-spoken-dialog, public.accessibility.describes-music-and-sound\",\n          \"uri\": \"subtitles/fra/prog_index.m3u8\"\n        },\n        \"Français (Forced)\": {\n          \"groupId\": \"subs\",\n          \"type\": \"SUBTITLES\",\n          \"name\": \"Français (Forced)\",\n          \"default\": true,\n          \"autoselect\": true,\n          \"forced\": true,\n          \"language\": \"fr\",\n          \"uri\": \"subtitles/fra_forced/prog_index.m3u8\"\n        },\n        \"Español\": {\n          \"groupId\": \"subs\",\n          \"type\": \"SUBTITLES\",\n          \"name\": \"Español\",\n          \"default\": true,\n          \"autoselect\": true,\n          \"forced\": true,\n          \"language\": \"es\",\n          \"characteristics\": \"public.accessibility.transcribes-spoken-dialog, public.accessibility.describes-music-and-sound\",\n          \"uri\": \"subtitles/spa/prog_index.m3u8\"\n        },\n        \"Español (Forced)\": {\n          \"groupId\": \"subs\",\n          \"type\": \"SUBTITLES\",\n          \"name\": \"Español (Forced)\",\n          \"default\": true,\n          \"autoselect\": true,\n          \"forced\": true,\n          \"language\": \"es\",\n          \"uri\": \"subtitles/spa_forced/prog_index.m3u8\"\n        },\n        \"日本語\": {\n          \"groupId\": \"subs\",\n          \"type\": \"SUBTITLES\",\n          \"name\": \"日本語\",\n          \"default\": true,\n          \"autoselect\": true,\n          \"forced\": true,\n          \"language\": \"ja\",\n          \"characteristics\": \"public.accessibility.transcribes-spoken-dialog, public.accessibility.describes-music-and-sound\",\n          \"uri\": \"subtitles/jpn/prog_index.m3u8\"\n        },\n        \"日本語 (Forced)\": {\n          \"groupId\": \"subs\",\n          \"type\": \"SUBTITLES\",\n          \"name\": \"日本語 (Forced)\",\n          \"default\": true,\n          \"autoselect\": true,\n          \"forced\": true,\n          \"language\": \"ja\",\n          \"uri\": \"subtitles/jpn_forced/prog_index.m3u8\"\n        }\n      }\n    }\n  },\n  \"sessionData\": {\n    \"com.example.lyrics\": {\n      \"undefined\": {\n        \"dataId\": \"com.example.lyrics\",\n        \"uri\": \"lyrics.json\"\n      }\n    },\n    \"com.example.title\": {\n      \"en\": {\n        \"dataId\": \"com.example.title\",\n        \"language\": \"en\",\n        \"value\": \"This is an example\"\n      },\n      \"es\": {\n        \"dataId\": \"com.example.title\",\n        \"language\": \"es\",\n        \"value\": \"Este es un ejemplo\"\n      }\n    }\n  },\n  \"endList\": 2\n}\n```\n\n## License\n\nMIT\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnimitzdev%2Fm3u8-file-parser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnimitzdev%2Fm3u8-file-parser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnimitzdev%2Fm3u8-file-parser/lists"}