@transmitlive/m3u8-parser 4.7.2-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +30 -0
- package/LICENSE +13 -0
- package/README.md +388 -0
- package/dist/m3u8-parser.cjs.js +1563 -0
- package/dist/m3u8-parser.es.js +1549 -0
- package/dist/m3u8-parser.js +1748 -0
- package/dist/m3u8-parser.min.js +2 -0
- package/index.html +15 -0
- package/package.json +100 -0
- package/scripts/karma.conf.js +12 -0
- package/scripts/rollup.config.js +47 -0
- package/src/index.js +19 -0
- package/src/line-stream.js +35 -0
- package/src/parse-stream.js +619 -0
- package/src/parser.js +748 -0
- package/test/fixtures/integration/absoluteUris.js +31 -0
- package/test/fixtures/integration/absoluteUris.m3u8 +12 -0
- package/test/fixtures/integration/allowCache.js +165 -0
- package/test/fixtures/integration/allowCache.m3u8 +58 -0
- package/test/fixtures/integration/allowCacheInvalid.js +21 -0
- package/test/fixtures/integration/allowCacheInvalid.m3u8 +10 -0
- package/test/fixtures/integration/alternateAudio.js +56 -0
- package/test/fixtures/integration/alternateAudio.m3u8 +9 -0
- package/test/fixtures/integration/alternateVideo.js +48 -0
- package/test/fixtures/integration/alternateVideo.m3u8 +8 -0
- package/test/fixtures/integration/brightcove.js +57 -0
- package/test/fixtures/integration/brightcove.m3u8 +9 -0
- package/test/fixtures/integration/byteRange.js +161 -0
- package/test/fixtures/integration/byteRange.m3u8 +56 -0
- package/test/fixtures/integration/dateTime.js +27 -0
- package/test/fixtures/integration/dateTime.m3u8 +12 -0
- package/test/fixtures/integration/diff-init-key.js +164 -0
- package/test/fixtures/integration/diff-init-key.m3u8 +57 -0
- package/test/fixtures/integration/disallowCache.js +21 -0
- package/test/fixtures/integration/disallowCache.m3u8 +10 -0
- package/test/fixtures/integration/disc-sequence.js +32 -0
- package/test/fixtures/integration/disc-sequence.m3u8 +15 -0
- package/test/fixtures/integration/discontinuity.js +59 -0
- package/test/fixtures/integration/discontinuity.m3u8 +26 -0
- package/test/fixtures/integration/domainUris.js +31 -0
- package/test/fixtures/integration/domainUris.m3u8 +12 -0
- package/test/fixtures/integration/empty.js +5 -0
- package/test/fixtures/integration/empty.m3u8 +0 -0
- package/test/fixtures/integration/emptyAllowCache.js +21 -0
- package/test/fixtures/integration/emptyAllowCache.m3u8 +10 -0
- package/test/fixtures/integration/emptyMediaSequence.js +31 -0
- package/test/fixtures/integration/emptyMediaSequence.m3u8 +14 -0
- package/test/fixtures/integration/emptyPlaylistType.js +40 -0
- package/test/fixtures/integration/emptyPlaylistType.m3u8 +16 -0
- package/test/fixtures/integration/emptyTargetDuration.js +57 -0
- package/test/fixtures/integration/emptyTargetDuration.m3u8 +10 -0
- package/test/fixtures/integration/encrypted.js +61 -0
- package/test/fixtures/integration/encrypted.m3u8 +28 -0
- package/test/fixtures/integration/event.js +41 -0
- package/test/fixtures/integration/event.m3u8 +16 -0
- package/test/fixtures/integration/extXPlaylistTypeInvalidPlaylist.js +15 -0
- package/test/fixtures/integration/extXPlaylistTypeInvalidPlaylist.m3u8 +8 -0
- package/test/fixtures/integration/extinf.js +165 -0
- package/test/fixtures/integration/extinf.m3u8 +57 -0
- package/test/fixtures/integration/fmp4.js +44 -0
- package/test/fixtures/integration/fmp4.m3u8 +14 -0
- package/test/fixtures/integration/headerOnly.js +5 -0
- package/test/fixtures/integration/headerOnly.m3u8 +1 -0
- package/test/fixtures/integration/invalidAllowCache.js +21 -0
- package/test/fixtures/integration/invalidAllowCache.m3u8 +10 -0
- package/test/fixtures/integration/invalidMediaSequence.js +31 -0
- package/test/fixtures/integration/invalidMediaSequence.m3u8 +14 -0
- package/test/fixtures/integration/invalidPlaylistType.js +40 -0
- package/test/fixtures/integration/invalidPlaylistType.m3u8 +16 -0
- package/test/fixtures/integration/invalidTargetDuration.js +164 -0
- package/test/fixtures/integration/invalidTargetDuration.m3u8 +57 -0
- package/test/fixtures/integration/liveMissingSegmentDuration.js +25 -0
- package/test/fixtures/integration/liveMissingSegmentDuration.m3u8 +9 -0
- package/test/fixtures/integration/liveStart30sBefore.js +54 -0
- package/test/fixtures/integration/liveStart30sBefore.m3u8 +22 -0
- package/test/fixtures/integration/llhls-byte-range.js +253 -0
- package/test/fixtures/integration/llhls-byte-range.m3u8 +66 -0
- package/test/fixtures/integration/llhls-delta-byte-range.js +149 -0
- package/test/fixtures/integration/llhls-delta-byte-range.m3u8 +30 -0
- package/test/fixtures/integration/llhls.js +214 -0
- package/test/fixtures/integration/llhls.m3u8 +56 -0
- package/test/fixtures/integration/llhlsDelta.js +186 -0
- package/test/fixtures/integration/llhlsDelta.m3u8 +50 -0
- package/test/fixtures/integration/manifestExtTTargetdurationNegative.js +14 -0
- package/test/fixtures/integration/manifestExtTTargetdurationNegative.m3u8 +5 -0
- package/test/fixtures/integration/manifestExtXEndlistEarly.js +35 -0
- package/test/fixtures/integration/manifestExtXEndlistEarly.m3u8 +14 -0
- package/test/fixtures/integration/manifestNoExtM3u.js +15 -0
- package/test/fixtures/integration/manifestNoExtM3u.m3u8 +4 -0
- package/test/fixtures/integration/master-fmp4.js +465 -0
- package/test/fixtures/integration/master-fmp4.m3u8 +76 -0
- package/test/fixtures/integration/master.js +57 -0
- package/test/fixtures/integration/master.m3u8 +10 -0
- package/test/fixtures/integration/media.js +31 -0
- package/test/fixtures/integration/media.m3u8 +12 -0
- package/test/fixtures/integration/mediaSequence.js +31 -0
- package/test/fixtures/integration/mediaSequence.m3u8 +14 -0
- package/test/fixtures/integration/missingEndlist.js +19 -0
- package/test/fixtures/integration/missingEndlist.m3u8 +6 -0
- package/test/fixtures/integration/missingExtinf.js +27 -0
- package/test/fixtures/integration/missingExtinf.m3u8 +11 -0
- package/test/fixtures/integration/missingMediaSequence.js +31 -0
- package/test/fixtures/integration/missingMediaSequence.m3u8 +13 -0
- package/test/fixtures/integration/missingSegmentDuration.js +31 -0
- package/test/fixtures/integration/missingSegmentDuration.m3u8 +11 -0
- package/test/fixtures/integration/multipleAudioGroups.js +89 -0
- package/test/fixtures/integration/multipleAudioGroups.m3u8 +17 -0
- package/test/fixtures/integration/multipleAudioGroupsCombinedMain.js +88 -0
- package/test/fixtures/integration/multipleAudioGroupsCombinedMain.m3u8 +17 -0
- package/test/fixtures/integration/multipleTargetDurations.js +28 -0
- package/test/fixtures/integration/multipleTargetDurations.m3u8 +8 -0
- package/test/fixtures/integration/multipleVideo.js +74 -0
- package/test/fixtures/integration/multipleVideo.m3u8 +16 -0
- package/test/fixtures/integration/negativeMediaSequence.js +31 -0
- package/test/fixtures/integration/negativeMediaSequence.m3u8 +14 -0
- package/test/fixtures/integration/playlist.js +165 -0
- package/test/fixtures/integration/playlist.m3u8 +57 -0
- package/test/fixtures/integration/playlistMediaSequenceHigher.js +16 -0
- package/test/fixtures/integration/playlistMediaSequenceHigher.m3u8 +8 -0
- package/test/fixtures/integration/start.js +36 -0
- package/test/fixtures/integration/start.m3u8 +13 -0
- package/test/fixtures/integration/streamInfInvalid.js +24 -0
- package/test/fixtures/integration/streamInfInvalid.m3u8 +6 -0
- package/test/fixtures/integration/twoMediaSequences.js +31 -0
- package/test/fixtures/integration/twoMediaSequences.m3u8 +15 -0
- package/test/fixtures/integration/versionInvalid.js +16 -0
- package/test/fixtures/integration/versionInvalid.m3u8 +8 -0
- package/test/fixtures/integration/whiteSpace.js +31 -0
- package/test/fixtures/integration/whiteSpace.m3u8 +13 -0
- package/test/fixtures/integration/zeroDuration.js +16 -0
- package/test/fixtures/integration/zeroDuration.m3u8 +7 -0
- package/test/line-stream.test.js +80 -0
- package/test/parse-stream.test.js +903 -0
- package/test/parser.test.js +884 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! @name @transmitlive/m3u8-parser @version 4.7.2-beta.6 @license Apache-2.0 */
|
|
2
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("global/window")):"function"==typeof define&&define.amd?define(["exports","global/window"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).m3u8Parser={},t.window)}(this,(function(t,e){"use strict";function i(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var r=i(e);var a=function(t,e){t.prototype=Object.create(e.prototype),t.prototype.constructor=t,t.__proto__=e},s=function(){function t(){this.listeners={}}var e=t.prototype;return e.on=function(t,e){this.listeners[t]||(this.listeners[t]=[]),this.listeners[t].push(e)},e.off=function(t,e){if(!this.listeners[t])return!1;var i=this.listeners[t].indexOf(e);return this.listeners[t]=this.listeners[t].slice(0),this.listeners[t].splice(i,1),i>-1},e.trigger=function(t){var e=this.listeners[t];if(e)if(2===arguments.length)for(var i=e.length,r=0;r<i;++r)e[r].call(this,arguments[1]);else for(var a=Array.prototype.slice.call(arguments,1),s=e.length,n=0;n<s;++n)e[n].apply(this,a)},e.dispose=function(){this.listeners={}},e.pipe=function(t){this.on("data",(function(e){t.push(e)}))},t}(),n=function(t){function e(){var e;return(e=t.call(this)||this).buffer="",e}return a(e,t),e.prototype.push=function(t){var e;for(this.buffer+=t,e=this.buffer.indexOf("\n");e>-1;e=this.buffer.indexOf("\n"))this.trigger("data",this.buffer.substring(0,e)),this.buffer=this.buffer.substring(e+1)},e}(s);var u=function(t,e,i){return t(i={path:e,exports:{},require:function(t,e){return function(){throw new Error("Dynamic requires are not currently supported by @rollup/plugin-commonjs")}(null==e&&i.path)}},i.exports),i.exports}((function(t){function e(){return t.exports=e=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var i=arguments[e];for(var r in i)Object.prototype.hasOwnProperty.call(i,r)&&(t[r]=i[r])}return t},e.apply(this,arguments)}t.exports=e})),o=String.fromCharCode(9),g=function(t){var e=/([0-9.]*)?@?([0-9.]*)?/.exec(t||""),i={};return e[1]&&(i.length=parseInt(e[1],10)),e[2]&&(i.offset=parseInt(e[2],10)),i},f=function(t){for(var e,i=t.split(new RegExp('(?:^|,)((?:[^=]*)=(?:"[^"]*"|[^,]*))')),r={},a=i.length;a--;)""!==i[a]&&((e=/([^=]*)=(.*)/.exec(i[a]).slice(1))[0]=e[0].replace(/^\s+|\s+$/g,""),e[1]=e[1].replace(/^\s+|\s+$/g,""),e[1]=e[1].replace(/^['"](.*)['"]$/g,"$1"),r[e[0]]=e[1]);return r},p=function(t){function e(){var e;return(e=t.call(this)||this).customParsers=[],e.tagMappers=[],e.lineNumber=0,e}a(e,t);var i=e.prototype;return i.push=function(t){var e,i,r=this;(this.lineNumber=this.lineNumber+1,0!==(t=t.trim()).length)&&("#"===t[0]?this.tagMappers.reduce((function(e,i){var r=i(t);return r===t?e:e.concat([r])}),[t]).forEach((function(t){for(var a=0;a<r.customParsers.length;a++)if(r.customParsers[a].call(r,t))return;if(0===t.indexOf("#EXT"))if(t=t.replace("\r",""),e=/^#EXTM3U/.exec(t))r.trigger("data",{type:"tag",tagType:"m3u"});else{if(e=/^#EXTINF:?([0-9\.]*)?,?(.*)?$/.exec(t))return i={type:"tag",tagType:"inf"},e[1]&&(i.duration=parseFloat(e[1])),e[2]&&(i.title=e[2]),void r.trigger("data",i);if(e=/^#EXT-X-TARGETDURATION:?([0-9.]*)?/.exec(t))return i={type:"tag",tagType:"targetduration"},e[1]&&(i.duration=parseInt(e[1],10)),void r.trigger("data",i);if(e=/^#EXT-X-VERSION:?([0-9.]*)?/.exec(t))return i={type:"tag",tagType:"version"},e[1]&&(i.version=parseInt(e[1],10)),void r.trigger("data",i);if(e=/^#EXT-X-MEDIA-SEQUENCE:?(\-?[0-9.]*)?/.exec(t))return i={type:"tag",tagType:"media-sequence"},e[1]&&(i.number=parseInt(e[1],10)),void r.trigger("data",i);if(e=/^#EXT-X-DISCONTINUITY-SEQUENCE:?(\-?[0-9.]*)?/.exec(t))return i={type:"tag",tagType:"discontinuity-sequence"},e[1]&&(i.number=parseInt(e[1],10)),void r.trigger("data",i);if(e=/^#EXT-X-PLAYLIST-TYPE:?(.*)?$/.exec(t))return i={type:"tag",tagType:"playlist-type"},e[1]&&(i.playlistType=e[1]),void r.trigger("data",i);if(e=/^#EXT-X-BYTERANGE:?(.*)?$/.exec(t))return i=u(g(e[1]),{type:"tag",tagType:"byterange"}),void r.trigger("data",i);if(e=/^#EXT-X-ALLOW-CACHE:?(YES|NO)?/.exec(t))return i={type:"tag",tagType:"allow-cache"},e[1]&&(i.allowed=!/NO/.test(e[1])),void r.trigger("data",i);if(e=/^#EXT-X-MAP:?(.*)$/.exec(t)){if(i={type:"tag",tagType:"map"},e[1]){var s=f(e[1]);s.URI&&(i.uri=s.URI),s.BYTERANGE&&(i.byterange=g(s.BYTERANGE))}r.trigger("data",i)}else if(e=/^#EXT-X-STREAM-INF:?(.*)$/.exec(t)){if(i={type:"tag",tagType:"stream-inf"},e[1]){if(i.attributes=f(e[1]),i.attributes.RESOLUTION){var n=i.attributes.RESOLUTION.split("x"),p={};n[0]&&(p.width=parseInt(n[0],10)),n[1]&&(p.height=parseInt(n[1],10)),i.attributes.RESOLUTION=p}i.attributes.BANDWIDTH&&(i.attributes.BANDWIDTH=parseInt(i.attributes.BANDWIDTH,10)),i.attributes["PROGRAM-ID"]&&(i.attributes["PROGRAM-ID"]=parseInt(i.attributes["PROGRAM-ID"],10))}r.trigger("data",i)}else{if(e=/^#EXT-X-MEDIA:?(.*)$/.exec(t))return i={type:"tag",tagType:"media"},e[1]&&(i.attributes=f(e[1])),void r.trigger("data",i);if(e=/^#EXT-X-ENDLIST/.exec(t))r.trigger("data",{type:"tag",tagType:"endlist"});else if(e=/^#EXT-X-DISCONTINUITY/.exec(t))r.trigger("data",{type:"tag",tagType:"discontinuity"});else{if(e=/^#EXT-X-PROGRAM-DATE-TIME:?(.*)$/.exec(t))return i={type:"tag",tagType:"program-date-time"},e[1]&&(i.dateTimeString=e[1],i.dateTimeObject=new Date(e[1])),void r.trigger("data",i);if(e=/^#EXT-X-KEY:?(.*)$/.exec(t))return i={type:"tag",tagType:"key"},e[1]&&(i.attributes=f(e[1]),i.attributes.IV&&("0x"===i.attributes.IV.substring(0,2).toLowerCase()&&(i.attributes.IV=i.attributes.IV.substring(2)),i.attributes.IV=i.attributes.IV.match(/.{8}/g),i.attributes.IV[0]=parseInt(i.attributes.IV[0],16),i.attributes.IV[1]=parseInt(i.attributes.IV[1],16),i.attributes.IV[2]=parseInt(i.attributes.IV[2],16),i.attributes.IV[3]=parseInt(i.attributes.IV[3],16),i.attributes.IV=new Uint32Array(i.attributes.IV))),void r.trigger("data",i);if(e=/^#EXT-X-START:?(.*)$/.exec(t))return i={type:"tag",tagType:"start"},e[1]&&(i.attributes=f(e[1]),i.attributes["TIME-OFFSET"]=parseFloat(i.attributes["TIME-OFFSET"]),i.attributes.PRECISE=/YES/.test(i.attributes.PRECISE)),void r.trigger("data",i);if(e=/^#EXT-X-CUE-OUT-CONT:?(.*)?$/.exec(t))return i={type:"tag",tagType:"cue-out-cont"},e[1]?i.data=e[1]:i.data="",void r.trigger("data",i);if(e=/^#EXT-X-CUE-OUT:?(.*)?$/.exec(t))return i={type:"tag",tagType:"cue-out"},e[1]?i.data=e[1]:i.data="",void r.trigger("data",i);if(e=/^#EXT-X-CUE-IN:?(.*)?$/.exec(t))return i={type:"tag",tagType:"cue-in"},e[1]?i.data=e[1]:i.data="",void r.trigger("data",i);if((e=/^#EXT-X-SKIP:(.*)$/.exec(t))&&e[1])return(i={type:"tag",tagType:"skip"}).attributes=f(e[1]),i.attributes.hasOwnProperty("SKIPPED-SEGMENTS")&&(i.attributes["SKIPPED-SEGMENTS"]=parseInt(i.attributes["SKIPPED-SEGMENTS"],10)),i.attributes.hasOwnProperty("RECENTLY-REMOVED-DATERANGES")&&(i.attributes["RECENTLY-REMOVED-DATERANGES"]=i.attributes["RECENTLY-REMOVED-DATERANGES"].split(o)),void r.trigger("data",i);if((e=/^#EXT-X-PART:(.*)$/.exec(t))&&e[1])return(i={type:"tag",tagType:"part"}).attributes=f(e[1]),["DURATION"].forEach((function(t){i.attributes.hasOwnProperty(t)&&(i.attributes[t]=parseFloat(i.attributes[t]))})),["INDEPENDENT","GAP"].forEach((function(t){i.attributes.hasOwnProperty(t)&&(i.attributes[t]=/YES/.test(i.attributes[t]))})),i.attributes.hasOwnProperty("BYTERANGE")&&(i.attributes.byterange=g(i.attributes.BYTERANGE)),void r.trigger("data",i);if((e=/^#EXT-X-SERVER-CONTROL:(.*)$/.exec(t))&&e[1])return(i={type:"tag",tagType:"server-control"}).attributes=f(e[1]),["CAN-SKIP-UNTIL","PART-HOLD-BACK","HOLD-BACK"].forEach((function(t){i.attributes.hasOwnProperty(t)&&(i.attributes[t]=parseFloat(i.attributes[t]))})),["CAN-SKIP-DATERANGES","CAN-BLOCK-RELOAD"].forEach((function(t){i.attributes.hasOwnProperty(t)&&(i.attributes[t]=/YES/.test(i.attributes[t]))})),void r.trigger("data",i);if((e=/^#EXT-X-PART-INF:(.*)$/.exec(t))&&e[1])return(i={type:"tag",tagType:"part-inf"}).attributes=f(e[1]),["PART-TARGET"].forEach((function(t){i.attributes.hasOwnProperty(t)&&(i.attributes[t]=parseFloat(i.attributes[t]))})),void r.trigger("data",i);if((e=/^#EXT-X-PRELOAD-HINT:(.*)$/.exec(t))&&e[1])return(i={type:"tag",tagType:"preload-hint"}).attributes=f(e[1]),["BYTERANGE-START","BYTERANGE-LENGTH"].forEach((function(t){if(i.attributes.hasOwnProperty(t)){i.attributes[t]=parseInt(i.attributes[t],10);var e="BYTERANGE-LENGTH"===t?"length":"offset";i.attributes.byterange=i.attributes.byterange||{},i.attributes.byterange[e]=i.attributes[t],delete i.attributes[t]}})),void r.trigger("data",i);if((e=/^#EXT-X-RENDITION-REPORT:(.*)$/.exec(t))&&e[1])return(i={type:"tag",tagType:"rendition-report"}).attributes=f(e[1]),["LAST-MSN","LAST-PART"].forEach((function(t){i.attributes.hasOwnProperty(t)&&(i.attributes[t]=parseInt(i.attributes[t],10))})),void r.trigger("data",i);r.trigger("data",{type:"tag",data:t.slice(4)})}}}else r.trigger("data",{type:"comment",text:t.slice(1)})})):this.trigger("data",{type:"uri",uri:t}))},i.addParser=function(t){var e=this,i=t.expression,r=t.customType,a=t.dataParser,s=t.segment;"function"!=typeof a&&(a=function(t){return t}),this.customParsers.push((function(t){if(i.exec(t))return e.trigger("data",{type:"custom",data:a(t),customType:r,segment:s}),!0}))},i.addTagMapper=function(t){var e=t.expression,i=t.map;this.tagMappers.push((function(t){return e.test(t)?i(t):t}))},e}(s);var c=function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t};function d(t){for(var e,i=(e=t,r.default.atob?r.default.atob(e):Buffer.from(e,"base64").toString("binary")),a=new Uint8Array(i.length),s=0;s<i.length;s++)a[s]=i.charCodeAt(s);return a}var h=function(t){var e={};return Object.keys(t).forEach((function(i){var r;e[(r=i,r.toLowerCase().replace(/-(\w)/g,(function(t){return t[1].toUpperCase()})))]=t[i]})),e},l=function(t){var e=t.serverControl,i=t.targetDuration,r=t.partTargetDuration;if(e){var a="#EXT-X-SERVER-CONTROL",s="holdBack",n="partHoldBack",u=i&&3*i,o=r&&2*r;i&&!e.hasOwnProperty(s)&&(e[s]=u,this.trigger("info",{message:a+" defaulting HOLD-BACK to targetDuration * 3 ("+u+")."})),u&&e[s]<u&&(this.trigger("warn",{message:a+" clamping HOLD-BACK ("+e[s]+") to targetDuration * 3 ("+u+")"}),e[s]=u),r&&!e.hasOwnProperty(n)&&(e[n]=3*r,this.trigger("info",{message:a+" defaulting PART-HOLD-BACK to partTargetDuration * 3 ("+e[n]+")."})),r&&e[n]<o&&(this.trigger("warn",{message:a+" clamping PART-HOLD-BACK ("+e[n]+") to partTargetDuration * 2 ("+o+")."}),e[n]=o)}},b=function(t){function e(){var e;(e=t.call(this)||this).lineStream=new n,e.parseStream=new p,e.lineStream.pipe(e.parseStream);var i,r,a=c(e),s=[],o={},g=!1,f=function(){},b={AUDIO:{},VIDEO:{},"CLOSED-CAPTIONS":{},SUBTITLES:{}},E=0;e.manifest={allowCache:!0,discontinuityStarts:[],segments:[]};var m=0,T=0,y=0;return e.on("end",(function(){o.uri||!o.parts&&!o.preloadHints||(!o.map&&i&&(o.map=i),!o.key&&r&&(o.key=r),o.timeline||"number"!=typeof E||(o.timeline=E),e.manifest.preloadSegment=o)})),e.parseStream.on("data",(function(t){var e,n;Object.keys(o).length||(y=this.lineNumber),{tag:function(){({version:function(){t.version&&(this.manifest.version=t.version)},"allow-cache":function(){this.manifest.allowCache=t.allowed,"allowed"in t||(this.trigger("info",{message:"defaulting allowCache to YES"}),this.manifest.allowCache=!0)},byterange:function(){var e={};"length"in t&&(o.byterange=e,e.length=t.length,"offset"in t||(t.offset=m)),"offset"in t&&(o.byterange=e,e.offset=t.offset),m=e.offset+e.length},endlist:function(){this.manifest.endList=!0},inf:function(){"mediaSequence"in this.manifest||(this.manifest.mediaSequence=0,this.trigger("info",{message:"defaulting media sequence to zero"})),"discontinuitySequence"in this.manifest||(this.manifest.discontinuitySequence=0,this.trigger("info",{message:"defaulting discontinuity sequence to zero"})),t.duration>0&&(o.duration=t.duration),0===t.duration&&(o.duration=.01,this.trigger("info",{message:"updating zero segment duration to a small value"})),this.manifest.segments=s},key:function(){if(t.attributes)if("NONE"!==t.attributes.METHOD)if(t.attributes.URI){if("com.apple.streamingkeydelivery"===t.attributes.KEYFORMAT)return this.manifest.contentProtection=this.manifest.contentProtection||{},void(this.manifest.contentProtection["com.apple.fps.1_0"]={attributes:t.attributes});if("com.microsoft.playready"===t.attributes.KEYFORMAT)return this.manifest.contentProtection=this.manifest.contentProtection||{},void(this.manifest.contentProtection["com.microsoft.playready"]={uri:t.attributes.URI});if("urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"===t.attributes.KEYFORMAT){return-1===["SAMPLE-AES","SAMPLE-AES-CTR","SAMPLE-AES-CENC"].indexOf(t.attributes.METHOD)?void this.trigger("warn",{message:"invalid key method provided for Widevine"}):("SAMPLE-AES-CENC"===t.attributes.METHOD&&this.trigger("warn",{message:"SAMPLE-AES-CENC is deprecated, please use SAMPLE-AES-CTR instead"}),"data:text/plain;base64,"!==t.attributes.URI.substring(0,23)?void this.trigger("warn",{message:"invalid key URI provided for Widevine"}):t.attributes.KEYID&&"0x"===t.attributes.KEYID.substring(0,2)?(this.manifest.contentProtection=this.manifest.contentProtection||{},void(this.manifest.contentProtection["com.widevine.alpha"]={attributes:{schemeIdUri:t.attributes.KEYFORMAT,keyId:t.attributes.KEYID.substring(2)},pssh:d(t.attributes.URI.split(",")[1])})):void this.trigger("warn",{message:"invalid key ID provided for Widevine"}))}t.attributes.METHOD||this.trigger("warn",{message:"defaulting key method to AES-128"}),r={method:t.attributes.METHOD||"AES-128",uri:t.attributes.URI},void 0!==t.attributes.IV&&(r.iv=t.attributes.IV)}else this.trigger("warn",{message:"ignoring key declaration without URI"});else r=null;else this.trigger("warn",{message:"ignoring key declaration without attribute list"})},"media-sequence":function(){isFinite(t.number)?this.manifest.mediaSequence=t.number:this.trigger("warn",{message:"ignoring invalid media sequence: "+t.number})},"discontinuity-sequence":function(){isFinite(t.number)?(this.manifest.discontinuitySequence=t.number,E=t.number):this.trigger("warn",{message:"ignoring invalid discontinuity sequence: "+t.number})},"playlist-type":function(){/VOD|EVENT/.test(t.playlistType)?this.manifest.playlistType=t.playlistType:this.trigger("warn",{message:"ignoring unknown playlist type: "+t.playlist})},map:function(){i={},t.uri&&(i.uri=t.uri),t.byterange&&(i.byterange=t.byterange),r&&(i.key=r)},"stream-inf":function(){this.manifest.playlists=s,this.manifest.mediaGroups=this.manifest.mediaGroups||b,t.attributes?(o.attributes||(o.attributes={}),u(o.attributes,t.attributes)):this.trigger("warn",{message:"ignoring empty stream-inf attributes"})},media:function(){if(this.manifest.mediaGroups=this.manifest.mediaGroups||b,t.attributes&&t.attributes.TYPE&&t.attributes["GROUP-ID"]&&t.attributes.NAME){var i=this.manifest.mediaGroups[t.attributes.TYPE];i[t.attributes["GROUP-ID"]]=i[t.attributes["GROUP-ID"]]||{},e=i[t.attributes["GROUP-ID"]],(n={default:/yes/i.test(t.attributes.DEFAULT)}).default?n.autoselect=!0:n.autoselect=/yes/i.test(t.attributes.AUTOSELECT),t.attributes.LANGUAGE&&(n.language=t.attributes.LANGUAGE),t.attributes.URI&&(n.uri=t.attributes.URI),t.attributes["INSTREAM-ID"]&&(n.instreamId=t.attributes["INSTREAM-ID"]),t.attributes.CHARACTERISTICS&&(n.characteristics=t.attributes.CHARACTERISTICS),t.attributes.FORCED&&(n.forced=/yes/i.test(t.attributes.FORCED)),e[t.attributes.NAME]=n}else this.trigger("warn",{message:"ignoring incomplete or missing media group"})},discontinuity:function(){E+=1,o.discontinuity=!0,this.manifest.discontinuityStarts.push(s.length)},"program-date-time":function(){void 0===this.manifest.dateTimeString&&(this.manifest.dateTimeString=t.dateTimeString,this.manifest.dateTimeObject=t.dateTimeObject),o.dateTimeString=t.dateTimeString,o.dateTimeObject=t.dateTimeObject},targetduration:function(){!isFinite(t.duration)||t.duration<0?this.trigger("warn",{message:"ignoring invalid target duration: "+t.duration}):(this.manifest.targetDuration=t.duration,l.call(this,this.manifest))},start:function(){t.attributes&&!isNaN(t.attributes["TIME-OFFSET"])?this.manifest.start={timeOffset:t.attributes["TIME-OFFSET"],precise:t.attributes.PRECISE}:this.trigger("warn",{message:"ignoring start declaration without appropriate attribute list"})},"cue-out":function(){o.cueOut=t.data},"cue-out-cont":function(){o.cueOutCont=t.data},"cue-in":function(){o.cueIn=t.data},skip:function(){this.manifest.skip=h(t.attributes),this.warnOnMissingAttributes_("#EXT-X-SKIP",t.attributes,["SKIPPED-SEGMENTS"])},part:function(){var e=this;g=!0;var i=this.manifest.segments.length,r=h(t.attributes);o.parts=o.parts||[],o.parts.push(r),r.byterange&&(r.byterange.hasOwnProperty("offset")||(r.byterange.offset=T),T=r.byterange.offset+r.byterange.length);var a=o.parts.length-1;this.warnOnMissingAttributes_("#EXT-X-PART #"+a+" for segment #"+i,t.attributes,["URI","DURATION"]),this.manifest.renditionReports&&this.manifest.renditionReports.forEach((function(t,i){t.hasOwnProperty("lastPart")||e.trigger("warn",{message:"#EXT-X-RENDITION-REPORT #"+i+" lacks required attribute(s): LAST-PART"})}))},"server-control":function(){var e=this.manifest.serverControl=h(t.attributes);e.hasOwnProperty("canBlockReload")||(e.canBlockReload=!1,this.trigger("info",{message:"#EXT-X-SERVER-CONTROL defaulting CAN-BLOCK-RELOAD to false"})),l.call(this,this.manifest),e.canSkipDateranges&&!e.hasOwnProperty("canSkipUntil")&&this.trigger("warn",{message:"#EXT-X-SERVER-CONTROL lacks required attribute CAN-SKIP-UNTIL which is required when CAN-SKIP-DATERANGES is set"})},"preload-hint":function(){var e=this.manifest.segments.length,i=h(t.attributes),r=i.type&&"PART"===i.type;o.preloadHints=o.preloadHints||[],o.preloadHints.push(i),i.byterange&&(i.byterange.hasOwnProperty("offset")||(i.byterange.offset=r?T:0,r&&(T=i.byterange.offset+i.byterange.length)));var a=o.preloadHints.length-1;if(this.warnOnMissingAttributes_("#EXT-X-PRELOAD-HINT #"+a+" for segment #"+e,t.attributes,["TYPE","URI"]),i.type)for(var s=0;s<o.preloadHints.length-1;s++){var n=o.preloadHints[s];n.type&&(n.type===i.type&&this.trigger("warn",{message:"#EXT-X-PRELOAD-HINT #"+a+" for segment #"+e+" has the same TYPE "+i.type+" as preload hint #"+s}))}},"rendition-report":function(){var e=h(t.attributes);this.manifest.renditionReports=this.manifest.renditionReports||[],this.manifest.renditionReports.push(e);var i=this.manifest.renditionReports.length-1,r=["LAST-MSN","URI"];g&&r.push("LAST-PART"),this.warnOnMissingAttributes_("#EXT-X-RENDITION-REPORT #"+i,t.attributes,r)},"part-inf":function(){this.manifest.partInf=h(t.attributes),this.warnOnMissingAttributes_("#EXT-X-PART-INF",t.attributes,["PART-TARGET"]),this.manifest.partInf.partTarget&&(this.manifest.partTargetDuration=this.manifest.partInf.partTarget),l.call(this,this.manifest)}}[t.tagType]||f).call(a)},uri:function(){o.uri=t.uri,o.lineNumberStart=y,o.lineNumberEnd=this.parseStream.lineNumber,s.push(o),this.manifest.targetDuration&&!("duration"in o)&&(this.trigger("warn",{message:"defaulting segment duration to the target duration"}),o.duration=this.manifest.targetDuration),r&&(o.key=r),o.timeline=E,i&&(o.map=i),T=0,o={}},comment:function(){},custom:function(){t.segment?(o.custom=o.custom||{},o.custom[t.customType]=t.data):(this.manifest.custom=this.manifest.custom||{},this.manifest.custom[t.customType]=t.data)}}[t.type].call(a)})),e}a(e,t);var i=e.prototype;return i.warnOnMissingAttributes_=function(t,e,i){var r=[];i.forEach((function(t){e.hasOwnProperty(t)||r.push(t)})),r.length&&this.trigger("warn",{message:t+" lacks required attribute(s): "+r.join(", ")})},i.push=function(t){this.lineStream.push(t)},i.end=function(){this.lineStream.push("\n"),this.trigger("end")},i.addParser=function(t){this.parseStream.addParser(t)},i.addTagMapper=function(t){this.parseStream.addTagMapper(t)},e}(s);t.LineStream=n,t.ParseStream=p,t.Parser=b,Object.defineProperty(t,"__esModule",{value:!0})}));
|
package/index.html
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>m3u8-parser Demo</title>
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
<p>Open dev tools to try it out</p>
|
|
9
|
+
<ul>
|
|
10
|
+
<li><a href="test/debug.html">Run unit tests in browser.</a></li>
|
|
11
|
+
<li><a href="docs/api/">Read generated docs.</a></li>
|
|
12
|
+
</ul>
|
|
13
|
+
<script src="dist/m3u8-parser.js"></script>
|
|
14
|
+
</body>
|
|
15
|
+
</html>
|
package/package.json
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@transmitlive/m3u8-parser",
|
|
3
|
+
"version": "4.7.2-beta.6",
|
|
4
|
+
"description": "m3u8 parser",
|
|
5
|
+
"main": "dist/m3u8-parser.cjs.js",
|
|
6
|
+
"module": "dist/m3u8-parser.es.js",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git@github.com:TransmitLive/m3u8-parser.git"
|
|
10
|
+
},
|
|
11
|
+
"contributors": [
|
|
12
|
+
{
|
|
13
|
+
"name": "gkatsev",
|
|
14
|
+
"github": "https://github.com/gkatsev"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"name": "imbcmdth",
|
|
18
|
+
"github": "https://github.com/imbcmdth"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "dmlap",
|
|
22
|
+
"github": "https://github.com/dmlap"
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build-test": "cross-env-shell TEST_BUNDLE_ONLY=1 'npm run build'",
|
|
27
|
+
"build-prod": "cross-env-shell NO_TEST_BUNDLE=1 'npm run build'",
|
|
28
|
+
"build": "npm-run-all -s clean -p build:*",
|
|
29
|
+
"build:js": "rollup -c scripts/rollup.config.js",
|
|
30
|
+
"clean": "shx rm -rf ./dist ./test/dist && shx mkdir -p ./dist ./test/dist",
|
|
31
|
+
"lint": "vjsstandard",
|
|
32
|
+
"prepublishOnly": "npm-run-all build-prod && vjsverify --verbose",
|
|
33
|
+
"start": "npm-run-all -p server watch",
|
|
34
|
+
"server": "karma start scripts/karma.conf.js --singleRun=false --auto-watch",
|
|
35
|
+
"test": "npm-run-all lint build-test test:*",
|
|
36
|
+
"test:browser": "karma start scripts/karma.conf.js",
|
|
37
|
+
"test:node": "qunit test/dist/bundle.js",
|
|
38
|
+
"posttest": "shx cat test/dist/coverage/text.txt",
|
|
39
|
+
"preversion": "npm test",
|
|
40
|
+
"version": "is-prerelease || npm run update-changelog && git add CHANGELOG.md",
|
|
41
|
+
"update-changelog": "conventional-changelog -p videojs -i CHANGELOG.md -s",
|
|
42
|
+
"watch": "npm-run-all -p watch:*",
|
|
43
|
+
"watch:js": "npm run build:js -- -w"
|
|
44
|
+
},
|
|
45
|
+
"keywords": [
|
|
46
|
+
"videojs",
|
|
47
|
+
"videojs-plugin"
|
|
48
|
+
],
|
|
49
|
+
"author": "Brightcove, Inc",
|
|
50
|
+
"license": "Apache-2.0",
|
|
51
|
+
"vjsstandard": {
|
|
52
|
+
"ignore": [
|
|
53
|
+
"dist",
|
|
54
|
+
"docs",
|
|
55
|
+
"test/dist"
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
"files": [
|
|
59
|
+
"CONTRIBUTING.md",
|
|
60
|
+
"dist/",
|
|
61
|
+
"docs/",
|
|
62
|
+
"index.html",
|
|
63
|
+
"scripts/",
|
|
64
|
+
"src/",
|
|
65
|
+
"test/"
|
|
66
|
+
],
|
|
67
|
+
"dependencies": {
|
|
68
|
+
"@babel/runtime": "^7.12.5",
|
|
69
|
+
"@videojs/vhs-utils": "^3.0.0",
|
|
70
|
+
"global": "^4.4.0"
|
|
71
|
+
},
|
|
72
|
+
"devDependencies": {
|
|
73
|
+
"@rollup/plugin-replace": "^2.3.4",
|
|
74
|
+
"@videojs/generator-helpers": "~2.0.1",
|
|
75
|
+
"karma": "^5.2.3",
|
|
76
|
+
"rollup": "^2.37.1",
|
|
77
|
+
"rollup-plugin-data-files": "^0.1.0",
|
|
78
|
+
"sinon": "^9.2.3",
|
|
79
|
+
"videojs-generate-karma-config": "~7.1.0",
|
|
80
|
+
"videojs-generate-rollup-config": "~6.2.0",
|
|
81
|
+
"videojs-generator-verify": "~3.0.1",
|
|
82
|
+
"videojs-standard": "^8.0.4"
|
|
83
|
+
},
|
|
84
|
+
"generator-videojs-plugin": {
|
|
85
|
+
"version": "7.7.3"
|
|
86
|
+
},
|
|
87
|
+
"browserslist": [
|
|
88
|
+
"defaults",
|
|
89
|
+
"ie 11"
|
|
90
|
+
],
|
|
91
|
+
"husky": {
|
|
92
|
+
"hooks": {
|
|
93
|
+
"pre-commit": "lint-staged"
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
"lint-staged": {
|
|
97
|
+
"*.js": "vjsstandard --fix",
|
|
98
|
+
"README.md": "doctoc --notitle"
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const generate = require('videojs-generate-karma-config');
|
|
2
|
+
|
|
3
|
+
module.exports = function(config) {
|
|
4
|
+
|
|
5
|
+
// see https://github.com/videojs/videojs-generate-karma-config
|
|
6
|
+
// for options
|
|
7
|
+
const options = {};
|
|
8
|
+
|
|
9
|
+
config = generate(config, options);
|
|
10
|
+
|
|
11
|
+
// any other custom stuff not supported by options here!
|
|
12
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const generate = require('videojs-generate-rollup-config');
|
|
2
|
+
const replace = require('@rollup/plugin-replace');
|
|
3
|
+
const dataFiles = require('rollup-plugin-data-files');
|
|
4
|
+
|
|
5
|
+
// see https://github.com/videojs/videojs-generate-rollup-config
|
|
6
|
+
// for options
|
|
7
|
+
const options = {
|
|
8
|
+
input: 'src/index.js',
|
|
9
|
+
externals(defaults) {
|
|
10
|
+
defaults.module.push('@videojs/vhs-utils');
|
|
11
|
+
|
|
12
|
+
return defaults;
|
|
13
|
+
},
|
|
14
|
+
primedPlugins(defaults) {
|
|
15
|
+
// when using "require" rather than import
|
|
16
|
+
// require cjs module
|
|
17
|
+
defaults.replace = replace({
|
|
18
|
+
// single quote replace
|
|
19
|
+
"require('@videojs/vhs-utils/es": "require('@videojs/vhs-utils/cjs",
|
|
20
|
+
// double quote replace
|
|
21
|
+
'require("@videojs/vhs-utils/es': 'require("@videojs/vhs-utils/cjs'
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
defaults.dataFiles = dataFiles({
|
|
25
|
+
expecteds: {include: 'test/fixtures/integration/*.js', transform: 'js', extensions: false},
|
|
26
|
+
manifests: {include: 'test/fixtures/integration/*.m3u8', transform: 'string', extensions: false}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
return defaults;
|
|
30
|
+
},
|
|
31
|
+
plugins(defaults) {
|
|
32
|
+
defaults.module.unshift('replace');
|
|
33
|
+
defaults.test.unshift('dataFiles');
|
|
34
|
+
|
|
35
|
+
return defaults;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const config = generate(options);
|
|
39
|
+
|
|
40
|
+
if (config.builds.test) {
|
|
41
|
+
config.builds.test.output[0].format = 'umd';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Add additonal builds/customization here!
|
|
45
|
+
|
|
46
|
+
// export the builds to rollup
|
|
47
|
+
export default Object.values(config.builds);
|
package/src/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file m3u8/index.js
|
|
3
|
+
*
|
|
4
|
+
* Utilities for parsing M3U8 files. If the entire manifest is available,
|
|
5
|
+
* `Parser` will create an object representation with enough detail for managing
|
|
6
|
+
* playback. `ParseStream` and `LineStream` are lower-level parsing primitives
|
|
7
|
+
* that do not assume the entirety of the manifest is ready and expose a
|
|
8
|
+
* ReadableStream-like interface.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import LineStream from './line-stream';
|
|
12
|
+
import ParseStream from './parse-stream';
|
|
13
|
+
import Parser from './parser';
|
|
14
|
+
|
|
15
|
+
export {
|
|
16
|
+
LineStream,
|
|
17
|
+
ParseStream,
|
|
18
|
+
Parser
|
|
19
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file m3u8/line-stream.js
|
|
3
|
+
*/
|
|
4
|
+
import Stream from '@videojs/vhs-utils/es/stream.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A stream that buffers string input and generates a `data` event for each
|
|
8
|
+
* line.
|
|
9
|
+
*
|
|
10
|
+
* @class LineStream
|
|
11
|
+
* @extends Stream
|
|
12
|
+
*/
|
|
13
|
+
export default class LineStream extends Stream {
|
|
14
|
+
constructor() {
|
|
15
|
+
super();
|
|
16
|
+
this.buffer = '';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Add new data to be parsed.
|
|
21
|
+
*
|
|
22
|
+
* @param {string} data the text to process
|
|
23
|
+
*/
|
|
24
|
+
push(data) {
|
|
25
|
+
let nextNewline;
|
|
26
|
+
|
|
27
|
+
this.buffer += data;
|
|
28
|
+
nextNewline = this.buffer.indexOf('\n');
|
|
29
|
+
|
|
30
|
+
for (; nextNewline > -1; nextNewline = this.buffer.indexOf('\n')) {
|
|
31
|
+
this.trigger('data', this.buffer.substring(0, nextNewline));
|
|
32
|
+
this.buffer = this.buffer.substring(nextNewline + 1);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|