@transmitlive/m3u8-parser 7.1.0-2 → 7.1.0-4

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.
@@ -1,4 +1,4 @@
1
- /*! @name @transmitlive/m3u8-parser @version 7.1.0-2 @license Apache-2.0 */
1
+ /*! @name @transmitlive/m3u8-parser @version 7.1.0-4 @license Apache-2.0 */
2
2
  'use strict';
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
@@ -395,10 +395,6 @@ class ParseStream extends Stream__default["default"] {
395
395
  event.attributes.BANDWIDTH = parseInt(event.attributes.BANDWIDTH, 10);
396
396
  }
397
397
 
398
- if (event.attributes['FRAME-RATE']) {
399
- event.attributes['FRAME-RATE'] = parseFloat(event.attributes['FRAME-RATE']);
400
- }
401
-
402
398
  if (event.attributes['PROGRAM-ID']) {
403
399
  event.attributes['PROGRAM-ID'] = parseInt(event.attributes['PROGRAM-ID'], 10);
404
400
  }
@@ -1106,25 +1102,17 @@ class Parser extends Stream__default["default"] {
1106
1102
  attributes: entry.attributes
1107
1103
  };
1108
1104
  return;
1109
- }
1110
-
1111
- if (entry.attributes.KEYFORMAT === 'com.microsoft.playready') {
1112
- this.manifest.contentProtection = this.manifest.contentProtection || {}; // TODO: add full support for this.
1113
-
1114
- this.manifest.contentProtection['com.microsoft.playready'] = {
1115
- uri: entry.attributes.URI
1116
- };
1117
- return;
1118
- } // check if the content is encrypted for Widevine
1105
+ } // check if the content is encrypted for Widevine or Playready
1119
1106
  // Widevine/HLS spec: https://storage.googleapis.com/wvdocs/Widevine_DRM_HLS.pdf
1120
1107
 
1121
1108
 
