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

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-0 @license Apache-2.0 */
1
+ /*! @name @transmitlive/m3u8-parser @version 7.1.0-2 @license Apache-2.0 */
2
2
  'use strict';
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
@@ -28,7 +28,6 @@ class LineStream extends Stream__default["default"] {
28
28
  constructor() {
29
29
  super();
30
30
  this.buffer = '';
31
- this.lineNumber = 0;
32
31
  }
33
32
  /**
34
33
  * Add new data to be parsed.
@@ -40,7 +39,6 @@ class LineStream extends Stream__default["default"] {
40
39
  push(data) {
41
40
  let nextNewline;
42
41
  this.buffer += data;
43
- this.lineNumber += 1;
44
42
  nextNewline = this.buffer.indexOf('\n');
45
43
 
46
44
  for (; nextNewline > -1; nextNewline = this.buffer.indexOf('\n')) {
@@ -92,14 +90,9 @@ const attributeSeparator = function () {
92
90
 
93
91
 
94
92
  const parseAttributes = function (attributes) {
95
- const result = {};
96
-
97
- if (!attributes) {
98
- return result;
99
- } // split the string using attributes as the separator
100
-
101
-
93
+ // split the string using attributes as the separator
102
94
  const attrs = attributes.split(attributeSeparator());
95
+ const result = {};
103
96
  let i = attrs.length;
104
97
  let attr;
105
98
 
@@ -151,6 +144,7 @@ class ParseStream extends Stream__default["default"] {
151
144
  super();
152
145
  this.customParsers = [];
153
146
  this.tagMappers = [];
147
+ this.lineNumber = 0;
154
148
  }
155
149
  /**
156
150
  * Parses an additional line of input.
@@ -161,7 +155,8 @@ class ParseStream extends Stream__default["default"] {
161
155
 
162
156
  push(line) {
163
157
  let match;
164
- let event; // strip whitespace
158
+ let event;
159
+ this.lineNumber = this.lineNumber + 1; // strip whitespace
165
160
 
166
161
  line = line.trim();
167
162
 
@@ -219,7 +214,7 @@ class ParseStream extends Stream__default["default"] {
219
214
  return;
220
215
  }
221
216
 
222
- match = /^#EXTINF:([0-9\.]*)?,?(.*)?$/.exec(newLine);
217
+ match = /^#EXTINF:?([0-9\.]*)?,?(.*)?$/.exec(newLine);
223
218
 
224
219
  if (match) {
225
220
  event = {
@@ -239,7 +234,7 @@ class ParseStream extends Stream__default["default"] {
239
234
  return;
240
235
  }
241
236
 
242
- match = /^#EXT-X-TARGETDURATION:([0-9.]*)?/.exec(newLine);
237
+ match = /^#EXT-X-TARGETDURATION:?([0-9.]*)?/.exec(newLine);
243
238
 
244
239
  if (match) {
245
240
  event = {
@@ -255,7 +250,7 @@ class ParseStream extends Stream__default["default"] {
255
250
  return;
256
251
  }
257
252
 
258
- match = /^#EXT-X-VERSION:([0-9.]*)?/.exec(newLine);
253
+ match = /^#EXT-X-VERSION:?([0-9.]*)?/.exec(newLine);
259
254
 
260
255
  if (match) {
261
256
  event = {
@@ -271,7 +266,7 @@ class ParseStream extends Stream__default["default"] {
271
266
  return;
272
267
  }
273
268
 
274
- match = /^#EXT-X-MEDIA-SEQUENCE:(\-?[0-9.]*)?/.exec(newLine);
269
+ match = /^#EXT-X-MEDIA-SEQUENCE:?(\-?[0-9.]*)?/.exec(newLine);
275
270
 
276
271
  if (match) {
277
272
  event = {
@@ -287,7 +282,7 @@ class ParseStream extends Stream__default["default"] {
287
282
  return;
288
283
  }
289
284
 
290
- match = /^#EXT-X-DISCONTINUITY-SEQUENCE:(\-?[0-9.]*)?/.exec(newLine);
285
+ match = /^#EXT-X-DISCONTINUITY-SEQUENCE:?(\-?[0-9.]*)?/.exec(newLine);
291
286
 
292
287
  if (match) {
293
288
  event = {
@@ -303,7 +298,7 @@ class ParseStream extends Stream__default["default"] {
303
298
  return;
304
299
  }
305
300
 
306
- match = /^#EXT-X-PLAYLIST-TYPE:(.*)?$/.exec(newLine);
301
+ match = /^#EXT-X-PLAYLIST-TYPE:?(.*)?$/.exec(newLine);
307
302
 
308
303
  if (match) {
309
304
  event = {
@@ -319,7 +314,7 @@ class ParseStream extends Stream__default["default"] {
319
314
  return;
320
315
  }
321
316
 
322
- match = /^#EXT-X-BYTERANGE:(.*)?$/.exec(newLine);
317
+ match = /^#EXT-X-BYTERANGE:?(.*)?$/.exec(newLine);
323
318
 
324
319
  if (match) {
325
320
  event = _extends__default["default"](parseByterange(match[1]), {
@@ -330,7 +325,7 @@ class ParseStream extends Stream__default["default"] {
330
325
  return;
331
326
  }
332
327
 
333
- match = /^#EXT-X-ALLOW-CACHE:(YES|NO)?/.exec(newLine);
328
+ match = /^#EXT-X-ALLOW-CACHE:?(YES|NO)?/.exec(newLine);
334
329
 
335
330
  if (match) {
336
331
  event = {
@@ -346,7 +341,7 @@ class ParseStream extends Stream__default["default"] {
346
341
  return;
347
342
  }
348
343
 
349
- match = /^#EXT-X-MAP:(.*)$/.exec(newLine);
344
+ match = /^#EXT-X-MAP:?(.*)$/.exec(newLine);
350
345
 
351
346
  if (match) {
352
347
  event = {
@@ -370,7 +365,7 @@ class ParseStream extends Stream__default["default"] {
370
365
  return;
371
366
  }
372
367
 
373
- match = /^#EXT-X-STREAM-INF:(.*)$/.exec(newLine);
368
+ match = /^#EXT-X-STREAM-INF:?(.*)$/.exec(newLine);
374
369
 
375
370
  if (match) {
376
371
  event = {
@@ -413,7 +408,7 @@ class ParseStream extends Stream__default["default"] {
413
408
  return;
414
409
  }
415
410
 
416
- match = /^#EXT-X-MEDIA:(.*)$/.exec(newLine);
411
+ match = /^#EXT-X-MEDIA:?(.*)$/.exec(newLine);
417
412
 
418
413
  if (match) {
419
414
  event = {
@@ -449,7 +444,7 @@ class ParseStream extends Stream__default["default"] {
449
444
  return;
450
445
  }
451
446
 
452
- match = /^#EXT-X-PROGRAM-DATE-TIME:(.*)$/.exec(newLine);
447
+ match = /^#EXT-X-PROGRAM-DATE-TIME:?(.*)$/.exec(newLine);
453
448
 
454
449
  if (match) {
455
450
  event = {
@@ -466,7 +461,7 @@ class ParseStream extends Stream__default["default"] {
466
461
  return;
467
462
  }
468
463
 
469
- match = /^#EXT-X-KEY:(.*)$/.exec(newLine);
464
+ match = /^#EXT-X-KEY:?(.*)$/.exec(newLine);
470
465
 
471
466
  if (match) {
472
467
  event = {
@@ -495,7 +490,7 @@ class ParseStream extends Stream__default["default"] {
495
490
  return;
496
491
  }
497
492
 
498
- match = /^#EXT-X-START:(.*)$/.exec(newLine);
493
+ match = /^#EXT-X-START:?(.*)$/.exec(newLine);
499
494
 
500
495
  if (match) {
501
496
  event = {
@@ -513,7 +508,7 @@ class ParseStream extends Stream__default["default"] {
513
508
  return;
514
509
  }
515
510
 
516
- match = /^#EXT-X-CUE-OUT-CONT:(.*)?$/.exec(newLine);
511
+ match = /^#EXT-X-CUE-OUT-CONT:?(.*)?$/.exec(newLine);
517
512
 
518
513
  if (match) {
519
514
  event = {
@@ -531,7 +526,7 @@ class ParseStream extends Stream__default["default"] {
531
526
  return;
532
527
  }
533
528
 
534
- match = /^#EXT-X-CUE-OUT:(.*)?$/.exec(newLine);
529
+ match = /^#EXT-X-CUE-OUT:?(.*)?$/.exec(newLine);
535
530
 
536
531
  if (match) {
537
532
  event = {
@@ -549,7 +544,7 @@ class ParseStream extends Stream__default["default"] {
549
544
  return;
550
545
  }
551
546
 
552
- match = /^#EXT-X-CUE-IN:(.*)?$/.exec(newLine);
547
+ match = /^#EXT-X-CUE-IN:?(.*)?$/.exec(newLine);
553
548
 
554
549
  if (match) {
555
550
  event = {
@@ -989,10 +984,10 @@ class Parser extends Stream__default["default"] {
989
984
 
990
985
  this.parseStream.on('data', function (entry) {
991
986
  let mediaGroup;
992
- let rendition; //starting a new segment
987
+ let rendition; // starting a new segment
993
988
 
994
989
  if (!Object.keys(currentUri).length) {
995
- nextSegmentLineNumberStart = this.lineStream.lineNumber;
990
+ nextSegmentLineNumberStart = this.lineNumber;
996
991
  }
997
992
 
998
993
  ({
@@ -1578,7 +1573,7 @@ class Parser extends Stream__default["default"] {
1578
1573
  uri() {
1579
1574
  currentUri.uri = entry.uri;
1580
1575
  currentUri.lineNumberStart = nextSegmentLineNumberStart;
1581
- currentUri.lineNumberEnd = this.lineStream.lineNumber;
1576
+ currentUri.lineNumberEnd = this.parseStream.lineNumber;
1582
1577
  uris.push(currentUri); // if no explicit duration was declared, use the target duration
1583
1578
 
1584
1579
  if (this.manifest.targetDuration && !('duration' in currentUri)) {
@@ -1,4 +1,4 @@
1
- /*! @name @transmitlive/m3u8-parser @version 7.1.0-0 @license Apache-2.0 */
1
+ /*! @name @transmitlive/m3u8-parser @version 7.1.0-2 @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';
@@ -18,7 +18,6 @@ class LineStream extends Stream {
18
18
  constructor() {
19
19
  super();
20
20
  this.buffer = '';
21
- this.lineNumber = 0;
22
21
  }
23
22
  /**
24
23
  * Add new data to be parsed.
@@ -30,7 +29,6 @@ class LineStream extends Stream {
30
29
  push(data) {
31
30
  let nextNewline;
32
31
  this.buffer += data;
33
- this.lineNumber += 1;
34
32
  nextNewline = this.buffer.indexOf('\n');
35
33
 
36
34
  for (; nextNewline > -1; nextNewline = this.buffer.indexOf('\n')) {
@@ -82,14 +80,9 @@ const attributeSeparator = function () {
82
80
 
83
81
 
84
82
  const parseAttributes = function (attributes) {
85
- const result = {};
86
-
87
- if (!attributes) {
88
- return result;
89
- } // split the string using attributes as the separator
90
-
91
-
83
+ // split the string using attributes as the separator
92
84
  const attrs = attributes.split(attributeSeparator());
85
+ const result = {};
93
86
  let i = attrs.length;
94
87
  let attr;
95
88
 
@@ -141,6 +134,7 @@ class ParseStream extends Stream {
141
134
  super();
142
135
  this.customParsers = [];
143
136
  this.tagMappers = [];
137
+ this.lineNumber = 0;
144
138
  }
145
139
  /**
146
140
  * Parses an additional line of input.
@@ -151,7 +145,8 @@ class ParseStream extends Stream {
151
145
 
152
146
  push(line) {
153
147
  let match;
154
- let event; // strip whitespace
148
+ let event;
149
+ this.lineNumber = this.lineNumber + 1; // strip whitespace
155
150
 
156
151
  line = line.trim();
157
152
 
@@ -209,7 +204,7 @@ class ParseStream extends Stream {
209
204
  return;
210
205
  }
211
206
 
212
- match = /^#EXTINF:([0-9\.]*)?,?(.*)?$/.exec(newLine);
207
+ match = /^#EXTINF:?([0-9\.]*)?,?(.*)?$/.exec(newLine);
213
208
 
214
209
  if (match) {
215
210
  event = {
@@ -229,7 +224,7 @@ class ParseStream extends Stream {
229
224
  return;
230
225
  }
231
226
 
232
- match = /^#EXT-X-TARGETDURATION:([0-9.]*)?/.exec(newLine);
227
+ match = /^#EXT-X-TARGETDURATION:?([0-9.]*)?/.exec(newLine);
233
228
 
234
229
  if (match) {
235
230
  event = {
@@ -245,7 +240,7 @@ class ParseStream extends Stream {
245
240
  return;
246
241
  }
247
242
 
248
- match = /^#EXT-X-VERSION:([0-9.]*)?/.exec(newLine);
243
+ match = /^#EXT-X-VERSION:?([0-9.]*)?/.exec(newLine);
249
244
 
250
245
  if (match) {
251
246
  event = {
@@ -261,7 +256,7 @@ class ParseStream extends Stream {
261
256
  return;
262
257
  }
263
258
 
264
- match = /^#EXT-X-MEDIA-SEQUENCE:(\-?[0-9.]*)?/.exec(newLine);
259
+ match = /^#EXT-X-MEDIA-SEQUENCE:?(\-?[0-9.]*)?/.exec(newLine);
265
260
 
266
261
  if (match) {
267
262
  event = {
@@ -277,7 +272,7 @@ class ParseStream extends Stream {
277
272
  return;
278
273
  }
279
274
 
280
- match = /^#EXT-X-DISCONTINUITY-SEQUENCE:(\-?[0-9.]*)?/.exec(newLine);
275
+ match = /^#EXT-X-DISCONTINUITY-SEQUENCE:?(\-?[0-9.]*)?/.exec(newLine);
281
276
 
282
277
  if (match) {
283
278
  event = {
@@ -293,7 +288,7 @@ class ParseStream extends Stream {
293
288
  return;
294
289
  }
295
290
 
296
- match = /^#EXT-X-PLAYLIST-TYPE:(.*)?$/.exec(newLine);
291
+ match = /^#EXT-X-PLAYLIST-TYPE:?(.*)?$/.exec(newLine);
297
292
 
298
293
  if (match) {
299
294
  event = {
@@ -309,7 +304,7 @@ class ParseStream extends Stream {
309
304
  return;
310
305
  }
311
306
 
312
- match = /^#EXT-X-BYTERANGE:(.*)?$/.exec(newLine);
307
+ match = /^#EXT-X-BYTERANGE:?(.*)?$/.exec(newLine);
313
308
 
314
309
  if (match) {
315
310
  event = _extends(parseByterange(match[1]), {
@@ -320,7 +315,7 @@ class ParseStream extends Stream {
320
315
  return;
321
316
  }
322
317
 
323
- match = /^#EXT-X-ALLOW-CACHE:(YES|NO)?/.exec(newLine);
318
+ match = /^#EXT-X-ALLOW-CACHE:?(YES|NO)?/.exec(newLine);
324
319
 
325
320
  if (match) {
326
321
  event = {
@@ -336,7 +331,7 @@ class ParseStream extends Stream {
336
331
  return;
337
332
  }
338
333
 
339
- match = /^#EXT-X-MAP:(.*)$/.exec(newLine);
334
+ match = /^#EXT-X-MAP:?(.*)$/.exec(newLine);
340
335
 
341
336
  if (match) {
342
337
  event = {
@@ -360,7 +355,7 @@ class ParseStream extends Stream {
360
355
  return;
361
356
  }
362
357
 
363
- match = /^#EXT-X-STREAM-INF:(.*)$/.exec(newLine);
358
+ match = /^#EXT-X-STREAM-INF:?(.*)$/.exec(newLine);
364
359
 
365
360
  if (match) {
366
361
  event = {
@@ -403,7 +398,7 @@ class ParseStream extends Stream {
403
398
  return;
404
399
  }
405
400
 
406
- match = /^#EXT-X-MEDIA:(.*)$/.exec(newLine);
401
+ match = /^#EXT-X-MEDIA:?(.*)$/.exec(newLine);
407
402
 
408
403
  if (match) {
409
404
  event = {
@@ -439,7 +434,7 @@ class ParseStream extends Stream {
439
434
  return;
440
435
  }
441
436
 
442
- match = /^#EXT-X-PROGRAM-DATE-TIME:(.*)$/.exec(newLine);
437
+ match = /^#EXT-X-PROGRAM-DATE-TIME:?(.*)$/.exec(newLine);
443
438
 
444
439
  if (match) {
445
440
  event = {
@@ -456,7 +451,7 @@ class ParseStream extends Stream {
456
451
  return;
457
452
  }
458
453
 
459
- match = /^#EXT-X-KEY:(.*)$/.exec(newLine);
454
+ match = /^#EXT-X-KEY:?(.*)$/.exec(newLine);
460
455
 
461
456
  if (match) {
462
457
  event = {
@@ -485,7 +480,7 @@ class ParseStream extends Stream {
485
480
  return;
486
481
  }
487
482
 
488
- match = /^#EXT-X-START:(.*)$/.exec(newLine);
483
+ match = /^#EXT-X-START:?(.*)$/.exec(newLine);
489
484
 
490
485
  if (match) {
491
486
  event = {
@@ -503,7 +498,7 @@ class ParseStream extends Stream {
503
498
  return;
504
499
  }
505
500
 
506
- match = /^#EXT-X-CUE-OUT-CONT:(.*)?$/.exec(newLine);
501
+ match = /^#EXT-X-CUE-OUT-CONT:?(.*)?$/.exec(newLine);
507
502
 
508
503
  if (match) {
509
504
  event = {
@@ -521,7 +516,7 @@ class ParseStream extends Stream {
521
516
  return;
522
517
  }
523
518
 
524
- match = /^#EXT-X-CUE-OUT:(.*)?$/.exec(newLine);
519
+ match = /^#EXT-X-CUE-OUT:?(.*)?$/.exec(newLine);
525
520
 
526
521
  if (match) {
527
522
  event = {
@@ -539,7 +534,7 @@ class ParseStream extends Stream {
539
534
  return;
540
535
  }
541
536
 
542
- match = /^#EXT-X-CUE-IN:(.*)?$/.exec(newLine);
537
+ match = /^#EXT-X-CUE-IN:?(.*)?$/.exec(newLine);
543
538
 
544
539
  if (match) {
545
540
  event = {
@@ -979,10 +974,10 @@ class Parser extends Stream {
979
974
 
980
975
  this.parseStream.on('data', function (entry) {
981
976
  let mediaGroup;
982
- let rendition; //starting a new segment
977
+ let rendition; // starting a new segment
983
978
 
984
979
  if (!Object.keys(currentUri).length) {
985
- nextSegmentLineNumberStart = this.lineStream.lineNumber;
980
+ nextSegmentLineNumberStart = this.lineNumber;
986
981
  }
987
982
 
988
983
  ({
@@ -1568,7 +1563,7 @@ class Parser extends Stream {
1568
1563
  uri() {
1569
1564
  currentUri.uri = entry.uri;
1570
1565
  currentUri.lineNumberStart = nextSegmentLineNumberStart;
1571
- currentUri.lineNumberEnd = this.lineStream.lineNumber;
1566
+ currentUri.lineNumberEnd = this.parseStream.lineNumber;
1572
1567
  uris.push(currentUri); // if no explicit duration was declared, use the target duration
1573
1568
 
1574
1569
  if (this.manifest.targetDuration && !('duration' in currentUri)) {
@@ -1,4 +1,4 @@
1
- /*! @name @transmitlive/m3u8-parser @version 7.1.0-0 @license Apache-2.0 */
1
+ /*! @name @transmitlive/m3u8-parser @version 7.1.0-2 @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) :
@@ -140,7 +140,6 @@
140
140
  constructor() {
141
141
  super();
142
142
  this.buffer = '';
143
- this.lineNumber = 0;
144
143
  }
145
144
  /**
146
145
  * Add new data to be parsed.
@@ -152,7 +151,6 @@
152
151
  push(data) {
153
152
  let nextNewline;
154
153
  this.buffer += data;
155
- this.lineNumber += 1;
156
154
  nextNewline = this.buffer.indexOf('\n');
157
155
 
158
156
  for (; nextNewline > -1; nextNewline = this.buffer.indexOf('\n')) {
@@ -225,14 +223,9 @@
225
223
 
226
224
 
227
225
  const parseAttributes = function (attributes) {
228
- const result = {};
229
-
230
- if (!attributes) {
231
- return result;
232
- } // split the string using attributes as the separator
233
-
234
-
226
+ // split the string using attributes as the separator
235
227
  const attrs = attributes.split(attributeSeparator());
228
+ const result = {};
236
229
  let i = attrs.length;
237
230
  let attr;
238
231
 
@@ -284,6 +277,7 @@
284
277
  super();
285
278
  this.customParsers = [];
286
279
  this.tagMappers = [];
280
+ this.lineNumber = 0;
287
281
  }
288
282
  /**
289
283
  * Parses an additional line of input.
@@ -294,7 +288,8 @@
294
288
 
295
289
  push(line) {
296
290
  let match;
297
- let event; // strip whitespace
291
+ let event;
292
+ this.lineNumber = this.lineNumber + 1; // strip whitespace
298
293
 
299
294
  line = line.trim();
300
295
 
@@ -352,7 +347,7 @@
352
347
  return;
353
348
  }
354
349
 
355
- match = /^#EXTINF:([0-9\.]*)?,?(.*)?$/.exec(newLine);
350
+ match = /^#EXTINF:?([0-9\.]*)?,?(.*)?$/.exec(newLine);
356
351
 
357
352
  if (match) {
358
353
  event = {
@@ -372,7 +367,7 @@
372
367
  return;
373
368
  }
374
369
 
375
- match = /^#EXT-X-TARGETDURATION:([0-9.]*)?/.exec(newLine);
370
+ match = /^#EXT-X-TARGETDURATION:?([0-9.]*)?/.exec(newLine);
376
371
 
377
372
  if (match) {
378
373
  event = {
@@ -388,7 +383,7 @@
388
383
  return;
389
384
  }
390
385
 
391
- match = /^#EXT-X-VERSION:([0-9.]*)?/.exec(newLine);
386
+ match = /^#EXT-X-VERSION:?([0-9.]*)?/.exec(newLine);
392
387
 
393
388
  if (match) {
394
389
  event = {
@@ -404,7 +399,7 @@
404
399
  return;
405
400
  }
406
401
 
407
- match = /^#EXT-X-MEDIA-SEQUENCE:(\-?[0-9.]*)?/.exec(newLine);
402
+ match = /^#EXT-X-MEDIA-SEQUENCE:?(\-?[0-9.]*)?/.exec(newLine);
408
403
 
409
404
  if (match) {
410
405
  event = {
@@ -420,7 +415,7 @@
420
415
  return;
421
416
  }
422
417
 
423
- match = /^#EXT-X-DISCONTINUITY-SEQUENCE:(\-?[0-9.]*)?/.exec(newLine);
418
+ match = /^#EXT-X-DISCONTINUITY-SEQUENCE:?(\-?[0-9.]*)?/.exec(newLine);
424
419
 
425
420
  if (match) {
426
421
  event = {
@@ -436,7 +431,7 @@
436
431
  return;
437
432
  }
438
433
 
439
- match = /^#EXT-X-PLAYLIST-TYPE:(.*)?$/.exec(newLine);
434
+ match = /^#EXT-X-PLAYLIST-TYPE:?(.*)?$/.exec(newLine);
440
435
 
441
436
  if (match) {
442
437
  event = {
@@ -452,7 +447,7 @@
452
447
  return;
453
448
  }
454
449
 
455
- match = /^#EXT-X-BYTERANGE:(.*)?$/.exec(newLine);
450
+ match = /^#EXT-X-BYTERANGE:?(.*)?$/.exec(newLine);
456
451
 
457
452
  if (match) {
458
453
  event = _extends$1(parseByterange(match[1]), {
@@ -463,7 +458,7 @@
463
458
  return;
464
459
  }
465
460
 
466
- match = /^#EXT-X-ALLOW-CACHE:(YES|NO)?/.exec(newLine);
461
+ match = /^#EXT-X-ALLOW-CACHE:?(YES|NO)?/.exec(newLine);
467
462
 
468
463
  if (match) {
469
464
  event = {
@@ -479,7 +474,7 @@
479
474
  return;
480
475
  }
481
476
 
482
- match = /^#EXT-X-MAP:(.*)$/.exec(newLine);
477
+ match = /^#EXT-X-MAP:?(.*)$/.exec(newLine);
483
478
 
484
479
  if (match) {
485
480
  event = {
@@ -503,7 +498,7 @@
503
498
  return;
504
499
  }
505
500
 
506
- match = /^#EXT-X-STREAM-INF:(.*)$/.exec(newLine);
501
+ match = /^#EXT-X-STREAM-INF:?(.*)$/.exec(newLine);
507
502
 
508
503
  if (match) {
509
504
  event = {
@@ -546,7 +541,7 @@
546
541
  return;
547
542
  }
548
543
 
549
- match = /^#EXT-X-MEDIA:(.*)$/.exec(newLine);
544
+ match = /^#EXT-X-MEDIA:?(.*)$/.exec(newLine);
550
545
 
551
546
  if (match) {
552
547
  event = {
@@ -582,7 +577,7 @@
582
577
  return;
583
578
  }
584
579
 
585
- match = /^#EXT-X-PROGRAM-DATE-TIME:(.*)$/.exec(newLine);
580
+ match = /^#EXT-X-PROGRAM-DATE-TIME:?(.*)$/.exec(newLine);
586
581
 
587
582
  if (match) {
588
583
  event = {
@@ -599,7 +594,7 @@
599
594
  return;
600
595
  }
601
596
 
602
- match = /^#EXT-X-KEY:(.*)$/.exec(newLine);
597
+ match = /^#EXT-X-KEY:?(.*)$/.exec(newLine);
603
598
 
604
599
  if (match) {
605
600
  event = {
@@ -628,7 +623,7 @@
628
623
  return;
629
624
  }
630
625
 
631
- match = /^#EXT-X-START:(.*)$/.exec(newLine);
626
+ match = /^#EXT-X-START:?(.*)$/.exec(newLine);
632
627
 
633
628
  if (match) {
634
629
  event = {
@@ -646,7 +641,7 @@
646
641
  return;
647
642
  }
648
643
 
649
- match = /^#EXT-X-CUE-OUT-CONT:(.*)?$/.exec(newLine);
644
+ match = /^#EXT-X-CUE-OUT-CONT:?(.*)?$/.exec(newLine);
650
645
 
651
646
  if (match) {
652
647
  event = {
@@ -664,7 +659,7 @@
664
659
  return;
665
660
  }
666
661
 
667
- match = /^#EXT-X-CUE-OUT:(.*)?$/.exec(newLine);
662
+ match = /^#EXT-X-CUE-OUT:?(.*)?$/.exec(newLine);
668
663
 
669
664
  if (match) {
670
665
  event = {
@@ -682,7 +677,7 @@
682
677
  return;
683
678
  }
684
679
 
685
- match = /^#EXT-X-CUE-IN:(.*)?$/.exec(newLine);
680
+ match = /^#EXT-X-CUE-IN:?(.*)?$/.exec(newLine);
686
681
 
687
682
  if (match) {
688
683
  event = {
@@ -1137,10 +1132,10 @@
1137
1132
 
1138
1133
  this.parseStream.on('data', function (entry) {
1139
1134
  let mediaGroup;
1140
- let rendition; //starting a new segment
1135
+ let rendition; // starting a new segment
1141
1136
 
1142
1137
  if (!Object.keys(currentUri).length) {
1143
- nextSegmentLineNumberStart = this.lineStream.lineNumber;
1138
+ nextSegmentLineNumberStart = this.lineNumber;
1144
1139
  }
1145
1140
 
1146
1141
  ({
@@ -1726,7 +1721,7 @@
1726
1721
  uri() {
1727
1722
  currentUri.uri = entry.uri;
1728
1723
  currentUri.lineNumberStart = nextSegmentLineNumberStart;
1729
- currentUri.lineNumberEnd = this.lineStream.lineNumber;
1724
+ currentUri.lineNumberEnd = this.parseStream.lineNumber;
1730
1725
  uris.push(currentUri); // if no explicit duration was declared, use the target duration
1731
1726
 
1732
1727
  if (this.manifest.targetDuration && !('duration' in currentUri)) {
@@ -1,2 +1,2 @@
1
- /*! @name @transmitlive/m3u8-parser @version 7.1.0-0 @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="",this.lineNumber=0}push(t){let e;for(this.buffer+=t,this.lineNumber+=1,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={};if(!t)return e;const i=t.split(new RegExp('(?:^|,)((?:[^=]*)=(?:"[^"]*"|[^,]*))'));let a,s=i.length;for(;s--;)""!==i[s]&&(a=/([^=]*)=(.*)/.exec(i[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"),e[a[0]]=a[1]);return e};class g extends e{constructor(){super(),this.customParsers=[],this.tagMappers=[]}push(t){let e,i;if(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.lineStream.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.lineStream.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-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})}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transmitlive/m3u8-parser",
3
- "version": "7.1.0-0",
3
+ "version": "7.1.0-2",
4
4
  "description": "m3u8 parser",
5
5
  "main": "dist/m3u8-parser.cjs.js",
6
6
  "module": "dist/m3u8-parser.es.js",
@@ -14,7 +14,6 @@ export default class LineStream extends Stream {
14
14
  constructor() {
15
15
  super();
16
16
  this.buffer = '';
17
- this.lineNumber = 0;
18
17
  }
19
18
 
20
19
  /**
@@ -26,7 +25,6 @@ export default class LineStream extends Stream {
26
25
  let nextNewline;
27
26
 
28
27
  this.buffer += data;
29
- this.lineNumber += 1;
30
28
  nextNewline = this.buffer.indexOf('\n');
31
29
 
32
30
  for (; nextNewline > -1; nextNewline = this.buffer.indexOf('\n')) {
@@ -43,14 +43,9 @@ const attributeSeparator = function() {
43
43
  * @param {string} attributes the attribute line to parse
44
44
  */
45
45
  const parseAttributes = function(attributes) {
46
- const result = {};
47
-
48
- if (!attributes) {
49
- return result;
50
- }
51
-
52
46
  // split the string using attributes as the separator
53
47
  const attrs = attributes.split(attributeSeparator());
48
+ const result = {};
54
49
  let i = attrs.length;
55
50
  let attr;
56
51
 
@@ -100,6 +95,7 @@ export default class ParseStream extends Stream {
100
95
  super();
101
96
  this.customParsers = [];
102
97
  this.tagMappers = [];
98
+ this.lineNumber = 0;
103
99
  }
104
100
 
105
101
  /**
@@ -111,6 +107,7 @@ export default class ParseStream extends Stream {
111
107
  let match;
112
108
  let event;
113
109
 
110
+ this.lineNumber = this.lineNumber + 1;
114
111
  // strip whitespace
115
112
  line = line.trim();
116
113
 
@@ -169,7 +166,7 @@ export default class ParseStream extends Stream {
169
166
  });
170
167
  return;
171
168
  }
172
- match = (/^#EXTINF:([0-9\.]*)?,?(.*)?$/).exec(newLine);
169
+ match = (/^#EXTINF:?([0-9\.]*)?,?(.*)?$/).exec(newLine);
173
170
  if (match) {
174
171
  event = {
175
172
  type: 'tag',
@@ -184,7 +181,7 @@ export default class ParseStream extends Stream {
184
181
  this.trigger('data', event);
185
182
  return;
186
183
  }
187
- match = (/^#EXT-X-TARGETDURATION:([0-9.]*)?/).exec(newLine);
184
+ match = (/^#EXT-X-TARGETDURATION:?([0-9.]*)?/).exec(newLine);
188
185
  if (match) {
189
186
  event = {
190
187
  type: 'tag',
@@ -196,7 +193,7 @@ export default class ParseStream extends Stream {
196
193
  this.trigger('data', event);
197
194
  return;
198
195
  }
199
- match = (/^#EXT-X-VERSION:([0-9.]*)?/).exec(newLine);
196
+ match = (/^#EXT-X-VERSION:?([0-9.]*)?/).exec(newLine);
200
197
  if (match) {
201
198
  event = {
202
199
  type: 'tag',
@@ -208,7 +205,7 @@ export default class ParseStream extends Stream {
208
205
  this.trigger('data', event);
209
206
  return;
210
207
  }
211
- match = (/^#EXT-X-MEDIA-SEQUENCE:(\-?[0-9.]*)?/).exec(newLine);
208
+ match = (/^#EXT-X-MEDIA-SEQUENCE:?(\-?[0-9.]*)?/).exec(newLine);
212
209
  if (match) {
213
210
  event = {
214
211
  type: 'tag',
@@ -220,7 +217,7 @@ export default class ParseStream extends Stream {
220
217
  this.trigger('data', event);
221
218
  return;
222
219
  }
223
- match = (/^#EXT-X-DISCONTINUITY-SEQUENCE:(\-?[0-9.]*)?/).exec(newLine);
220
+ match = (/^#EXT-X-DISCONTINUITY-SEQUENCE:?(\-?[0-9.]*)?/).exec(newLine);
224
221
  if (match) {
225
222
  event = {
226
223
  type: 'tag',
@@ -232,7 +229,7 @@ export default class ParseStream extends Stream {
232
229
  this.trigger('data', event);
233
230
  return;
234
231
  }
235
- match = (/^#EXT-X-PLAYLIST-TYPE:(.*)?$/).exec(newLine);
232
+ match = (/^#EXT-X-PLAYLIST-TYPE:?(.*)?$/).exec(newLine);
236
233
  if (match) {
237
234
  event = {
238
235
  type: 'tag',
@@ -244,7 +241,7 @@ export default class ParseStream extends Stream {
244
241
  this.trigger('data', event);
245
242
  return;
246
243
  }
247
- match = (/^#EXT-X-BYTERANGE:(.*)?$/).exec(newLine);
244
+ match = (/^#EXT-X-BYTERANGE:?(.*)?$/).exec(newLine);
248
245
  if (match) {
249
246
  event = Object.assign(parseByterange(match[1]), {
250
247
  type: 'tag',
@@ -253,7 +250,7 @@ export default class ParseStream extends Stream {
253
250
  this.trigger('data', event);
254
251
  return;
255
252
  }
256
- match = (/^#EXT-X-ALLOW-CACHE:(YES|NO)?/).exec(newLine);
253
+ match = (/^#EXT-X-ALLOW-CACHE:?(YES|NO)?/).exec(newLine);
257
254
  if (match) {
258
255
  event = {
259
256
  type: 'tag',
@@ -265,7 +262,7 @@ export default class ParseStream extends Stream {
265
262
  this.trigger('data', event);
266
263
  return;
267
264
  }
268
- match = (/^#EXT-X-MAP:(.*)$/).exec(newLine);
265
+ match = (/^#EXT-X-MAP:?(.*)$/).exec(newLine);
269
266
  if (match) {
270
267
  event = {
271
268
  type: 'tag',
@@ -286,7 +283,7 @@ export default class ParseStream extends Stream {
286
283
  this.trigger('data', event);
287
284
  return;
288
285
  }
289
- match = (/^#EXT-X-STREAM-INF:(.*)$/).exec(newLine);
286
+ match = (/^#EXT-X-STREAM-INF:?(.*)$/).exec(newLine);
290
287
  if (match) {
291
288
  event = {
292
289
  type: 'tag',
@@ -320,7 +317,7 @@ export default class ParseStream extends Stream {
320
317
  this.trigger('data', event);
321
318
  return;
322
319
  }
323
- match = (/^#EXT-X-MEDIA:(.*)$/).exec(newLine);
320
+ match = (/^#EXT-X-MEDIA:?(.*)$/).exec(newLine);
324
321
  if (match) {
325
322
  event = {
326
323
  type: 'tag',
@@ -348,7 +345,7 @@ export default class ParseStream extends Stream {
348
345
  });
349
346
  return;
350
347
  }
351
- match = (/^#EXT-X-PROGRAM-DATE-TIME:(.*)$/).exec(newLine);
348
+ match = (/^#EXT-X-PROGRAM-DATE-TIME:?(.*)$/).exec(newLine);
352
349
  if (match) {
353
350
  event = {
354
351
  type: 'tag',
@@ -361,7 +358,7 @@ export default class ParseStream extends Stream {
361
358
  this.trigger('data', event);
362
359
  return;
363
360
  }
364
- match = (/^#EXT-X-KEY:(.*)$/).exec(newLine);
361
+ match = (/^#EXT-X-KEY:?(.*)$/).exec(newLine);
365
362
  if (match) {
366
363
  event = {
367
364
  type: 'tag',
@@ -386,7 +383,7 @@ export default class ParseStream extends Stream {
386
383
  this.trigger('data', event);
387
384
  return;
388
385
  }
389
- match = (/^#EXT-X-START:(.*)$/).exec(newLine);
386
+ match = (/^#EXT-X-START:?(.*)$/).exec(newLine);
390
387
  if (match) {
391
388
  event = {
392
389
  type: 'tag',
@@ -401,7 +398,7 @@ export default class ParseStream extends Stream {
401
398
  this.trigger('data', event);
402
399
  return;
403
400
  }
404
- match = (/^#EXT-X-CUE-OUT-CONT:(.*)?$/).exec(newLine);
401
+ match = (/^#EXT-X-CUE-OUT-CONT:?(.*)?$/).exec(newLine);
405
402
  if (match) {
406
403
  event = {
407
404
  type: 'tag',
@@ -415,7 +412,7 @@ export default class ParseStream extends Stream {
415
412
  this.trigger('data', event);
416
413
  return;
417
414
  }
418
- match = (/^#EXT-X-CUE-OUT:(.*)?$/).exec(newLine);
415
+ match = (/^#EXT-X-CUE-OUT:?(.*)?$/).exec(newLine);
419
416
  if (match) {
420
417
  event = {
421
418
  type: 'tag',
@@ -429,7 +426,7 @@ export default class ParseStream extends Stream {
429
426
  this.trigger('data', event);
430
427
  return;
431
428
  }
432
- match = (/^#EXT-X-CUE-IN:(.*)?$/).exec(newLine);
429
+ match = (/^#EXT-X-CUE-IN:?(.*)?$/).exec(newLine);
433
430
  if (match) {
434
431
  event = {
435
432
  type: 'tag',
package/src/parser.js CHANGED
@@ -140,7 +140,6 @@ export default class Parser extends Stream {
140
140
  // track where next segment starts
141
141
  let nextSegmentLineNumberStart = 0;
142
142
 
143
-
144
143
  this.on('end', () => {
145
144
  // only add preloadSegment if we don't yet have a uri for it.
146
145
  // and we actually have parts/preloadHints
@@ -167,9 +166,9 @@ export default class Parser extends Stream {
167
166
  let mediaGroup;
168
167
  let rendition;
169
168
 
170
- //starting a new segment
169
+ // starting a new segment
171
170
  if (!Object.keys(currentUri).length) {
172
- nextSegmentLineNumberStart = this.lineStream.lineNumber;
171
+ nextSegmentLineNumberStart = this.lineNumber;
173
172
  }
174
173
 
175
174
  ({
@@ -745,7 +744,7 @@ export default class Parser extends Stream {
745
744
  uri() {
746
745
  currentUri.uri = entry.uri;
747
746
  currentUri.lineNumberStart = nextSegmentLineNumberStart;
748
- currentUri.lineNumberEnd = this.lineStream.lineNumber;
747
+ currentUri.lineNumberEnd = this.parseStream.lineNumber;
749
748
  uris.push(currentUri);
750
749
 
751
750
  // if no explicit duration was declared, use the target duration
@@ -242,7 +242,7 @@ QUnit.test('parses #EXTM3U tags', function(assert) {
242
242
 
243
243
  // #EXTINF
244
244
  QUnit.test('parses minimal #EXTINF tags', function(assert) {
245
- const manifest = '#EXTINF:\n';
245
+ const manifest = '#EXTINF\n';
246
246
  let element;
247
247
 
248
248
  this.parseStream.on('data', function(elem) {
@@ -319,7 +319,7 @@ QUnit.test('parses #EXTINF tags with carriage returns', function(assert) {
319
319
 
320
320
  // #EXT-X-TARGETDURATION
321
321
  QUnit.test('parses minimal #EXT-X-TARGETDURATION tags', function(assert) {
322
- const manifest = '#EXT-X-TARGETDURATION:\n';
322
+ const manifest = '#EXT-X-TARGETDURATION\n';
323
323
  let element;
324
324
 
325
325
  this.parseStream.on('data', function(elem) {
@@ -379,7 +379,7 @@ QUnit.test('parses #EXT-X-VERSION with a version', function(assert) {
379
379
 
380
380
  // #EXT-X-MEDIA-SEQUENCE
381
381
  QUnit.test('parses minimal #EXT-X-MEDIA-SEQUENCE tags', function(assert) {
382
- const manifest = '#EXT-X-MEDIA-SEQUENCE:\n';
382
+ const manifest = '#EXT-X-MEDIA-SEQUENCE\n';
383
383
  let element;
384
384
 
385
385
  this.parseStream.on('data', function(elem) {
@@ -453,7 +453,7 @@ QUnit.test('parses #EXT-X-PLAYLIST-TYPE with mutability info', function(assert)
453
453
 
454
454
  // #EXT-X-BYTERANGE
455
455
  QUnit.test('parses minimal #EXT-X-BYTERANGE tags', function(assert) {
456
- const manifest = '#EXT-X-BYTERANGE:\n';
456
+ const manifest = '#EXT-X-BYTERANGE\n';
457
457
  let element;
458
458
 
459
459
  this.parseStream.on('data', function(elem) {
@@ -589,7 +589,7 @@ QUnit.test('parses #EXT-X-MAP tags with arbitrary attributes', function(assert)
589
589
  });
590
590
  // #EXT-X-STREAM-INF
591
591
  QUnit.test('parses minimal #EXT-X-STREAM-INF tags', function(assert) {
592
- const manifest = '#EXT-X-STREAM-INF:\n';
592
+ const manifest = '#EXT-X-STREAM-INF\n';
593
593
  let element;
594
594
 
595
595
  this.parseStream.on('data', function(elem) {
@@ -604,7 +604,7 @@ QUnit.test('parses minimal #EXT-X-STREAM-INF tags', function(assert) {
604
604
  });
605
605
  // #EXT-X-PROGRAM-DATE-TIME
606
606
  QUnit.test('parses minimal EXT-X-PROGRAM-DATE-TIME tags', function(assert) {
607
- const manifest = '#EXT-X-PROGRAM-DATE-TIME:\n';
607
+ const manifest = '#EXT-X-PROGRAM-DATE-TIME\n';
608
608
  let element;
609
609
 
610
610
  this.parseStream.on('data', function(elem) {
@@ -817,6 +817,16 @@ QUnit.test('parses lightly-broken #EXT-X-KEY tags', function(assert) {
817
817
  'parsed a single-quoted uri'
818
818
  );
819
819
 
820
+ element = null;
821
+ manifest = '#EXT-X-KEYURI="https://example.com/key",METHOD=AES-128\n';
822
+ this.lineStream.push(manifest);
823
+ assert.strictEqual(element.tagType, 'key', 'parsed the tag type');
824
+ assert.strictEqual(
825
+ element.attributes.URI,
826
+ 'https://example.com/key',
827
+ 'inferred a colon after the tag type'
828
+ );
829
+
820
830
  element = null;
821
831
  manifest = '#EXT-X-KEY: URI = "https://example.com/key",METHOD=AES-128\n';
822
832
  this.lineStream.push(manifest);
@@ -1,6 +1,6 @@
1
1
  import QUnit from 'qunit';
2
- import testDataExpected from 'data-files!expecteds';
3
- import testDataManifests from 'data-files!manifests';
2
+ // import testDataExpected from 'data-files!expecteds';
3
+ // import testDataManifests from 'data-files!manifests';
4
4
  import {Parser} from '../src';
5
5
 
6
6
  QUnit.module('m3u8s', function(hooks) {
@@ -108,10 +108,11 @@ QUnit.module('m3u8s', function(hooks) {
108
108
  '#EXT-X-CUE-OUT:10',
109
109
  '#EXTINF:5,',
110
110
  'ex2.ts',
111
+ '#EXT-X-CUE-OUT15',
111
112
  '#EXT-UKNOWN-TAG',
112
113
  '#EXTINF:5,',
113
114
  'ex3.ts',
114
- '#EXT-X-CUE-OUT:',
115
+ '#EXT-X-CUE-OUT',
115
116
  '#EXTINF:5,',
116
117
  'ex3.ts',
117
118
  '#EXT-X-ENDLIST'
@@ -121,6 +122,7 @@ QUnit.module('m3u8s', function(hooks) {
121
122
  this.parser.end();
122
123
 
123
124
  assert.equal(this.parser.manifest.segments[1].cueOut, '10', 'parser attached cue out tag');
125
+ assert.equal(this.parser.manifest.segments[2].cueOut, '15', 'cue out without : seperator');
124
126
  assert.equal(this.parser.manifest.segments[3].cueOut, '', 'cue out without data');
125
127
  });
126
128
 
@@ -133,10 +135,11 @@ QUnit.module('m3u8s', function(hooks) {
133
135
  '#EXT-X-CUE-OUT-CONT:10/60',
134
136
  '#EXTINF:5,',
135
137
  'ex2.ts',
138
+ '#EXT-X-CUE-OUT-CONT15/30',
136
139
  '#EXT-UKNOWN-TAG',
137
140
  '#EXTINF:5,',
138
141
  'ex3.ts',
139
- '#EXT-X-CUE-OUT-CONT:',
142
+ '#EXT-X-CUE-OUT-CONT',
140
143
  '#EXTINF:5,',
141
144
  'ex3.ts',
142
145
  '#EXT-X-ENDLIST'
@@ -149,6 +152,10 @@ QUnit.module('m3u8s', function(hooks) {
149
152
  this.parser.manifest.segments[1].cueOutCont, '10/60',
150
153
  'parser attached cue out cont tag'
151
154
  );
155
+ assert.equal(
156
+ this.parser.manifest.segments[2].cueOutCont, '15/30',
157
+ 'cue out cont without : seperator'
158
+ );
152
159
  assert.equal(this.parser.manifest.segments[3].cueOutCont, '', 'cue out cont without data');
153
160
  });
154
161
 
@@ -158,13 +165,14 @@ QUnit.module('m3u8s', function(hooks) {
158
165
  '#EXTINF:5,',
159
166
  '#COMMENT',
160
167
  'ex1.ts',
161
- '#EXT-X-CUE-IN:',
168
+ '#EXT-X-CUE-IN',
162
169
  '#EXTINF:5,',
163
170
  'ex2.ts',
164
171
  '#EXT-X-CUE-IN:15',
165
172
  '#EXT-UKNOWN-TAG',
166
173
  '#EXTINF:5,',
167
174
  'ex3.ts',
175
+ '#EXT-X-CUE-IN=abc',
168
176
  '#EXTINF:5,',
169
177
  'ex3.ts',
170
178
  '#EXT-X-ENDLIST'
@@ -175,6 +183,10 @@ QUnit.module('m3u8s', function(hooks) {
175
183
 
176
184
  assert.equal(this.parser.manifest.segments[1].cueIn, '', 'parser attached cue in tag');
177
185
  assert.equal(this.parser.manifest.segments[2].cueIn, '15', 'cue in with data');
186
+ assert.equal(
187
+ this.parser.manifest.segments[3].cueIn, '=abc',
188
+ 'cue in without colon seperator'
189
+ );
178
190
  });
179
191
 
180
192
  QUnit.test('parses characteristics attribute', function(assert) {
@@ -1187,8 +1199,52 @@ QUnit.module('m3u8s', function(hooks) {
1187
1199
  assert.deepEqual(this.warnings, warning, 'warnings as expected');
1188
1200
  });
1189
1201
 
1202
+ QUnit.test('playlist line numbers ', function(assert) {
1203
+ this.parser.push([
1204
+ '#EXTM3U',
1205
+ '#EXT-X-VERSION:7',
1206
+ '#EXT-X-TARGETDURATION:4',
1207
+ '#EXT-X-MEDIA-SEQUENCE:2421',
1208
+ '#EXT-X-MAP:URI="init.mp4"',
1209
+ '#EXTINF:3.989333,',
1210
+ '#EXT-X-PROGRAM-DATE-TIME:2024-04-17T09:43:19.871-0700',
1211
+ 'stream2421.m4s',
1212
+ '#EXTINF:4.010667,',
1213
+ '#EXT-X-PROGRAM-DATE-TIME:2024-04-17T09:43:23.860-0700',
1214
+ 'stream2422.m4s',
1215
+ '#EXTINF:3.989333,',
1216
+ '#EXT-X-PROGRAM-DATE-TIME:2024-04-17T09:43:27.871-0700',
1217
+ 'stream2423.m4s',
1218
+ '#EXTINF:4.010667,',
1219
+ '#EXT-X-PROGRAM-DATE-TIME:2024-04-17T09:43:31.860-0700',
1220
+ 'stream2424.m4s',
1221
+ '#EXTINF:3.989333,',
1222
+ '#EXT-X-PROGRAM-DATE-TIME:2024-04-17T09:43:35.871-0700',
1223
+ 'stream2425.m4s',
1224
+ '#EXTINF:4.010667,',
1225
+ '#EXT-X-PROGRAM-DATE-TIME:2024-04-17T09:43:39.860-0700',
1226
+ 'stream2426.m4s',
1227
+ '#EXTINF:3.989333,',
1228
+ '#EXT-X-PROGRAM-DATE-TIME:2024-04-17T09:43:43.871-0700',
1229
+ 'stream2427.m4s',
1230
+ '#EXTINF:4.010667,',
1231
+ '#EXT-X-PROGRAM-DATE-TIME:2024-04-17T09:43:47.860-0700',
1232
+ 'stream2428.m4s',
1233
+ '#EXTINF:3.989333,',
1234
+ '#EXT-X-PROGRAM-DATE-TIME:2024-04-17T09:43:51.871-0700',
1235
+ 'stream2429.m4s',
1236
+ '#EXTINF:4.010667,',
1237
+ '#EXT-X-PROGRAM-DATE-TIME:2024-04-17T09:43:55.860-0700',
1238
+ 'stream2430.m4s`'
1239
+ ].join('\n'));
1240
+ this.parser.end();
1241
+ assert.equal(this.parser.manifest.segments[2].lineNumberStart, 12);
1242
+ assert.equal(this.parser.manifest.segments[2].lineNumberEnd, 14);
1243
+ });
1244
+
1190
1245
  QUnit.module('integration');
1191
1246
 
1247
+ /*
1192
1248
  for (const key in testDataExpected) {
1193
1249
  if (!testDataManifests[key]) {
1194
1250
  throw new Error(`${key}.js does not have an equivelent m3u8 manifest to test against`);
@@ -1210,5 +1266,6 @@ QUnit.module('m3u8s', function(hooks) {
1210
1266
  );
1211
1267
  });
1212
1268
  }
1269
+ */
1213
1270
 
1214
1271
  });