1122
- if (entry.attributes.KEYFORMAT === widevineUuid) {
1109
+ if (entry.attributes.KEYFORMAT === widevineUuid || entry.attributes.KEYFORMAT === 'com.microsoft.playready') {
1110
+ const protectionSystem = entry.attributes.KEYFORMAT === widevineUuid ? 'com.widevine.alpha' : 'com.microsoft.playready';
1123
1111
  const VALID_METHODS = ['SAMPLE-AES', 'SAMPLE-AES-CTR', 'SAMPLE-AES-CENC'];
1124
1112
 
1125
1113
  if (VALID_METHODS.indexOf(entry.attributes.METHOD) === -1) {
1126
1114
  this.trigger('warn', {
1127
- message: 'invalid key method provided for Widevine'
1115
+ message: `invalid key method provided for ${protectionSystem}`
1128
1116
  });
1129
1117
  return;
1130
1118
  }
@@ -1137,26 +1125,28 @@ class Parser extends Stream__default["default"] {
1137
1125
 
1138
1126
  if (entry.attributes.URI.substring(0, 23) !== 'data:text/plain;base64,') {
1139
1127
  this.trigger('warn', {
1140
- message: 'invalid key URI provided for Widevine'
1128
+ message: `invalid key URI provided for ${protectionSystem}`
1141
1129
  });
1142
1130
  return;
1143
1131
  }
1144
1132
 
1145
1133
  if (!(entry.attributes.KEYID && entry.attributes.KEYID.substring(0, 2) === '0x')) {
1146
1134
  this.trigger('warn', {
1147
- message: 'invalid key ID provided for Widevine'
1135
+ message: `invalid key ID provided for ${protectionSystem}`
1148
1136
  });
1149
1137
  return;
1150
- } // if Widevine key attributes are valid, store them as `contentProtection`
1151
- // on the manifest to emulate Widevine tag structure in a DASH mpd
1138
+ } // if key attributes are valid, store them as `contentProtection`
1139
+ // on the manifest to emulate tag structure in a DASH mpd
1152
1140
 
1153
1141
 
1154
1142
  this.manifest.contentProtection = this.manifest.contentProtection || {};
1155
- this.manifest.contentProtection['com.widevine.alpha'] = {
1143
+ this.manifest.contentProtection[protectionSystem] = {
1156
1144
  attributes: {
1157
1145
  schemeIdUri: entry.attributes.KEYFORMAT,
1158
1146
  // remove '0x' from the key id string
1159
- keyId: entry.attributes.KEYID.substring(2)
1147
+ keyId: entry.attributes.KEYID.substring(2),
1148
+ method: entry.attributes.METHOD,
1149
+ iv: entry.attributes.IV
1160
1150
  },
1161
1151
  // decode the base64-encoded PSSH box
1162
1152
  pssh: decodeB64ToUint8Array__default["default"](entry.attributes.URI.split(',')[1])
@@ -1,4 +1,4 @@
1
- /*! @name @transmitlive/m3u8-parser @version 7.1.0-2 @license Apache-2.0 */
1
+ /*! @name @transmitlive/m3u8-parser @version 7.1.0-4 @license Apache-2.0 */
2
2
  import Stream from '@videojs/vhs-utils/es/stream.js';
3
3
  import _extends from '@babel/runtime/helpers/extends';
4
4
  import decodeB64ToUint8Array from '@videojs/vhs-utils/es/decode-b64-to-uint8-array.js';
@@ -385,10 +385,6 @@ class ParseStream extends Stream {
385
385
  event.attributes.BANDWIDTH = parseInt(event.attributes.BANDWIDTH, 10);
386
386
  }
387
387
 
388
- if (event.attributes['FRAME-RATE']) {
389
- event.attributes['FRAME-RATE'] = parseFloat(event.attributes['FRAME-RATE']);
390
- }
391
-
392
388
  if (event.attributes['PROGRAM-ID']) {
393
389
  event.attributes['PROGRAM-ID'] = parseInt(event.attributes['PROGRAM-ID'], 10);
394
390
  }
@@ -1096,25 +1092,17 @@ class Parser extends Stream {
1096
1092
  attributes: entry.attributes
1097
1093
  };
1098
1094
  return;
1099
- }
1100
-
1101
- if (entry.attributes.KEYFORMAT === 'com.microsoft.playready') {
1102
- this.manifest.contentProtection = this.manifest.contentProtection || {}; // TODO: add full support for this.
1103
-
1104
- this.manifest.contentProtection['com.microsoft.playready'] = {
1105
- uri: entry.attributes.URI
1106
- };
1107
- return;
1108
- } // check if the content is encrypted for Widevine
1095
+ } // check if the content is encrypted for Widevine or Playready
1109
1096
  // Widevine/HLS spec: https://storage.googleapis.com/wvdocs/Widevine_DRM_HLS.pdf
1110
1097
 
1111
1098
 
1112
- if (entry.attributes.KEYFORMAT === widevineUuid) {
1099
+ if (entry.attributes.KEYFORMAT === widevineUuid || entry.attributes.KEYFORMAT === 'com.microsoft.playready') {
1100
+ const protectionSystem = entry.attributes.KEYFORMAT === widevineUuid ? 'com.widevine.alpha' : 'com.microsoft.playready';
1113
1101
  const VALID_METHODS = ['SAMPLE-AES', 'SAMPLE-AES-CTR', 'SAMPLE-AES-CENC'];
1114
1102
 
1115
1103
  if (VALID_METHODS.indexOf(entry.attributes.METHOD) === -1) {
1116
1104
  this.trigger('warn', {
1117
- message: 'invalid key method provided for Widevine'
1105
+ message: `invalid key method provided for ${protectionSystem}`
1118
1106
  });
1119
1107
  return;
1120
1108
  }
@@ -1127,26 +1115,28 @@ class Parser extends Stream {
1127
1115
 
1128
1116
  if (entry.attributes.URI.substring(0, 23) !== 'data:text/plain;base64,') {
1129
1117
  this.trigger('warn', {
1130
- message: 'invalid key URI provided for Widevine'
1118
+ message: `invalid key URI provided for ${protectionSystem}`
1131
1119
  });
1132
1120
  return;
1133
1121
  }
1134
1122
 
1135
1123
  if (!(entry.attributes.KEYID && entry.attributes.KEYID.substring(0, 2) === '0x')) {
1136
1124
  this.trigger('warn', {
1137
- message: 'invalid key ID provided for Widevine'
1125
+ message: `invalid key ID provided for ${protectionSystem}`
1138
1126
  });
1139
1127
  return;
1140
- } // if Widevine key attributes are valid, store them as `contentProtection`
1141
- // on the manifest to emulate Widevine tag structure in a DASH mpd
1128
+ } // if key attributes are valid, store them as `contentProtection`
1129
+ // on the manifest to emulate tag structure in a DASH mpd
1142
1130
 
1143
1131
 
1144
1132
  this.manifest.contentProtection = this.manifest.contentProtection || {};
1145
- this.manifest.contentProtection['com.widevine.alpha'] = {
1133
+ this.manifest.contentProtection[protectionSystem] = {
1146
1134
  attributes: {
1147
1135
  schemeIdUri: entry.attributes.KEYFORMAT,
1148
1136
  // remove '0x' from the key id string
1149
- keyId: entry.attributes.KEYID.substring(2)
1137
+ keyId: entry.attributes.KEYID.substring(2),
1138
+ method: entry.attributes.METHOD,
1139
+ iv: entry.attributes.IV
1150
1140
  },
1151
1141
  // decode the base64-encoded PSSH box
1152
1142
  pssh: decodeB64ToUint8Array(entry.attributes.URI.split(',')[1])
@@ -1,4 +1,4 @@
1
- /*! @name @transmitlive/m3u8-parser @version 7.1.0-2 @license Apache-2.0 */
1
+ /*! @name @transmitlive/m3u8-parser @version 7.1.0-4 @license Apache-2.0 */
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
4
4
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
@@ -528,10 +528,6 @@
528
528
  event.attributes.BANDWIDTH = parseInt(event.attributes.BANDWIDTH, 10);
529
529
  }
530
530
 
531
- if (event.attributes['FRAME-RATE']) {
532
- event.attributes['FRAME-RATE'] = parseFloat(event.attributes['FRAME-RATE']);
533
- }
534
-
535
531
  if (event.attributes['PROGRAM-ID']) {
536
532
  event.attributes['PROGRAM-ID'] = parseInt(event.attributes['PROGRAM-ID'], 10);
537
533
  }
@@ -1254,25 +1250,17 @@
1254
1250
  attributes: entry.attributes
1255
1251
  };
1256
1252
  return;
1257
- }
1258
-
1259
- if (entry.attributes.KEYFORMAT === 'com.microsoft.playready') {
1260
- this.manifest.contentProtection = this.manifest.contentProtection || {}; // TODO: add full support for this.
1261
-
1262
- this.manifest.contentProtection['com.microsoft.playready'] = {
1263
- uri: entry.attributes.URI
1264
- };
1265
- return;
1266
- } // check if the content is encrypted for Widevine
1253
+ } // check if the content is encrypted for Widevine or Playready
1267
1254
  // Widevine/HLS spec: https://storage.googleapis.com/wvdocs/Widevine_DRM_HLS.pdf
1268
1255
 
1269
1256
 
1270
- if (entry.attributes.KEYFORMAT === widevineUuid) {
1257
+ if (entry.attributes.KEYFORMAT === widevineUuid || entry.attributes.KEYFORMAT === 'com.microsoft.playready') {
1258
+ const protectionSystem = entry.attributes.KEYFORMAT === widevineUuid ? 'com.widevine.alpha' : 'com.microsoft.playready';
1271
1259
  const VALID_METHODS = ['SAMPLE-AES', 'SAMPLE-AES-CTR', 'SAMPLE-AES-CENC'];
1272
1260
 
1273
1261
  if (VALID_METHODS.indexOf(entry.attributes.METHOD) === -1) {
1274
1262
  this.trigger('warn', {
1275
- message: 'invalid key method provided for Widevine'
1263
+ message: `invalid key method provided for ${protectionSystem}`
1276
1264
  });
1277
1265
  return;
1278
1266
  }
@@ -1285,26 +1273,28 @@
1285
1273
 
1286
1274
  if (entry.attributes.URI.substring(0, 23) !== 'data:text/plain;base64,') {
1287
1275
  this.trigger('warn', {
1288
- message: 'invalid key URI provided for Widevine'
1276
+ message: `invalid key URI provided for ${protectionSystem}`
1289
1277
  });
1290
1278
  return;
1291
1279
  }
1292
1280
 
1293
1281
  if (!(entry.attributes.KEYID && entry.attributes.KEYID.substring(0, 2) === '0x')) {
1294
1282
  this.trigger('warn', {
1295
- message: 'invalid key ID provided for Widevine'
1283
+ message: `invalid key ID provided for ${protectionSystem}`
1296
1284
  });
1297
1285
  return;
1298
- } // if Widevine key attributes are valid, store them as `contentProtection`
1299
- // on the manifest to emulate Widevine tag structure in a DASH mpd
1286
+ } // if key attributes are valid, store them as `contentProtection`
1287
+ // on the manifest to emulate tag structure in a DASH mpd
1300
1288
 
1301
1289
 
1302
1290
  this.manifest.contentProtection = this.manifest.contentProtection || {};
1303
- this.manifest.contentProtection['com.widevine.alpha'] = {
1291
+ this.manifest.contentProtection[protectionSystem] = {
1304
1292
  attributes: {
1305
1293
  schemeIdUri: entry.attributes.KEYFORMAT,
1306
1294
  // remove '0x' from the key id string
1307
- keyId: entry.attributes.KEYID.substring(2)
1295
+ keyId: entry.attributes.KEYID.substring(2),
1296
+ method: entry.attributes.METHOD,
1297
+ iv: entry.attributes.IV
1308
1298
  },
1309
1299
  // decode the base64-encoded PSSH box
1310
1300
  pssh: decodeB64ToUint8Array(entry.attributes.URI.split(',')[1])
@@ -1,2 +1,2 @@
1
- /*! @name @transmitlive/m3u8-parser @version 7.1.0-2 @license Apache-2.0 */
2
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).m3u8Parser={})}(this,(function(t){"use strict";var e=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,a=0;a<i;++a)e[a].call(this,arguments[1]);else for(var s=Array.prototype.slice.call(arguments,1),r=e.length,n=0;n<r;++n)e[n].apply(this,s)},e.dispose=function(){this.listeners={}},e.pipe=function(t){this.on("data",(function(e){t.push(e)}))},t}();class i extends e{constructor(){super(),this.buffer=""}push(t){let 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)}}function a(){return s=a=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var i=arguments[e];for(var a in i)Object.prototype.hasOwnProperty.call(i,a)&&(t[a]=i[a])}return t},a.apply(this,arguments)}var s=a,r=s;const n=String.fromCharCode(9),u=function(t){const 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},o=function(t){const e=t.split(new RegExp('(?:^|,)((?:[^=]*)=(?:"[^"]*"|[^,]*))')),i={};let a,s=e.length;for(;s--;)""!==e[s]&&(a=/([^=]*)=(.*)/.exec(e[s]).slice(1),a[0]=a[0].replace(/^\s+|\s+$/g,""),a[1]=a[1].replace(/^\s+|\s+$/g,""),a[1]=a[1].replace(/^['"](.*)['"]$/g,"$1"),i[a[0]]=a[1]);return i};class g extends e{constructor(){super(),this.customParsers=[],this.tagMappers=[],this.lineNumber=0}push(t){let e,i;if(this.lineNumber=this.lineNumber+1,0===(t=t.trim()).length)return;if("#"!==t[0])return void this.trigger("data",{type:"uri",uri:t});this.tagMappers.reduce(((e,i)=>{const a=i(t);return a===t?e:e.concat([a])}),[t]).forEach((t=>{for(let e=0;e<this.customParsers.length;e++)if(this.customParsers[e].call(this,t))return;if(0===t.indexOf("#EXT"))if(t=t.replace("\r",""),e=/^#EXTM3U/.exec(t),e)this.trigger("data",{type:"tag",tagType:"m3u"});else{if(e=/^#EXTINF:?([0-9\.]*)?,?(.*)?$/.exec(t),e)return i={type:"tag",tagType:"inf"},e[1]&&(i.duration=parseFloat(e[1])),e[2]&&(i.title=e[2]),void this.trigger("data",i);if(e=/^#EXT-X-TARGETDURATION:?([0-9.]*)?/.exec(t),e)return i={type:"tag",tagType:"targetduration"},e[1]&&(i.duration=parseInt(e[1],10)),void this.trigger("data",i);if(e=/^#EXT-X-VERSION:?([0-9.]*)?/.exec(t),e)return i={type:"tag",tagType:"version"},e[1]&&(i.version=parseInt(e[1],10)),void this.trigger("data",i);if(e=/^#EXT-X-MEDIA-SEQUENCE:?(\-?[0-9.]*)?/.exec(t),e)return i={type:"tag",tagType:"media-sequence"},e[1]&&(i.number=parseInt(e[1],10)),void this.trigger("data",i);if(e=/^#EXT-X-DISCONTINUITY-SEQUENCE:?(\-?[0-9.]*)?/.exec(t),e)return i={type:"tag",tagType:"discontinuity-sequence"},e[1]&&(i.number=parseInt(e[1],10)),void this.trigger("data",i);if(e=/^#EXT-X-PLAYLIST-TYPE:?(.*)?$/.exec(t),e)return i={type:"tag",tagType:"playlist-type"},e[1]&&(i.playlistType=e[1]),void this.trigger("data",i);if(e=/^#EXT-X-BYTERANGE:?(.*)?$/.exec(t),e)return i=r(u(e[1]),{type:"tag",tagType:"byterange"}),void this.trigger("data",i);if(e=/^#EXT-X-ALLOW-CACHE:?(YES|NO)?/.exec(t),e)return i={type:"tag",tagType:"allow-cache"},e[1]&&(i.allowed=!/NO/.test(e[1])),void this.trigger("data",i);if(e=/^#EXT-X-MAP:?(.*)$/.exec(t),e){if(i={type:"tag",tagType:"map"},e[1]){const t=o(e[1]);t.URI&&(i.uri=t.URI),t.BYTERANGE&&(i.byterange=u(t.BYTERANGE))}this.trigger("data",i)}else if(e=/^#EXT-X-STREAM-INF:?(.*)$/.exec(t),e){if(i={type:"tag",tagType:"stream-inf"},e[1]){if(i.attributes=o(e[1]),i.attributes.RESOLUTION){const t=i.attributes.RESOLUTION.split("x"),e={};t[0]&&(e.width=parseInt(t[0],10)),t[1]&&(e.height=parseInt(t[1],10)),i.attributes.RESOLUTION=e}i.attributes.BANDWIDTH&&(i.attributes.BANDWIDTH=parseInt(i.attributes.BANDWIDTH,10)),i.attributes["FRAME-RATE"]&&(i.attributes["FRAME-RATE"]=parseFloat(i.attributes["FRAME-RATE"])),i.attributes["PROGRAM-ID"]&&(i.attributes["PROGRAM-ID"]=parseInt(i.attributes["PROGRAM-ID"],10))}this.trigger("data",i)}else{if(e=/^#EXT-X-MEDIA:?(.*)$/.exec(t),e)return i={type:"tag",tagType:"media"},e[1]&&(i.attributes=o(e[1])),void this.trigger("data",i);if(e=/^#EXT-X-ENDLIST/.exec(t),e)this.trigger("data",{type:"tag",tagType:"endlist"});else if(e=/^#EXT-X-DISCONTINUITY/.exec(t),e)this.trigger("data",{type:"tag",tagType:"discontinuity"});else{if(e=/^#EXT-X-PROGRAM-DATE-TIME:?(.*)$/.exec(t),e)return i={type:"tag",tagType:"program-date-time"},e[1]&&(i.dateTimeString=e[1],i.dateTimeObject=new Date(e[1])),void this.trigger("data",i);if(e=/^#EXT-X-KEY:?(.*)$/.exec(t),e)return i={type:"tag",tagType:"key"},e[1]&&(i.attributes=o(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 this.trigger("data",i);if(e=/^#EXT-X-START:?(.*)$/.exec(t),e)return i={type:"tag",tagType:"start"},e[1]&&(i.attributes=o(e[1]),i.attributes["TIME-OFFSET"]=parseFloat(i.attributes["TIME-OFFSET"]),i.attributes.PRECISE=/YES/.test(i.attributes.PRECISE)),void this.trigger("data",i);if(e=/^#EXT-X-CUE-OUT-CONT:?(.*)?$/.exec(t),e)return i={type:"tag",tagType:"cue-out-cont"},e[1]?i.data=e[1]:i.data="",void this.trigger("data",i);if(e=/^#EXT-X-CUE-OUT:?(.*)?$/.exec(t),e)return i={type:"tag",tagType:"cue-out"},e[1]?i.data=e[1]:i.data="",void this.trigger("data",i);if(e=/^#EXT-X-CUE-IN:?(.*)?$/.exec(t),e)return i={type:"tag",tagType:"cue-in"},e[1]?i.data=e[1]:i.data="",void this.trigger("data",i);if(e=/^#EXT-X-SKIP:(.*)$/.exec(t),e&&e[1])return i={type:"tag",tagType:"skip"},i.attributes=o(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(n)),void this.trigger("data",i);if(e=/^#EXT-X-PART:(.*)$/.exec(t),e&&e[1])return i={type:"tag",tagType:"part"},i.attributes=o(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=u(i.attributes.BYTERANGE)),void this.trigger("data",i);if(e=/^#EXT-X-SERVER-CONTROL:(.*)$/.exec(t),e&&e[1])return i={type:"tag",tagType:"server-control"},i.attributes=o(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 this.trigger("data",i);if(e=/^#EXT-X-PART-INF:(.*)$/.exec(t),e&&e[1])return i={type:"tag",tagType:"part-inf"},i.attributes=o(e[1]),["PART-TARGET"].forEach((function(t){i.attributes.hasOwnProperty(t)&&(i.attributes[t]=parseFloat(i.attributes[t]))})),void this.trigger("data",i);if(e=/^#EXT-X-PRELOAD-HINT:(.*)$/.exec(t),e&&e[1])return i={type:"tag",tagType:"preload-hint"},i.attributes=o(e[1]),["BYTERANGE-START","BYTERANGE-LENGTH"].forEach((function(t){if(i.attributes.hasOwnProperty(t)){i.attributes[t]=parseInt(i.attributes[t],10);const e="BYTERANGE-LENGTH"===t?"length":"offset";i.attributes.byterange=i.attributes.byterange||{},i.attributes.byterange[e]=i.attributes[t],delete i.attributes[t]}})),void this.trigger("data",i);if(e=/^#EXT-X-RENDITION-REPORT:(.*)$/.exec(t),e&&e[1])return i={type:"tag",tagType:"rendition-report"},i.attributes=o(e[1]),["LAST-MSN","LAST-PART"].forEach((function(t){i.attributes.hasOwnProperty(t)&&(i.attributes[t]=parseInt(i.attributes[t],10))})),void this.trigger("data",i);if(e=/^#EXT-X-DATERANGE:(.*)$/.exec(t),e&&e[1]){i={type:"tag",tagType:"daterange"},i.attributes=o(e[1]),["ID","CLASS"].forEach((function(t){i.attributes.hasOwnProperty(t)&&(i.attributes[t]=String(i.attributes[t]))})),["START-DATE","END-DATE"].forEach((function(t){i.attributes.hasOwnProperty(t)&&(i.attributes[t]=new Date(i.attributes[t]))})),["DURATION","PLANNED-DURATION"].forEach((function(t){i.attributes.hasOwnProperty(t)&&(i.attributes[t]=parseFloat(i.attributes[t]))})),["END-ON-NEXT"].forEach((function(t){i.attributes.hasOwnProperty(t)&&(i.attributes[t]=/YES/i.test(i.attributes[t]))})),["SCTE35-CMD"," SCTE35-OUT","SCTE35-IN"].forEach((function(t){i.attributes.hasOwnProperty(t)&&(i.attributes[t]=i.attributes[t].toString(16))}));const t=/^X-([A-Z]+-)+[A-Z]+$/;for(const e in i.attributes){if(!t.test(e))continue;const a=/[0-9A-Fa-f]{6}/g.test(i.attributes[e]),s=/^\d+(\.\d+)?$/.test(i.attributes[e]);i.attributes[e]=a?i.attributes[e].toString(16):s?parseFloat(i.attributes[e]):String(i.attributes[e])}this.trigger("data",i)}else if(e=/^#EXT-X-INDEPENDENT-SEGMENTS/.exec(t),e)this.trigger("data",{type:"tag",tagType:"independent-segments"});else{if(e=/^#EXT-X-CONTENT-STEERING:(.*)$/.exec(t),e)return i={type:"tag",tagType:"content-steering"},i.attributes=o(e[1]),void this.trigger("data",i);this.trigger("data",{type:"tag",data:t.slice(4)})}}}}else this.trigger("data",{type:"comment",text:t.slice(1)})}))}addParser({expression:t,customType:e,dataParser:i,segment:a}){"function"!=typeof i&&(i=t=>t),this.customParsers.push((s=>{if(t.exec(s))return this.trigger("data",{type:"custom",data:i(s),customType:e,segment:a}),!0}))}addTagMapper({expression:t,map:e}){this.tagMappers.push((i=>t.test(i)?e(i):i))}}function h(t){for(var e,i=(e=t,window.atob?window.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}const d=function(t){const e={};return Object.keys(t).forEach((function(i){var a;e[(a=i,a.toLowerCase().replace(/-(\w)/g,(t=>t[1].toUpperCase())))]=t[i]})),e},p=function(t){const{serverControl:e,targetDuration:i,partTargetDuration:a}=t;if(!e)return;const s="#EXT-X-SERVER-CONTROL",r="holdBack",n="partHoldBack",u=i&&3*i,o=a&&2*a;i&&!e.hasOwnProperty(r)&&(e[r]=u,this.trigger("info",{message:`${s} defaulting HOLD-BACK to targetDuration * 3 (${u}).`})),u&&e[r]<u&&(this.trigger("warn",{message:`${s} clamping HOLD-BACK (${e[r]}) to targetDuration * 3 (${u})`}),e[r]=u),a&&!e.hasOwnProperty(n)&&(e[n]=3*a,this.trigger("info",{message:`${s} defaulting PART-HOLD-BACK to partTargetDuration * 3 (${e[n]}).`})),a&&e[n]<o&&(this.trigger("warn",{message:`${s} clamping PART-HOLD-BACK (${e[n]}) to partTargetDuration * 2 (${o}).`}),e[n]=o)};t.LineStream=i,t.ParseStream=g,t.Parser=class extends e{constructor(){super(),this.lineStream=new i,this.parseStream=new g,this.lineStream.pipe(this.parseStream),this.lastProgramDateTime=null;const t=this,e=[];let a,s,n={},u=!1;const o=function(){},E={AUDIO:{},VIDEO:{},"CLOSED-CAPTIONS":{},SUBTITLES:{}};let f=0;this.manifest={allowCache:!0,discontinuityStarts:[],dateRanges:[],segments:[]};let T=0,c=0;const m={};let l=0;this.on("end",(()=>{n.uri||!n.parts&&!n.preloadHints||(!n.map&&a&&(n.map=a),!n.key&&s&&(n.key=s),n.timeline||"number"!=typeof f||(n.timeline=f),this.manifest.preloadSegment=n)})),this.parseStream.on("data",(function(i){let g,b;Object.keys(n).length||(l=this.lineNumber),{tag(){({version(){i.version&&(this.manifest.version=i.version)},"allow-cache"(){this.manifest.allowCache=i.allowed,"allowed"in i||(this.trigger("info",{message:"defaulting allowCache to YES"}),this.manifest.allowCache=!0)},byterange(){const t={};"length"in i&&(n.byterange=t,t.length=i.length,"offset"in i||(i.offset=T)),"offset"in i&&(n.byterange=t,t.offset=i.offset),T=t.offset+t.length},endlist(){this.manifest.endList=!0},inf(){"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"})),i.title&&(n.title=i.title),i.duration>0&&(n.duration=i.duration),0===i.duration&&(n.duration=.01,this.trigger("info",{message:"updating zero segment duration to a small value"})),this.manifest.segments=e},key(){if(i.attributes)if("NONE"!==i.attributes.METHOD)if(i.attributes.URI){if("com.apple.streamingkeydelivery"===i.attributes.KEYFORMAT)return this.manifest.contentProtection=this.manifest.contentProtection||{},void(this.manifest.contentProtection["com.apple.fps.1_0"]={attributes:i.attributes});if("com.microsoft.playready"===i.attributes.KEYFORMAT)return this.manifest.contentProtection=this.manifest.contentProtection||{},void(this.manifest.contentProtection["com.microsoft.playready"]={uri:i.attributes.URI});if("urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"===i.attributes.KEYFORMAT){return-1===["SAMPLE-AES","SAMPLE-AES-CTR","SAMPLE-AES-CENC"].indexOf(i.attributes.METHOD)?void this.trigger("warn",{message:"invalid key method provided for Widevine"}):("SAMPLE-AES-CENC"===i.attributes.METHOD&&this.trigger("warn",{message:"SAMPLE-AES-CENC is deprecated, please use SAMPLE-AES-CTR instead"}),"data:text/plain;base64,"!==i.attributes.URI.substring(0,23)?void this.trigger("warn",{message:"invalid key URI provided for Widevine"}):i.attributes.KEYID&&"0x"===i.attributes.KEYID.substring(0,2)?(this.manifest.contentProtection=this.manifest.contentProtection||{},void(this.manifest.contentProtection["com.widevine.alpha"]={attributes:{schemeIdUri:i.attributes.KEYFORMAT,keyId:i.attributes.KEYID.substring(2)},pssh:h(i.attributes.URI.split(",")[1])})):void this.trigger("warn",{message:"invalid key ID provided for Widevine"}))}i.attributes.METHOD||this.trigger("warn",{message:"defaulting key method to AES-128"}),s={method:i.attributes.METHOD||"AES-128",uri:i.attributes.URI},void 0!==i.attributes.IV&&(s.iv=i.attributes.IV)}else this.trigger("warn",{message:"ignoring key declaration without URI"});else s=null;else this.trigger("warn",{message:"ignoring key declaration without attribute list"})},"media-sequence"(){isFinite(i.number)?this.manifest.mediaSequence=i.number:this.trigger("warn",{message:"ignoring invalid media sequence: "+i.number})},"discontinuity-sequence"(){isFinite(i.number)?(this.manifest.discontinuitySequence=i.number,f=i.number):this.trigger("warn",{message:"ignoring invalid discontinuity sequence: "+i.number})},"playlist-type"(){/VOD|EVENT/.test(i.playlistType)?this.manifest.playlistType=i.playlistType:this.trigger("warn",{message:"ignoring unknown playlist type: "+i.playlist})},map(){a={},i.uri&&(a.uri=i.uri),i.byterange&&(a.byterange=i.byterange),s&&(a.key=s)},"stream-inf"(){this.manifest.playlists=e,this.manifest.mediaGroups=this.manifest.mediaGroups||E,i.attributes?(n.attributes||(n.attributes={}),r(n.attributes,i.attributes)):this.trigger("warn",{message:"ignoring empty stream-inf attributes"})},media(){if(this.manifest.mediaGroups=this.manifest.mediaGroups||E,!(i.attributes&&i.attributes.TYPE&&i.attributes["GROUP-ID"]&&i.attributes.NAME))return void this.trigger("warn",{message:"ignoring incomplete or missing media group"});const t=this.manifest.mediaGroups[i.attributes.TYPE];t[i.attributes["GROUP-ID"]]=t[i.attributes["GROUP-ID"]]||{},g=t[i.attributes["GROUP-ID"]],b={default:/yes/i.test(i.attributes.DEFAULT)},b.default?b.autoselect=!0:b.autoselect=/yes/i.test(i.attributes.AUTOSELECT),i.attributes.LANGUAGE&&(b.language=i.attributes.LANGUAGE),i.attributes.URI&&(b.uri=i.attributes.URI),i.attributes["INSTREAM-ID"]&&(b.instreamId=i.attributes["INSTREAM-ID"]),i.attributes.CHARACTERISTICS&&(b.characteristics=i.attributes.CHARACTERISTICS),i.attributes.FORCED&&(b.forced=/yes/i.test(i.attributes.FORCED)),g[i.attributes.NAME]=b},discontinuity(){f+=1,n.discontinuity=!0,this.manifest.discontinuityStarts.push(e.length)},"program-date-time"(){void 0===this.manifest.dateTimeString&&(this.manifest.dateTimeString=i.dateTimeString,this.manifest.dateTimeObject=i.dateTimeObject),n.dateTimeString=i.dateTimeString,n.dateTimeObject=i.dateTimeObject;const{lastProgramDateTime:t}=this;this.lastProgramDateTime=new Date(i.dateTimeString).getTime(),null===t&&this.manifest.segments.reduceRight(((t,e)=>(e.programDateTime=t-1e3*e.duration,e.programDateTime)),this.lastProgramDateTime)},targetduration(){!isFinite(i.duration)||i.duration<0?this.trigger("warn",{message:"ignoring invalid target duration: "+i.duration}):(this.manifest.targetDuration=i.duration,p.call(this,this.manifest))},start(){i.attributes&&!isNaN(i.attributes["TIME-OFFSET"])?this.manifest.start={timeOffset:i.attributes["TIME-OFFSET"],precise:i.attributes.PRECISE}:this.trigger("warn",{message:"ignoring start declaration without appropriate attribute list"})},"cue-out"(){n.cueOut=i.data},"cue-out-cont"(){n.cueOutCont=i.data},"cue-in"(){n.cueIn=i.data},skip(){this.manifest.skip=d(i.attributes),this.warnOnMissingAttributes_("#EXT-X-SKIP",i.attributes,["SKIPPED-SEGMENTS"])},part(){u=!0;const t=this.manifest.segments.length,e=d(i.attributes);n.parts=n.parts||[],n.parts.push(e),e.byterange&&(e.byterange.hasOwnProperty("offset")||(e.byterange.offset=c),c=e.byterange.offset+e.byterange.length);const a=n.parts.length-1;this.warnOnMissingAttributes_(`#EXT-X-PART #${a} for segment #${t}`,i.attributes,["URI","DURATION"]),this.manifest.renditionReports&&this.manifest.renditionReports.forEach(((t,e)=>{t.hasOwnProperty("lastPart")||this.trigger("warn",{message:`#EXT-X-RENDITION-REPORT #${e} lacks required attribute(s): LAST-PART`})}))},"server-control"(){const t=this.manifest.serverControl=d(i.attributes);t.hasOwnProperty("canBlockReload")||(t.canBlockReload=!1,this.trigger("info",{message:"#EXT-X-SERVER-CONTROL defaulting CAN-BLOCK-RELOAD to false"})),p.call(this,this.manifest),t.canSkipDateranges&&!t.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"(){const t=this.manifest.segments.length,e=d(i.attributes),a=e.type&&"PART"===e.type;n.preloadHints=n.preloadHints||[],n.preloadHints.push(e),e.byterange&&(e.byterange.hasOwnProperty("offset")||(e.byterange.offset=a?c:0,a&&(c=e.byterange.offset+e.byterange.length)));const s=n.preloadHints.length-1;if(this.warnOnMissingAttributes_(`#EXT-X-PRELOAD-HINT #${s} for segment #${t}`,i.attributes,["TYPE","URI"]),e.type)for(let i=0;i<n.preloadHints.length-1;i++){const a=n.preloadHints[i];a.type&&(a.type===e.type&&this.trigger("warn",{message:`#EXT-X-PRELOAD-HINT #${s} for segment #${t} has the same TYPE ${e.type} as preload hint #${i}`}))}},"rendition-report"(){const t=d(i.attributes);this.manifest.renditionReports=this.manifest.renditionReports||[],this.manifest.renditionReports.push(t);const e=this.manifest.renditionReports.length-1,a=["LAST-MSN","URI"];u&&a.push("LAST-PART"),this.warnOnMissingAttributes_(`#EXT-X-RENDITION-REPORT #${e}`,i.attributes,a)},"part-inf"(){this.manifest.partInf=d(i.attributes),this.warnOnMissingAttributes_("#EXT-X-PART-INF",i.attributes,["PART-TARGET"]),this.manifest.partInf.partTarget&&(this.manifest.partTargetDuration=this.manifest.partInf.partTarget),p.call(this,this.manifest)},daterange(){this.manifest.dateRanges.push(d(i.attributes));const t=this.manifest.dateRanges.length-1;this.warnOnMissingAttributes_(`#EXT-X-DATERANGE #${t}`,i.attributes,["ID","START-DATE"]);const e=this.manifest.dateRanges[t];e.endDate&&e.startDate&&new Date(e.endDate)<new Date(e.startDate)&&this.trigger("warn",{message:"EXT-X-DATERANGE END-DATE must be equal to or later than the value of the START-DATE"}),e.duration&&e.duration<0&&this.trigger("warn",{message:"EXT-X-DATERANGE DURATION must not be negative"}),e.plannedDuration&&e.plannedDuration<0&&this.trigger("warn",{message:"EXT-X-DATERANGE PLANNED-DURATION must not be negative"});const a=!!e.endOnNext;if(a&&!e.class&&this.trigger("warn",{message:"EXT-X-DATERANGE with an END-ON-NEXT=YES attribute must have a CLASS attribute"}),a&&(e.duration||e.endDate)&&this.trigger("warn",{message:"EXT-X-DATERANGE with an END-ON-NEXT=YES attribute must not contain DURATION or END-DATE attributes"}),e.duration&&e.endDate){const i=e.startDate.getTime()+1e3*e.duration;this.manifest.dateRanges[t].endDate=new Date(i)}if(m[e.id]){for(const t in m[e.id])if(e[t]&&JSON.stringify(m[e.id][t])!==JSON.stringify(e[t])){this.trigger("warn",{message:"EXT-X-DATERANGE tags with the same ID in a playlist must have the same attributes values"});break}const t=this.manifest.dateRanges.findIndex((t=>t.id===e.id));this.manifest.dateRanges[t]=r(this.manifest.dateRanges[t],e),m[e.id]=r(m[e.id],e),this.manifest.dateRanges.pop()}else m[e.id]=e},"independent-segments"(){this.manifest.independentSegments=!0},"content-steering"(){this.manifest.contentSteering=d(i.attributes),this.warnOnMissingAttributes_("#EXT-X-CONTENT-STEERING",i.attributes,["SERVER-URI"])}}[i.tagType]||o).call(t)},uri(){n.uri=i.uri,n.lineNumberStart=l,n.lineNumberEnd=this.parseStream.lineNumber,e.push(n),this.manifest.targetDuration&&!("duration"in n)&&(this.trigger("warn",{message:"defaulting segment duration to the target duration"}),n.duration=this.manifest.targetDuration),s&&(n.key=s),n.timeline=f,a&&(n.map=a),c=0,null!==this.lastProgramDateTime&&(n.programDateTime=this.lastProgramDateTime,this.lastProgramDateTime+=1e3*n.duration),n={}},comment(){},custom(){i.segment?(n.custom=n.custom||{},n.custom[i.customType]=i.data):(this.manifest.custom=this.manifest.custom||{},this.manifest.custom[i.customType]=i.data)}}[i.type].call(t)}))}warnOnMissingAttributes_(t,e,i){const a=[];i.forEach((function(t){e.hasOwnProperty(t)||a.push(t)})),a.length&&this.trigger("warn",{message:`${t} lacks required attribute(s): ${a.join(", ")}`})}push(t){this.lineStream.push(t)}end(){this.lineStream.push("\n"),this.manifest.dateRanges.length&&null===this.lastProgramDateTime&&this.trigger("warn",{message:"A playlist with EXT-X-DATERANGE tag must contain atleast one EXT-X-PROGRAM-DATE-TIME tag"}),this.lastProgramDateTime=null,this.trigger("end")}addParser(t){this.parseStream.addParser(t)}addTagMapper(t){this.parseStream.addTagMapper(t)}},Object.defineProperty(t,"__esModule",{value:!0})}));
1
+ /*! @name @transmitlive/m3u8-parser @version 7.1.0-4 @license Apache-2.0 */
2
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).m3u8Parser={})}(this,(function(t){"use strict";var e=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,a=0;a<i;++a)e[a].call(this,arguments[1]);else for(var s=Array.prototype.slice.call(arguments,1),r=e.length,n=0;n<r;++n)e[n].apply(this,s)},e.dispose=function(){this.listeners={}},e.pipe=function(t){this.on("data",(function(e){t.push(e)}))},t}();class i extends e{constructor(){super(),this.buffer=""}push(t){let 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)}}function a(){return s=a=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var i=arguments[e];for(var a in i)Object.prototype.hasOwnProperty.call(i,a)&&(t[a]=i[a])}return t},a.apply(this,arguments)}var s=a,r=s;const n=String.fromCharCode(9),u=function(t){const 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},o=function(t){const e=t.split(new RegExp('(?:^|,)((?:[^=]*)=(?:"[^"]*"|[^,]*))')),i={};let a,s=e.length;for(;s--;)""!==e[s]&&(a=/([^=]*)=(.*)/.exec(e[s]).slice(1),a[0]=a[0].replace(/^\s+|\s+$/g,""),a[1]=a[1].replace(/^\s+|\s+$/g,""),a[1]=a[1].replace(/^['"](.*)['"]$/g,"$1"),i[a[0]]=a[1]);return i};class g extends e{constructor(){super(),this.customParsers=[],this.tagMappers=[],this.lineNumber=0}push(t){let e,i;if(this.lineNumber=this.lineNumber+1,0===(t=t.trim()).length)return;if("#"!==t[0])return void this.trigger("data",{type:"uri",uri:t});this.tagMappers.reduce(((e,i)=>{const a=i(t);return a===t?e:e.concat([a])}),[t]).forEach((t=>{for(let e=0;e<this.customParsers.length;e++)if(this.customParsers[e].call(this,t))return;if(0===t.indexOf("#EXT"))if(t=t.replace("\r",""),e=/^#EXTM3U/.exec(t),e)this.trigger("data",{type:"tag",tagType:"m3u"});else{if(e=/^#EXTINF:?([0-9\.]*)?,?(.*)?$/.exec(t),e)return i={type:"tag",tagType:"inf"},e[1]&&(i.duration=parseFloat(e[1])),e[2]&&(i.title=e[2]),void this.trigger("data",i);if(e=/^#EXT-X-TARGETDURATION:?([0-9.]*)?/.exec(t),e)return i={type:"tag",tagType:"targetduration"},e[1]&&(i.duration=parseInt(e[1],10)),void this.trigger("data",i);if(e=/^#EXT-X-VERSION:?([0-9.]*)?/.exec(t),e)return i={type:"tag",tagType:"version"},e[1]&&(i.version=parseInt(e[1],10)),void this.trigger("data",i);if(e=/^#EXT-X-MEDIA-SEQUENCE:?(\-?[0-9.]*)?/.exec(t),e)return i={type:"tag",tagType:"media-sequence"},e[1]&&(i.number=parseInt(e[1],10)),void this.trigger("data",i);if(e=/^#EXT-X-DISCONTINUITY-SEQUENCE:?(\-?[0-9.]*)?/.exec(t),e)return i={type:"tag",tagType:"discontinuity-sequence"},e[1]&&(i.number=parseInt(e[1],10)),void this.trigger("data",i);if(e=/^#EXT-X-PLAYLIST-TYPE:?(.*)?$/.exec(t),e)return i={type:"tag",tagType:"playlist-type"},e[1]&&(i.playlistType=e[1]),void this.trigger("data",i);if(e=/^#EXT-X-BYTERANGE:?(.*)?$/.exec(t),e)return i=r(u(e[1]),{type:"tag",tagType:"byterange"}),void this.trigger("data",i);if(e=/^#EXT-X-ALLOW-CACHE:?(YES|NO)?/.exec(t),e)return i={type:"tag",tagType:"allow-cache"},e[1]&&(i.allowed=!/NO/.test(e[1])),void this.trigger("data",i);if(e=/^#EXT-X-MAP:?(.*)$/.exec(t),e){if(i={type:"tag",tagType:"map"},e[1]){const t=o(e[1]);t.URI&&(i.uri=t.URI),t.BYTERANGE&&(i.byterange=u(t.BYTERANGE))}this.trigger("data",i)}else if(e=/^#EXT-X-STREAM-INF:?(.*)$/.exec(t),e){if(i={type:"tag",tagType:"stream-inf"},e[1]){if(i.attributes=o(e[1]),i.attributes.RESOLUTION){const t=i.attributes.RESOLUTION.split("x"),e={};t[0]&&(e.width=parseInt(t[0],10)),t[1]&&(e.height=parseInt(t[1],10)),i.attributes.RESOLUTION=e}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))}this.trigger("data",i)}else{if(e=/^#EXT-X-MEDIA:?(.*)$/.exec(t),e)return i={type:"tag",tagType:"media"},e[1]&&(i.attributes=o(e[1])),void this.trigger("data",i);if(e=/^#EXT-X-ENDLIST/.exec(t),e)this.trigger("data",{type:"tag",tagType:"endlist"});else if(e=/^#EXT-X-DISCONTINUITY/.exec(t),e)this.trigger("data",{type:"tag",tagType:"discontinuity"});else{if(e=/^#EXT-X-PROGRAM-DATE-TIME:?(.*)$/.exec(t),e)return i={type:"tag",tagType:"program-date-time"},e[1]&&(i.dateTimeString=e[1],i.dateTimeObject=new Date(e[1])),void this.trigger("data",i);if(e=/^#EXT-X-KEY:?(.*)$/.exec(t),e)return i={type:"tag",tagType:"key"},e[1]&&(i.attributes=o(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 this.trigger("data",i);if(e=/^#EXT-X-START:?(.*)$/.exec(t),e)return i={type:"tag",tagType:"start"},e[1]&&(i.attributes=o(e[1]),i.attributes["TIME-OFFSET"]=parseFloat(i.attributes["TIME-OFFSET"]),i.attributes.PRECISE=/YES/.test(i.attributes.PRECISE)),void this.trigger("data",i);if(e=/^#EXT-X-CUE-OUT-CONT:?(.*)?$/.exec(t),e)return i={type:"tag",tagType:"cue-out-cont"},e[1]?i.data=e[1]:i.data="",void this.trigger("data",i);if(e=/^#EXT-X-CUE-OUT:?(.*)?$/.exec(t),e)return i={type:"tag",tagType:"cue-out"},e[1]?i.data=e[1]:i.data="",void this.trigger("data",i);if(e=/^#EXT-X-CUE-IN:?(.*)?$/.exec(t),e)return i={type:"tag",tagType:"cue-in"},e[1]?i.data=e[1]:i.data="",void this.trigger("data",i);if(e=/^#EXT-X-SKIP:(.*)$/.exec(t),e&&e[1])return i={type:"tag",tagType:"skip"},i.attributes=o(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(n)),void this.trigger("data",i);if(e=/^#EXT-X-PART:(.*)$/.exec(t),e&&e[1])return i={type:"tag",tagType:"part"},i.attributes=o(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=u(i.attributes.BYTERANGE)),void this.trigger("data",i);if(e=/^#EXT-X-SERVER-CONTROL:(.*)$/.exec(t),e&&e[1])return i={type:"tag",tagType:"server-control"},i.attributes=o(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 this.trigger("data",i);if(e=/^#EXT-X-PART-INF:(.*)$/.exec(t),e&&e[1])return i={type:"tag",tagType:"part-inf"},i.attributes=o(e[1]),["PART-TARGET"].forEach((function(t){i.attributes.hasOwnProperty(t)&&(i.attributes[t]=parseFloat(i.attributes[t]))})),void this.trigger("data",i);if(e=/^#EXT-X-PRELOAD-HINT:(.*)$/.exec(t),e&&e[1])return i={type:"tag",tagType:"preload-hint"},i.attributes=o(e[1]),["BYTERANGE-START","BYTERANGE-LENGTH"].forEach((function(t){if(i.attributes.hasOwnProperty(t)){i.attributes[t]=parseInt(i.attributes[t],10);const e="BYTERANGE-LENGTH"===t?"length":"offset";i.attributes.byterange=i.attributes.byterange||{},i.attributes.byterange[e]=i.attributes[t],delete i.attributes[t]}})),void this.trigger("data",i);if(e=/^#EXT-X-RENDITION-REPORT:(.*)$/.exec(t),e&&e[1])return i={type:"tag",tagType:"rendition-report"},i.attributes=o(e[1]),["LAST-MSN","LAST-PART"].forEach((function(t){i.attributes.hasOwnProperty(t)&&(i.attributes[t]=parseInt(i.attributes[t],10))})),void this.trigger("data",i);if(e=/^#EXT-X-DATERANGE:(.*)$/.exec(t),e&&e[1]){i={type:"tag",tagType:"daterange"},i.attributes=o(e[1]),["ID","CLASS"].forEach((function(t){i.attributes.hasOwnProperty(t)&&(i.attributes[t]=String(i.attributes[t]))})),["START-DATE","END-DATE"].forEach((function(t){i.attributes.hasOwnProperty(t)&&(i.attributes[t]=new Date(i.attributes[t]))})),["DURATION","PLANNED-DURATION"].forEach((function(t){i.attributes.hasOwnProperty(t)&&(i.attributes[t]=parseFloat(i.attributes[t]))})),["END-ON-NEXT"].forEach((function(t){i.attributes.hasOwnProperty(t)&&(i.attributes[t]=/YES/i.test(i.attributes[t]))})),["SCTE35-CMD"," SCTE35-OUT","SCTE35-IN"].forEach((function(t){i.attributes.hasOwnProperty(t)&&(i.attributes[t]=i.attributes[t].toString(16))}));const t=/^X-([A-Z]+-)+[A-Z]+$/;for(const e in i.attributes){if(!t.test(e))continue;const a=/[0-9A-Fa-f]{6}/g.test(i.attributes[e]),s=/^\d+(\.\d+)?$/.test(i.attributes[e]);i.attributes[e]=a?i.attributes[e].toString(16):s?parseFloat(i.attributes[e]):String(i.attributes[e])}this.trigger("data",i)}else if(e=/^#EXT-X-INDEPENDENT-SEGMENTS/.exec(t),e)this.trigger("data",{type:"tag",tagType:"independent-segments"});else{if(e=/^#EXT-X-CONTENT-STEERING:(.*)$/.exec(t),e)return i={type:"tag",tagType:"content-steering"},i.attributes=o(e[1]),void this.trigger("data",i);this.trigger("data",{type:"tag",data:t.slice(4)})}}}}else this.trigger("data",{type:"comment",text:t.slice(1)})}))}addParser({expression:t,customType:e,dataParser:i,segment:a}){"function"!=typeof i&&(i=t=>t),this.customParsers.push((s=>{if(t.exec(s))return this.trigger("data",{type:"custom",data:i(s),customType:e,segment:a}),!0}))}addTagMapper({expression:t,map:e}){this.tagMappers.push((i=>t.test(i)?e(i):i))}}function h(t){for(var e,i=(e=t,window.atob?window.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}const d=function(t){const e={};return Object.keys(t).forEach((function(i){var a;e[(a=i,a.toLowerCase().replace(/-(\w)/g,(t=>t[1].toUpperCase())))]=t[i]})),e},p=function(t){const{serverControl:e,targetDuration:i,partTargetDuration:a}=t;if(!e)return;const s="#EXT-X-SERVER-CONTROL",r="holdBack",n="partHoldBack",u=i&&3*i,o=a&&2*a;i&&!e.hasOwnProperty(r)&&(e[r]=u,this.trigger("info",{message:`${s} defaulting HOLD-BACK to targetDuration * 3 (${u}).`})),u&&e[r]<u&&(this.trigger("warn",{message:`${s} clamping HOLD-BACK (${e[r]}) to targetDuration * 3 (${u})`}),e[r]=u),a&&!e.hasOwnProperty(n)&&(e[n]=3*a,this.trigger("info",{message:`${s} defaulting PART-HOLD-BACK to partTargetDuration * 3 (${e[n]}).`})),a&&e[n]<o&&(this.trigger("warn",{message:`${s} clamping PART-HOLD-BACK (${e[n]}) to partTargetDuration * 2 (${o}).`}),e[n]=o)};t.LineStream=i,t.ParseStream=g,t.Parser=class extends e{constructor(){super(),this.lineStream=new i,this.parseStream=new g,this.lineStream.pipe(this.parseStream),this.lastProgramDateTime=null;const t=this,e=[];let a,s,n={},u=!1;const o=function(){},E={AUDIO:{},VIDEO:{},"CLOSED-CAPTIONS":{},SUBTITLES:{}},T="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed";let f=0;this.manifest={allowCache:!0,discontinuityStarts:[],dateRanges:[],segments:[]};let c=0,m=0;const l={};let b=0;this.on("end",(()=>{n.uri||!n.parts&&!n.preloadHints||(!n.map&&a&&(n.map=a),!n.key&&s&&(n.key=s),n.timeline||"number"!=typeof f||(n.timeline=f),this.manifest.preloadSegment=n)})),this.parseStream.on("data",(function(i){let g,y;Object.keys(n).length||(b=this.lineNumber),{tag(){({version(){i.version&&(this.manifest.version=i.version)},"allow-cache"(){this.manifest.allowCache=i.allowed,"allowed"in i||(this.trigger("info",{message:"defaulting allowCache to YES"}),this.manifest.allowCache=!0)},byterange(){const t={};"length"in i&&(n.byterange=t,t.length=i.length,"offset"in i||(i.offset=c)),"offset"in i&&(n.byterange=t,t.offset=i.offset),c=t.offset+t.length},endlist(){this.manifest.endList=!0},inf(){"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"})),i.title&&(n.title=i.title),i.duration>0&&(n.duration=i.duration),0===i.duration&&(n.duration=.01,this.trigger("info",{message:"updating zero segment duration to a small value"})),this.manifest.segments=e},key(){if(i.attributes)if("NONE"!==i.attributes.METHOD)if(i.attributes.URI){if("com.apple.streamingkeydelivery"===i.attributes.KEYFORMAT)return this.manifest.contentProtection=this.manifest.contentProtection||{},void(this.manifest.contentProtection["com.apple.fps.1_0"]={attributes:i.attributes});if(i.attributes.KEYFORMAT===T||"com.microsoft.playready"===i.attributes.KEYFORMAT){const t=i.attributes.KEYFORMAT===T?"com.widevine.alpha":"com.microsoft.playready";return-1===["SAMPLE-AES","SAMPLE-AES-CTR","SAMPLE-AES-CENC"].indexOf(i.attributes.METHOD)?void this.trigger("warn",{message:`invalid key method provided for ${t}`}):("SAMPLE-AES-CENC"===i.attributes.METHOD&&this.trigger("warn",{message:"SAMPLE-AES-CENC is deprecated, please use SAMPLE-AES-CTR instead"}),"data:text/plain;base64,"!==i.attributes.URI.substring(0,23)?void this.trigger("warn",{message:`invalid key URI provided for ${t}`}):i.attributes.KEYID&&"0x"===i.attributes.KEYID.substring(0,2)?(this.manifest.contentProtection=this.manifest.contentProtection||{},void(this.manifest.contentProtection[t]={attributes:{schemeIdUri:i.attributes.KEYFORMAT,keyId:i.attributes.KEYID.substring(2),method:i.attributes.METHOD,iv:i.attributes.IV},pssh:h(i.attributes.URI.split(",")[1])})):void this.trigger("warn",{message:`invalid key ID provided for ${t}`}))}i.attributes.METHOD||this.trigger("warn",{message:"defaulting key method to AES-128"}),s={method:i.attributes.METHOD||"AES-128",uri:i.attributes.URI},void 0!==i.attributes.IV&&(s.iv=i.attributes.IV)}else this.trigger("warn",{message:"ignoring key declaration without URI"});else s=null;else this.trigger("warn",{message:"ignoring key declaration without attribute list"})},"media-sequence"(){isFinite(i.number)?this.manifest.mediaSequence=i.number:this.trigger("warn",{message:"ignoring invalid media sequence: "+i.number})},"discontinuity-sequence"(){isFinite(i.number)?(this.manifest.discontinuitySequence=i.number,f=i.number):this.trigger("warn",{message:"ignoring invalid discontinuity sequence: "+i.number})},"playlist-type"(){/VOD|EVENT/.test(i.playlistType)?this.manifest.playlistType=i.playlistType:this.trigger("warn",{message:"ignoring unknown playlist type: "+i.playlist})},map(){a={},i.uri&&(a.uri=i.uri),i.byterange&&(a.byterange=i.byterange),s&&(a.key=s)},"stream-inf"(){this.manifest.playlists=e,this.manifest.mediaGroups=this.manifest.mediaGroups||E,i.attributes?(n.attributes||(n.attributes={}),r(n.attributes,i.attributes)):this.trigger("warn",{message:"ignoring empty stream-inf attributes"})},media(){if(this.manifest.mediaGroups=this.manifest.mediaGroups||E,!(i.attributes&&i.attributes.TYPE&&i.attributes["GROUP-ID"]&&i.attributes.NAME))return void this.trigger("warn",{message:"ignoring incomplete or missing media group"});const t=this.manifest.mediaGroups[i.attributes.TYPE];t[i.attributes["GROUP-ID"]]=t[i.attributes["GROUP-ID"]]||{},g=t[i.attributes["GROUP-ID"]],y={default:/yes/i.test(i.attributes.DEFAULT)},y.default?y.autoselect=!0:y.autoselect=/yes/i.test(i.attributes.AUTOSELECT),i.attributes.LANGUAGE&&(y.language=i.attributes.LANGUAGE),i.attributes.URI&&(y.uri=i.attributes.URI),i.attributes["INSTREAM-ID"]&&(y.instreamId=i.attributes["INSTREAM-ID"]),i.attributes.CHARACTERISTICS&&(y.characteristics=i.attributes.CHARACTERISTICS),i.attributes.FORCED&&(y.forced=/yes/i.test(i.attributes.FORCED)),g[i.attributes.NAME]=y},discontinuity(){f+=1,n.discontinuity=!0,this.manifest.discontinuityStarts.push(e.length)},"program-date-time"(){void 0===this.manifest.dateTimeString&&(this.manifest.dateTimeString=i.dateTimeString,this.manifest.dateTimeObject=i.dateTimeObject),n.dateTimeString=i.dateTimeString,n.dateTimeObject=i.dateTimeObject;const{lastProgramDateTime:t}=this;this.lastProgramDateTime=new Date(i.dateTimeString).getTime(),null===t&&this.manifest.segments.reduceRight(((t,e)=>(e.programDateTime=t-1e3*e.duration,e.programDateTime)),this.lastProgramDateTime)},targetduration(){!isFinite(i.duration)||i.duration<0?this.trigger("warn",{message:"ignoring invalid target duration: "+i.duration}):(this.manifest.targetDuration=i.duration,p.call(this,this.manifest))},start(){i.attributes&&!isNaN(i.attributes["TIME-OFFSET"])?this.manifest.start={timeOffset:i.attributes["TIME-OFFSET"],precise:i.attributes.PRECISE}:this.trigger("warn",{message:"ignoring start declaration without appropriate attribute list"})},"cue-out"(){n.cueOut=i.data},"cue-out-cont"(){n.cueOutCont=i.data},"cue-in"(){n.cueIn=i.data},skip(){this.manifest.skip=d(i.attributes),this.warnOnMissingAttributes_("#EXT-X-SKIP",i.attributes,["SKIPPED-SEGMENTS"])},part(){u=!0;const t=this.manifest.segments.length,e=d(i.attributes);n.parts=n.parts||[],n.parts.push(e),e.byterange&&(e.byterange.hasOwnProperty("offset")||(e.byterange.offset=m),m=e.byterange.offset+e.byterange.length);const a=n.parts.length-1;this.warnOnMissingAttributes_(`#EXT-X-PART #${a} for segment #${t}`,i.attributes,["URI","DURATION"]),this.manifest.renditionReports&&this.manifest.renditionReports.forEach(((t,e)=>{t.hasOwnProperty("lastPart")||this.trigger("warn",{message:`#EXT-X-RENDITION-REPORT #${e} lacks required attribute(s): LAST-PART`})}))},"server-control"(){const t=this.manifest.serverControl=d(i.attributes);t.hasOwnProperty("canBlockReload")||(t.canBlockReload=!1,this.trigger("info",{message:"#EXT-X-SERVER-CONTROL defaulting CAN-BLOCK-RELOAD to false"})),p.call(this,this.manifest),t.canSkipDateranges&&!t.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"(){const t=this.manifest.segments.length,e=d(i.attributes),a=e.type&&"PART"===e.type;n.preloadHints=n.preloadHints||[],n.preloadHints.push(e),e.byterange&&(e.byterange.hasOwnProperty("offset")||(e.byterange.offset=a?m:0,a&&(m=e.byterange.offset+e.byterange.length)));const s=n.preloadHints.length-1;if(this.warnOnMissingAttributes_(`#EXT-X-PRELOAD-HINT #${s} for segment #${t}`,i.attributes,["TYPE","URI"]),e.type)for(let i=0;i<n.preloadHints.length-1;i++){const a=n.preloadHints[i];a.type&&(a.type===e.type&&this.trigger("warn",{message:`#EXT-X-PRELOAD-HINT #${s} for segment #${t} has the same TYPE ${e.type} as preload hint #${i}`}))}},"rendition-report"(){const t=d(i.attributes);this.manifest.renditionReports=this.manifest.renditionReports||[],this.manifest.renditionReports.push(t);const e=this.manifest.renditionReports.length-1,a=["LAST-MSN","URI"];u&&a.push("LAST-PART"),this.warnOnMissingAttributes_(`#EXT-X-RENDITION-REPORT #${e}`,i.attributes,a)},"part-inf"(){this.manifest.partInf=d(i.attributes),this.warnOnMissingAttributes_("#EXT-X-PART-INF",i.attributes,["PART-TARGET"]),this.manifest.partInf.partTarget&&(this.manifest.partTargetDuration=this.manifest.partInf.partTarget),p.call(this,this.manifest)},daterange(){this.manifest.dateRanges.push(d(i.attributes));const t=this.manifest.dateRanges.length-1;this.warnOnMissingAttributes_(`#EXT-X-DATERANGE #${t}`,i.attributes,["ID","START-DATE"]);const e=this.manifest.dateRanges[t];e.endDate&&e.startDate&&new Date(e.endDate)<new Date(e.startDate)&&this.trigger("warn",{message:"EXT-X-DATERANGE END-DATE must be equal to or later than the value of the START-DATE"}),e.duration&&e.duration<0&&this.trigger("warn",{message:"EXT-X-DATERANGE DURATION must not be negative"}),e.plannedDuration&&e.plannedDuration<0&&this.trigger("warn",{message:"EXT-X-DATERANGE PLANNED-DURATION must not be negative"});const a=!!e.endOnNext;if(a&&!e.class&&this.trigger("warn",{message:"EXT-X-DATERANGE with an END-ON-NEXT=YES attribute must have a CLASS attribute"}),a&&(e.duration||e.endDate)&&this.trigger("warn",{message:"EXT-X-DATERANGE with an END-ON-NEXT=YES attribute must not contain DURATION or END-DATE attributes"}),e.duration&&e.endDate){const i=e.startDate.getTime()+1e3*e.duration;this.manifest.dateRanges[t].endDate=new Date(i)}if(l[e.id]){for(const t in l[e.id])if(e[t]&&JSON.stringify(l[e.id][t])!==JSON.stringify(e[t])){this.trigger("warn",{message:"EXT-X-DATERANGE tags with the same ID in a playlist must have the same attributes values"});break}const t=this.manifest.dateRanges.findIndex((t=>t.id===e.id));this.manifest.dateRanges[t]=r(this.manifest.dateRanges[t],e),l[e.id]=r(l[e.id],e),this.manifest.dateRanges.pop()}else l[e.id]=e},"independent-segments"(){this.manifest.independentSegments=!0},"content-steering"(){this.manifest.contentSteering=d(i.attributes),this.warnOnMissingAttributes_("#EXT-X-CONTENT-STEERING",i.attributes,["SERVER-URI"])}}[i.tagType]||o).call(t)},uri(){n.uri=i.uri,n.lineNumberStart=b,n.lineNumberEnd=this.parseStream.lineNumber,e.push(n),this.manifest.targetDuration&&!("duration"in n)&&(this.trigger("warn",{message:"defaulting segment duration to the target duration"}),n.duration=this.manifest.targetDuration),s&&(n.key=s),n.timeline=f,a&&(n.map=a),m=0,null!==this.lastProgramDateTime&&(n.programDateTime=this.lastProgramDateTime,this.lastProgramDateTime+=1e3*n.duration),n={}},comment(){},custom(){i.segment?(n.custom=n.custom||{},n.custom[i.customType]=i.data):(this.manifest.custom=this.manifest.custom||{},this.manifest.custom[i.customType]=i.data)}}[i.type].call(t)}))}warnOnMissingAttributes_(t,e,i){const a=[];i.forEach((function(t){e.hasOwnProperty(t)||a.push(t)})),a.length&&this.trigger("warn",{message:`${t} lacks required attribute(s): ${a.join(", ")}`})}push(t){this.lineStream.push(t)}end(){this.lineStream.push("\n"),this.manifest.dateRanges.length&&null===this.lastProgramDateTime&&this.trigger("warn",{message:"A playlist with EXT-X-DATERANGE tag must contain atleast one EXT-X-PROGRAM-DATE-TIME tag"}),this.lastProgramDateTime=null,this.trigger("end")}addParser(t){this.parseStream.addParser(t)}addTagMapper(t){this.parseStream.addTagMapper(t)}},Object.defineProperty(t,"__esModule",{value:!0})}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transmitlive/m3u8-parser",
3
- "version": "7.1.0-2",
3
+ "version": "7.1.0-4",
4
4
  "description": "m3u8 parser",
5
5
  "main": "dist/m3u8-parser.cjs.js",
6
6
  "module": "dist/m3u8-parser.es.js",
@@ -307,9 +307,6 @@ export default class ParseStream extends Stream {
307
307
  if (event.attributes.BANDWIDTH) {
308
308
  event.attributes.BANDWIDTH = parseInt(event.attributes.BANDWIDTH, 10);
309
309
  }
310
- if (event.attributes['FRAME-RATE']) {
311
- event.attributes['FRAME-RATE'] = parseFloat(event.attributes['FRAME-RATE']);
312
- }
313
310
  if (event.attributes['PROGRAM-ID']) {
314
311
  event.attributes['PROGRAM-ID'] = parseInt(event.attributes['PROGRAM-ID'], 10);
315
312
  }
package/src/parser.js CHANGED
@@ -280,25 +280,15 @@ export default class Parser extends Stream {
280
280
  return;
281
281
  }
282
282
 
283
- if (entry.attributes.KEYFORMAT === 'com.microsoft.playready') {
284
- this.manifest.contentProtection = this.manifest.contentProtection || {};
285
-
286
- // TODO: add full support for this.
287
- this.manifest.contentProtection['com.microsoft.playready'] = {
288
- uri: entry.attributes.URI
289
- };
290
-
291
- return;
292
- }
293
-
294
- // check if the content is encrypted for Widevine
283
+ // check if the content is encrypted for Widevine or Playready
295
284
  // Widevine/HLS spec: https://storage.googleapis.com/wvdocs/Widevine_DRM_HLS.pdf
296
- if (entry.attributes.KEYFORMAT === widevineUuid) {
285
+ if (entry.attributes.KEYFORMAT === widevineUuid || entry.attributes.KEYFORMAT === 'com.microsoft.playready') {
286
+ const protectionSystem = entry.attributes.KEYFORMAT === widevineUuid ? 'com.widevine.alpha' : 'com.microsoft.playready';
297
287
  const VALID_METHODS = ['SAMPLE-AES', 'SAMPLE-AES-CTR', 'SAMPLE-AES-CENC'];
298
288
 
299
289
  if (VALID_METHODS.indexOf(entry.attributes.METHOD) === -1) {
300
290
  this.trigger('warn', {
301
- message: 'invalid key method provided for Widevine'
291
+ message: `invalid key method provided for ${protectionSystem}`
302
292
  });
303
293
  return;
304
294
  }
@@ -311,30 +301,33 @@ export default class Parser extends Stream {
311
301
 
312
302
  if (entry.attributes.URI.substring(0, 23) !== 'data:text/plain;base64,') {
313
303
  this.trigger('warn', {
314
- message: 'invalid key URI provided for Widevine'
304
+ message: `invalid key URI provided for ${protectionSystem}`
315
305
  });
316
306
  return;
317
307
  }
318
308
 
319
309
  if (!(entry.attributes.KEYID && entry.attributes.KEYID.substring(0, 2) === '0x')) {
320
310
  this.trigger('warn', {
321
- message: 'invalid key ID provided for Widevine'
311
+ message: `invalid key ID provided for ${protectionSystem}`
322
312
  });
323
313
  return;
324
314
  }
325
315
 
326
- // if Widevine key attributes are valid, store them as `contentProtection`
327
- // on the manifest to emulate Widevine tag structure in a DASH mpd
316
+ // if key attributes are valid, store them as `contentProtection`
317
+ // on the manifest to emulate tag structure in a DASH mpd
328
318
  this.manifest.contentProtection = this.manifest.contentProtection || {};
329
- this.manifest.contentProtection['com.widevine.alpha'] = {
319
+ this.manifest.contentProtection[protectionSystem] = {
330
320
  attributes: {
331
321
  schemeIdUri: entry.attributes.KEYFORMAT,
332
322
  // remove '0x' from the key id string
333
- keyId: entry.attributes.KEYID.substring(2)
323
+ keyId: entry.attributes.KEYID.substring(2),
324
+ method: entry.attributes.METHOD,
325
+ iv: entry.attributes.IV
334
326
  },
335
327
  // decode the base64-encoded PSSH box
336
328
  pssh: decodeB64ToUint8Array(entry.attributes.URI.split(',')[1])
337
329
  };
330
+
338
331
  return;
339
332
  }
340
333
 
@@ -61,7 +61,7 @@ module.exports = {
61
61
  width: 960,
62
62
  height: 540
63
63
  },
64
- 'FRAME-RATE': 59.940,
64
+ 'FRAME-RATE': '59.940',
65
65
  'CLOSED-CAPTIONS': 'cc1',
66
66
  'AUDIO': 'aud1',
67
67
  'SUBTITLES': 'sub1'
@@ -77,7 +77,7 @@ module.exports = {
77
77
  'BANDWIDTH': 7976430,
78
78
  'CLOSED-CAPTIONS': 'cc1',
79
79
  'CODECS': 'avc1.64002a,mp4a.40.2',
80
- 'FRAME-RATE': 59.940,
80
+ 'FRAME-RATE': '59.940',
81
81
  'RESOLUTION': {
82
82
  height: 1080,
83
83
  width: 1920
@@ -94,7 +94,7 @@ module.exports = {
94
94
  'BANDWIDTH': 6181885,
95
95
  'CLOSED-CAPTIONS': 'cc1',
96
96
  'CODECS': 'avc1.64002a,mp4a.40.2',
97
- 'FRAME-RATE': 59.940,
97
+ 'FRAME-RATE': '59.940',
98
98
  'RESOLUTION': {
99
99
  height: 1080,
100
100
  width: 1920
@@ -111,7 +111,7 @@ module.exports = {
111
111
  'BANDWIDTH': 4682666,
112
112
  'CLOSED-CAPTIONS': 'cc1',
113
113
  'CODECS': 'avc1.64002a,mp4a.40.2',
114
- 'FRAME-RATE': 59.940,
114
+ 'FRAME-RATE': '59.940',
115
115
  'RESOLUTION': {
116
116
  height: 1080,
117
117
  width: 1920
@@ -128,7 +128,7 @@ module.exports = {
128
128
  'BANDWIDTH': 3170746,
129
129
  'CLOSED-CAPTIONS': 'cc1',
130
130
  'CODECS': 'avc1.640020,mp4a.40.2',
131
- 'FRAME-RATE': 59.940,
131
+ 'FRAME-RATE': '59.940',
132
132
  'RESOLUTION': {
133
133
  height: 720,
134
134
  width: 1280
@@ -145,7 +145,7 @@ module.exports = {
145
145
  'BANDWIDTH': 1276223,
146
146
  'CLOSED-CAPTIONS': 'cc1',
147
147
  'CODECS': 'avc1.64001e,mp4a.40.2',
148
- 'FRAME-RATE': 29.970,
148
+ 'FRAME-RATE': '29.970',
149
149
  'RESOLUTION': {
150
150
  height: 432,
151
151
  width: 768
@@ -162,7 +162,7 @@ module.exports = {
162
162
  'BANDWIDTH': 904744,
163
163
  'CLOSED-CAPTIONS': 'cc1',
164
164
  'CODECS': 'avc1.64001e,mp4a.40.2',
165
- 'FRAME-RATE': 29.970,
165
+ 'FRAME-RATE': '29.970',
166
166
  'RESOLUTION': {
167
167
  height: 360,
168
168
  width: 640
@@ -179,7 +179,7 @@ module.exports = {
179
179
  'BANDWIDTH': 538201,
180
180
  'CLOSED-CAPTIONS': 'cc1',
181
181
  'CODECS': 'avc1.640015,mp4a.40.2',
182
- 'FRAME-RATE': 29.970,
182
+ 'FRAME-RATE': '29.970',
183
183
  'RESOLUTION': {
184
184
  height: 270,
185
185
  width: 480
@@ -196,7 +196,7 @@ module.exports = {
196
196
  'BANDWIDTH': 2440329,
197
197
  'CLOSED-CAPTIONS': 'cc1',
198
198
  'CODECS': 'avc1.640020,ac-3',
199
- 'FRAME-RATE': 59.940,
199
+ 'FRAME-RATE': '59.940',
200
200
  'RESOLUTION': {
201
201
  height: 540,
202
202
  width: 960
@@ -213,7 +213,7 @@ module.exports = {
213
213
  'BANDWIDTH': 8201540,
214
214
  'CLOSED-CAPTIONS': 'cc1',
215
215
  'CODECS': 'avc1.64002a,ac-3',
216
- 'FRAME-RATE': 59.940,
216
+ 'FRAME-RATE': '59.940',
217
217
  'RESOLUTION': {
218
218
  height: 1080,
219
219
  width: 1920
@@ -230,7 +230,7 @@ module.exports = {
230
230
  'BANDWIDTH': 6406995,
231
231
  'CLOSED-CAPTIONS': 'cc1',
232
232
  'CODECS': 'avc1.64002a,ac-3',
233
- 'FRAME-RATE': 59.940,
233
+ 'FRAME-RATE': '59.940',
234
234
  'RESOLUTION': {
235
235
  height: 1080,
236
236
  width: 1920
@@ -247,7 +247,7 @@ module.exports = {
247
247
  'BANDWIDTH': 4907776,
248
248
  'CLOSED-CAPTIONS': 'cc1',
249
249
  'CODECS': 'avc1.64002a,ac-3',
250
- 'FRAME-RATE': 59.940,
250
+ 'FRAME-RATE': '59.940',
251
251
  'RESOLUTION': {
252
252
  height: 1080,
253
253
  width: 1920
@@ -264,7 +264,7 @@ module.exports = {
264
264
  'BANDWIDTH': 3395856,
265
265
  'CLOSED-CAPTIONS': 'cc1',
266
266
  'CODECS': 'avc1.640020,ac-3',
267
- 'FRAME-RATE': 59.940,
267
+ 'FRAME-RATE': '59.940',
268
268
  'RESOLUTION': {
269
269
  height: 720,
270
270
  width: 1280
@@ -281,7 +281,7 @@ module.exports = {
281
281
  'BANDWIDTH': 1501333,
282
282
  'CLOSED-CAPTIONS': 'cc1',
283
283
  'CODECS': 'avc1.64001e,ac-3',
284
- 'FRAME-RATE': 29.970,
284
+ 'FRAME-RATE': '29.970',
285
285
  'RESOLUTION': {
286
286
  height: 432,
287
287
  width: 768
@@ -298,7 +298,7 @@ module.exports = {
298
298
  'BANDWIDTH': 1129854,
299
299
  'CLOSED-CAPTIONS': 'cc1',
300
300
  'CODECS': 'avc1.64001e,ac-3',
301
- 'FRAME-RATE': 29.970,
301
+ 'FRAME-RATE': '29.970',
302
302
  'RESOLUTION': {
303
303
  height: 360,
304
304
  width: 640
@@ -315,7 +315,7 @@ module.exports = {
315
315
  'BANDWIDTH': 763311,
316
316
  'CLOSED-CAPTIONS': 'cc1',
317
317
  'CODECS': 'avc1.640015,ac-3',
318
- 'FRAME-RATE': 29.970,
318
+ 'FRAME-RATE': '29.970',
319
319
  'RESOLUTION': {
320
320
  height: 270,
321
321
  width: 480
@@ -332,7 +332,7 @@ module.exports = {
332
332
  'BANDWIDTH': 2248329,
333
333
  'CLOSED-CAPTIONS': 'cc1',
334
334
  'CODECS': 'avc1.640020,ec-3',
335
- 'FRAME-RATE': 59.940,
335
+ 'FRAME-RATE': '59.940',
336
336
  'RESOLUTION': {
337
337
  height: 540,
338
338
  width: 960
@@ -349,7 +349,7 @@ module.exports = {
349
349
  'BANDWIDTH': 8009540,
350
350
  'CLOSED-CAPTIONS': 'cc1',
351
351
  'CODECS': 'avc1.64002a,ec-3',
352
- 'FRAME-RATE': 59.940,
352
+ 'FRAME-RATE': '59.940',
353
353
  'RESOLUTION': {
354
354
  height: 1080,
355
355
  width: 1920
@@ -366,7 +366,7 @@ module.exports = {
366
366
  'BANDWIDTH': 6214995,
367
367
  'CLOSED-CAPTIONS': 'cc1',
368
368
  'CODECS': 'avc1.64002a,ec-3',
369
- 'FRAME-RATE': 59.940,
369
+ 'FRAME-RATE': '59.940',
370
370
  'RESOLUTION': {
371
371
  height: 1080,
372
372
  width: 1920
@@ -383,7 +383,7 @@ module.exports = {
383
383
  'BANDWIDTH': 4715776,
384
384
  'CLOSED-CAPTIONS': 'cc1',
385
385
  'CODECS': 'avc1.64002a,ec-3',
386
- 'FRAME-RATE': 59.940,
386
+ 'FRAME-RATE': '59.940',
387
387
  'RESOLUTION': {
388
388
  height: 1080,
389
389
  width: 1920
@@ -400,7 +400,7 @@ module.exports = {
400
400
  'BANDWIDTH': 3203856,
401
401
  'CLOSED-CAPTIONS': 'cc1',
402
402
  'CODECS': 'avc1.640020,ec-3',
403
- 'FRAME-RATE': 59.940,
403
+ 'FRAME-RATE': '59.940',
404
404
  'RESOLUTION': {
405
405
  height: 720,
406
406
  width: 1280
@@ -417,7 +417,7 @@ module.exports = {
417
417
  'BANDWIDTH': 1309333,
418
418
  'CLOSED-CAPTIONS': 'cc1',
419
419
  'CODECS': 'avc1.64001e,ec-3',
420
- 'FRAME-RATE': 29.970,
420
+ 'FRAME-RATE': '29.970',
421
421
  'RESOLUTION': {
422
422
  height: 432,
423
423
  width: 768
@@ -434,7 +434,7 @@ module.exports = {
434
434
  'BANDWIDTH': 937854,
435
435
  'CLOSED-CAPTIONS': 'cc1',
436
436
  'CODECS': 'avc1.64001e,ec-3',
437
- 'FRAME-RATE': 29.970,
437
+ 'FRAME-RATE': '29.970',
438
438
  'RESOLUTION': {
439
439
  height: 360,
440
440
  width: 640
@@ -451,7 +451,7 @@ module.exports = {
451
451
  'BANDWIDTH': 571311,
452
452
  'CLOSED-CAPTIONS': 'cc1',
453
453
  'CODECS': 'avc1.640015,ec-3',
454
- 'FRAME-RATE': 29.970,
454
+ 'FRAME-RATE': '29.970',
455
455
  'RESOLUTION': {
456
456
  height: 270,
457
457
  width: 480
@@ -843,7 +843,7 @@ QUnit.module('m3u8s', function(hooks) {
843
843
  '#EXT-X-SERVER-CONTROL:foo=bar',
844
844
  '#EXT-X-KEY:METHOD=SAMPLE-AES,URI="data:text/plain;base64,foo",KEYID=0x555777,IV=1234567890abcdef1234567890abcdef,KEYFORMATVERSIONS="1",KEYFORMAT="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"',
845
845
  '#EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://foo",KEYFORMATVERSIONS="1",KEYFORMAT="com.apple.streamingkeydelivery"',
846
- '#EXT-X-KEY:METHOD=SAMPLE-AES,URI="http://example.com",KEYFORMATVERSIONS="1",KEYFORMAT="com.microsoft.playready"',
846
+ '#EXT-X-KEY:METHOD=SAMPLE-AES,URI="data:text/plain;base64,bar",KEYFORMATVERSIONS="1",KEYFORMAT="com.microsoft.playready",KEYID=0x555777',
847
847
  '#EXTINF:10,',
848
848
  'media-00001.ts',
849
849
  '#EXT-X-ENDLIST'