@gcorevideo/player 2.10.0 → 2.12.1

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.
Files changed (65) hide show
  1. package/LICENSE +13 -0
  2. package/coverage/clover.xml +6 -0
  3. package/coverage/coverage-final.json +1 -0
  4. package/coverage/lcov-report/base.css +224 -0
  5. package/coverage/lcov-report/block-navigation.js +87 -0
  6. package/coverage/lcov-report/favicon.png +0 -0
  7. package/coverage/lcov-report/index.html +101 -0
  8. package/coverage/lcov-report/prettify.css +1 -0
  9. package/coverage/lcov-report/prettify.js +2 -0
  10. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  11. package/coverage/lcov-report/sorter.js +196 -0
  12. package/coverage/lcov.info +0 -0
  13. package/dist/index.js +3115 -1185
  14. package/lib/Player.d.ts +3 -2
  15. package/lib/Player.d.ts.map +1 -1
  16. package/lib/Player.js +33 -20
  17. package/lib/index.d.ts +6 -5
  18. package/lib/index.d.ts.map +1 -1
  19. package/lib/index.js +5 -5
  20. package/lib/internal.types.d.ts +3 -1
  21. package/lib/internal.types.d.ts.map +1 -1
  22. package/lib/playback/index.d.ts +4 -0
  23. package/lib/playback/index.d.ts.map +1 -0
  24. package/lib/playback/index.js +13 -0
  25. package/lib/playback.types.d.ts +9 -0
  26. package/lib/playback.types.d.ts.map +1 -1
  27. package/lib/playback.types.js +9 -1
  28. package/lib/plugins/dash-playback/DashPlayback.d.ts +0 -1
  29. package/lib/plugins/dash-playback/DashPlayback.d.ts.map +1 -1
  30. package/lib/plugins/dash-playback/DashPlayback.js +32 -96
  31. package/lib/plugins/dash-playback/types.d.ts +6 -0
  32. package/lib/plugins/dash-playback/types.d.ts.map +1 -0
  33. package/lib/plugins/dash-playback/types.js +1 -0
  34. package/lib/plugins/hls-playback/HlsPlayback.d.ts +3 -3
  35. package/lib/plugins/hls-playback/HlsPlayback.d.ts.map +1 -1
  36. package/lib/plugins/hls-playback/HlsPlayback.js +136 -63
  37. package/lib/types.d.ts +3 -3
  38. package/lib/types.d.ts.map +1 -1
  39. package/lib/utils/mediaSources.d.ts +14 -6
  40. package/lib/utils/mediaSources.d.ts.map +1 -1
  41. package/lib/utils/mediaSources.js +56 -53
  42. package/lib/utils/testUtils.d.ts +3 -0
  43. package/lib/utils/testUtils.d.ts.map +1 -0
  44. package/lib/utils/testUtils.js +12 -0
  45. package/package.json +6 -4
  46. package/src/Player.ts +46 -26
  47. package/src/__tests__/Player.test.ts +357 -0
  48. package/src/index.ts +6 -5
  49. package/src/internal.types.ts +3 -1
  50. package/src/playback/index.ts +17 -0
  51. package/src/playback.types.ts +11 -1
  52. package/src/plugins/dash-playback/DashPlayback.ts +38 -114
  53. package/src/plugins/hls-playback/HlsPlayback.ts +561 -386
  54. package/src/types.ts +5 -3
  55. package/src/typings/@clappr/core/error_mixin.d.ts +0 -2
  56. package/src/typings/@clappr/core/index.d.ts +5 -0
  57. package/src/typings/@clappr/index.d.ts +1 -0
  58. package/src/utils/__tests__/mediaSources.test.ts +230 -0
  59. package/src/utils/mediaSources.ts +67 -63
  60. package/src/utils/testUtils.ts +15 -0
  61. package/tsconfig.json +0 -9
  62. package/tsconfig.tsbuildinfo +1 -1
  63. package/vitest.config.ts +8 -0
  64. package/licenses.json +0 -782
  65. package/src/utils/queryParams.ts +0 -5
@@ -1,11 +1,12 @@
1
1
  // Copyright 2014 Globo.com Player authors. All rights reserved.
2
2
  // Use of this source code is governed by a BSD-style
3
3
  // license that can be found in the LICENSE file.
4
- import { Events, HTML5Video, Log, Playback, PlayerError, Utils } from '@clappr/core';
4
+ import { Events, HTML5Video, Log, Playback, PlayerError, Utils, } from '@clappr/core';
5
+ import { trace } from '@gcorevideo/utils';
5
6
  import assert from 'assert';
6
7
  import HLSJS from 'hls.js';
7
- import { trace } from '@gcorevideo/utils';
8
- import { CLAPPR_VERSION } from "../../build.js";
8
+ import { PlaybackErrorCode } from '../../playback.types.js';
9
+ import { CLAPPR_VERSION } from '../../build.js';
9
10
  const { now, listContainsIgnoreCase } = Utils;
10
11
  const AUTO = -1;
11
12
  const DEFAULT_RECOVER_ATTEMPTS = 16;
@@ -75,7 +76,8 @@ export default class HlsPlayback extends HTML5Video {
75
76
  return this._hls.playingDate;
76
77
  }
77
78
  get _startTime() {
78
- if (this._playbackType === Playback.LIVE && this._playlistType !== 'EVENT') {
79
+ if (this._playbackType === Playback.LIVE &&
80
+ this._playlistType !== 'EVENT') {
79
81
  return this._extrapolatedStartTime;
80
82
  }
81
83
  return this._playableRegionStartTime;
@@ -140,7 +142,8 @@ export default class HlsPlayback extends HTML5Video {
140
142
  return { preload: true };
141
143
  }
142
144
  get customListeners() {
143
- return this.options.hlsPlayback && this.options.hlsPlayback.customListeners || [];
145
+ return ((this.options.hlsPlayback && this.options.hlsPlayback.customListeners) ||
146
+ []);
144
147
  }
145
148
  get sourceMedia() {
146
149
  return this.options.src;
@@ -162,17 +165,27 @@ export default class HlsPlayback extends HTML5Video {
162
165
  constructor(...args) {
163
166
  // @ts-ignore
164
167
  super(...args);
165
- this.options.hlsPlayback = { ...this.defaultOptions, ...this.options.hlsPlayback };
168
+ this.options.hlsPlayback = {
169
+ ...this.defaultOptions,
170
+ ...this.options.hlsPlayback,
171
+ };
166
172
  this._setInitialState();
167
173
  }
168
174
  _setInitialState() {
169
175
  // @ts-ignore
170
- this._minDvrSize = typeof (this.options.hlsMinimumDvrSize) === 'undefined' ? 60 : this.options.hlsMinimumDvrSize;
176
+ this._minDvrSize =
177
+ typeof this.options.hlsMinimumDvrSize === 'undefined'
178
+ ? 60
179
+ : this.options.hlsMinimumDvrSize;
171
180
  // The size of the start time extrapolation window measured as a multiple of segments.
172
181
  // Should be 2 or higher, or 0 to disable. Should only need to be increased above 2 if more than one segment is
173
182
  // removed from the start of the playlist at a time. E.g if the playlist is cached for 10 seconds and new chunks are
174
183
  // added/removed every 5.
175
- this._extrapolatedWindowNumSegments = !this.options.playback || typeof (this.options.playback.extrapolatedWindowNumSegments) === 'undefined' ? 2 : this.options.playback.extrapolatedWindowNumSegments;
184
+ this._extrapolatedWindowNumSegments =
185
+ !this.options.playback ||
186
+ typeof this.options.playback.extrapolatedWindowNumSegments === 'undefined'
187
+ ? 2
188
+ : this.options.playback.extrapolatedWindowNumSegments;
176
189
  this._playbackType = Playback.VOD;
177
190
  this._lastTimeUpdate = { current: 0, total: 0 };
178
191
  this._lastDuration = null;
@@ -204,7 +217,8 @@ export default class HlsPlayback extends HTML5Video {
204
217
  // #EXT-X-PLAYLIST-TYPE
205
218
  this._playlistType = null;
206
219
  // TODO options.hlsRecoverAttempts
207
- this._recoverAttemptsRemaining = this.options.hlsRecoverAttempts || DEFAULT_RECOVER_ATTEMPTS;
220
+ this._recoverAttemptsRemaining =
221
+ this.options.hlsRecoverAttempts || DEFAULT_RECOVER_ATTEMPTS;
208
222
  }
209
223
  _setup() {
210
224
  this._destroyHLSInstance();
@@ -247,13 +261,15 @@ export default class HlsPlayback extends HTML5Video {
247
261
  });
248
262
  const onPlaying = () => {
249
263
  if (this._hls) {
250
- this._hls.config.maxBufferLength = this.options.hlsPlayback.maxBufferLength || 30;
251
- this._hls.config.maxMaxBufferLength = this.options.hlsPlayback.maxMaxBufferLength || 60;
264
+ this._hls.config.maxBufferLength =
265
+ this.options.hlsPlayback.maxBufferLength || 30;
266
+ this._hls.config.maxMaxBufferLength =
267
+ this.options.hlsPlayback.maxMaxBufferLength || 60;
252
268
  }
253
269
  this.el.removeEventListener('playing', onPlaying);
254
270
  };
255
271
  this.el.addEventListener('playing', onPlaying);
256
- this._hls.on(HLSJS.Events.MANIFEST_PARSED, () => this._manifestParsed = true);
272
+ this._hls.on(HLSJS.Events.MANIFEST_PARSED, () => (this._manifestParsed = true));
257
273
  this._hls.on(HLSJS.Events.LEVEL_LOADED, (evt, data) => this._updatePlaybackType(evt, data));
258
274
  this._hls.on(HLSJS.Events.LEVEL_UPDATED, (evt, data) => this._onLevelUpdated(evt, data));
259
275
  this._hls.on(HLSJS.Events.LEVEL_SWITCHING, (evt, data) => this._onLevelSwitch(evt, data));
@@ -263,7 +279,7 @@ export default class HlsPlayback extends HTML5Video {
263
279
  this._hls.on(HLSJS.Events.ERROR, (evt, data) => this._onHLSJSError(evt, data));
264
280
  // this._hls.on(HLSJS.Events.SUBTITLE_TRACK_LOADED, (evt, data) => this._onSubtitleLoaded(evt, data));
265
281
  this._hls.on(HLSJS.Events.SUBTITLE_TRACK_LOADED, () => this._onSubtitleLoaded());
266
- this._hls.on(HLSJS.Events.SUBTITLE_TRACKS_UPDATED, () => this._ccTracksUpdated = true);
282
+ this._hls.on(HLSJS.Events.SUBTITLE_TRACKS_UPDATED, () => (this._ccTracksUpdated = true));
267
283
  this.bindCustomListeners();
268
284
  }
269
285
  bindCustomListeners() {
@@ -271,7 +287,8 @@ export default class HlsPlayback extends HTML5Video {
271
287
  const requestedEventName = item.eventName;
272
288
  const typeOfListener = item.once ? 'once' : 'on';
273
289
  assert.ok(this._hls, 'Hls.js instance is not available');
274
- requestedEventName && this._hls[`${typeOfListener}`](requestedEventName, item.callback);
290
+ requestedEventName &&
291
+ this._hls[`${typeOfListener}`](requestedEventName, item.callback);
275
292
  });
276
293
  }
277
294
  unbindCustomListeners() {
@@ -283,7 +300,10 @@ export default class HlsPlayback extends HTML5Video {
283
300
  }
284
301
  _onFragmentParsingMetadata(evt, data) {
285
302
  // @ts-ignore
286
- this.trigger(Events.Custom.PLAYBACK_FRAGMENT_PARSING_METADATA, { evt, data });
303
+ this.trigger(Events.Custom.PLAYBACK_FRAGMENT_PARSING_METADATA, {
304
+ evt,
305
+ data,
306
+ });
287
307
  }
288
308
  render() {
289
309
  this._ready();
@@ -316,7 +336,6 @@ export default class HlsPlayback extends HTML5Video {
316
336
  this.stop();
317
337
  }
318
338
  }
319
- // override
320
339
  // this playback manages the src on the video element itself
321
340
  _setupSrc(srcUrl) { } // eslint-disable-line no-unused-vars
322
341
  _startTimeUpdateTimer() {
@@ -336,7 +355,7 @@ export default class HlsPlayback extends HTML5Video {
336
355
  this._timeUpdateTimer = null;
337
356
  }
338
357
  getProgramDateTime() {
339
- return this._programDateTime;
358
+ return this._programDateTime ?? 0;
340
359
  }
341
360
  // the duration on the video element itself should not be used
342
361
  // as this does not necesarily represent the duration of the stream
@@ -357,9 +376,7 @@ export default class HlsPlayback extends HTML5Video {
357
376
  return this._startTime;
358
377
  }
359
378
  seekPercentage(percentage) {
360
- const seekTo = (percentage > 0)
361
- ? this._duration * (percentage / 100)
362
- : this._duration;
379
+ const seekTo = percentage > 0 ? this._duration * (percentage / 100) : this._duration;
363
380
  this.seek(seekTo);
364
381
  }
365
382
  seek(time) {
@@ -377,7 +394,7 @@ export default class HlsPlayback extends HTML5Video {
377
394
  }
378
395
  _updateDvr(status) {
379
396
  this.trigger(Events.PLAYBACK_DVR, status);
380
- this.trigger(Events.PLAYBACK_STATS_ADD, { 'dvr': status });
397
+ this.trigger(Events.PLAYBACK_STATS_ADD, { dvr: status });
381
398
  }
382
399
  _updateSettings() {
383
400
  if (this._playbackType === Playback.VOD) {
@@ -398,7 +415,8 @@ export default class HlsPlayback extends HTML5Video {
398
415
  }
399
416
  _onHLSJSError(evt, data) {
400
417
  const error = {
401
- code: `${data.type}_${data.details}`,
418
+ // code: `${data.type}_${data.details}`,
419
+ code: PlaybackErrorCode.Generic,
402
420
  description: `${this.name} error: type: ${data.type}, details: ${data.details}`,
403
421
  raw: data,
404
422
  };
@@ -422,13 +440,28 @@ export default class HlsPlayback extends HTML5Video {
422
440
  case HLSJS.ErrorDetails.MANIFEST_PARSING_ERROR:
423
441
  case HLSJS.ErrorDetails.LEVEL_LOAD_ERROR:
424
442
  case HLSJS.ErrorDetails.LEVEL_LOAD_TIMEOUT:
425
- Log.error('hlsjs: unrecoverable network fatal error.', { evt, data });
426
- formattedError = this.createError(error);
443
+ Log.error('hlsjs: unrecoverable network fatal error.', {
444
+ evt,
445
+ data,
446
+ });
447
+ error.code = [
448
+ HLSJS.ErrorDetails.MANIFEST_LOAD_ERROR,
449
+ HLSJS.ErrorDetails.MANIFEST_LOAD_TIMEOUT,
450
+ HLSJS.ErrorDetails.MANIFEST_PARSING_ERROR
451
+ ].includes(data.details)
452
+ ? PlaybackErrorCode.MediaSourceUnavailable
453
+ : PlaybackErrorCode.QualityLevelUnavailable;
454
+ formattedError = this.createError(error, {
455
+ useCodePrefix: false,
456
+ });
427
457
  this.trigger(Events.PLAYBACK_ERROR, formattedError);
428
458
  this.stop();
429
459
  break;
430
460
  default:
431
- Log.warn('hlsjs: trying to recover from network error.', { evt, data });
461
+ Log.warn('hlsjs: trying to recover from network error.', {
462
+ evt,
463
+ data,
464
+ });
432
465
  error.level = PlayerError.Levels.WARN;
433
466
  assert(this._hls, 'Hls.js instance is not available');
434
467
  this._hls.startLoad();
@@ -436,13 +469,18 @@ export default class HlsPlayback extends HTML5Video {
436
469
  }
437
470
  break;
438
471
  case HLSJS.ErrorTypes.MEDIA_ERROR:
439
- Log.warn('hlsjs: trying to recover from media error.', { evt, data });
472
+ Log.warn('hlsjs: trying to recover from media error.', {
473
+ evt,
474
+ data,
475
+ });
440
476
  error.level = PlayerError.Levels.WARN;
441
477
  this._recover(evt, data, error);
442
478
  break;
443
479
  default:
444
480
  Log.error('hlsjs: could not recover from error.', { evt, data });
445
- formattedError = this.createError(error);
481
+ formattedError = this.createError(error, {
482
+ useCodePrefix: false,
483
+ });
446
484
  this.trigger(Events.PLAYBACK_ERROR, formattedError);
447
485
  this.stop();
448
486
  break;
@@ -450,7 +488,10 @@ export default class HlsPlayback extends HTML5Video {
450
488
  }
451
489
  else {
452
490
  Log.error('hlsjs: could not recover from error after maximum number of attempts.', { evt, data });
453
- formattedError = this.createError(error);
491
+ // TODO
492
+ formattedError = this.createError(error, {
493
+ useCodePrefix: false,
494
+ });
454
495
  this.trigger(Events.PLAYBACK_ERROR, formattedError);
455
496
  this.stop();
456
497
  }
@@ -460,9 +501,12 @@ export default class HlsPlayback extends HTML5Video {
460
501
  // playback fatal error if triggerFatalErrorOnResourceDenied playback
461
502
  // option is set. HLSJS.ErrorTypes.KEY_SYSTEM_ERROR are fatal errors
462
503
  // and therefore already handled.
463
- if (this.options.playback.triggerFatalErrorOnResourceDenied && this._keyIsDenied(data)) {
504
+ if (this.options.playback.triggerFatalErrorOnResourceDenied &&
505
+ this._keyIsDenied(data)) {
464
506
  Log.error('hlsjs: could not load decrypt key.', { evt, data });
465
- formattedError = this.createError(error);
507
+ formattedError = this.createError(error, {
508
+ useCodePrefix: false,
509
+ });
466
510
  this.trigger(Events.PLAYBACK_ERROR, formattedError);
467
511
  this.stop();
468
512
  return;
@@ -472,16 +516,21 @@ export default class HlsPlayback extends HTML5Video {
472
516
  }
473
517
  }
474
518
  _keyIsDenied(data) {
475
- return data.type === HLSJS.ErrorTypes.NETWORK_ERROR
476
- && data.details === HLSJS.ErrorDetails.KEY_LOAD_ERROR
477
- && data.response
478
- && data.response.code
479
- && data.response.code >= 400;
519
+ return (data.type === HLSJS.ErrorTypes.NETWORK_ERROR &&
520
+ data.details === HLSJS.ErrorDetails.KEY_LOAD_ERROR &&
521
+ data.response &&
522
+ data.response.code &&
523
+ data.response.code >= 400);
480
524
  }
481
525
  _onTimeUpdate() {
482
- const update = { current: this.getCurrentTime(), total: this.getDuration(), firstFragDateTime: this.getProgramDateTime() };
483
- const isSame = this._lastTimeUpdate && (update.current === this._lastTimeUpdate.current &&
484
- update.total === this._lastTimeUpdate.total);
526
+ const update = {
527
+ current: this.getCurrentTime(),
528
+ total: this.getDuration(),
529
+ firstFragDateTime: this.getProgramDateTime(),
530
+ };
531
+ const isSame = this._lastTimeUpdate &&
532
+ update.current === this._lastTimeUpdate.current &&
533
+ update.total === this._lastTimeUpdate.total;
485
534
  if (isSame) {
486
535
  return;
487
536
  }
@@ -503,19 +552,25 @@ export default class HlsPlayback extends HTML5Video {
503
552
  let buffered = [];
504
553
  let bufferedPos = 0;
505
554
  for (let i = 0; i < this.el.buffered.length; i++) {
506
- buffered = [...buffered, {
555
+ buffered = [
556
+ ...buffered,
557
+ {
507
558
  // for a stream with sliding window dvr something that is buffered my slide off the start of the timeline
508
- start: Math.max(0, this.el.buffered.start(i) - this._playableRegionStartTime),
509
- end: Math.max(0, this.el.buffered.end(i) - this._playableRegionStartTime)
510
- }];
511
- if (this.el.currentTime >= buffered[i].start && this.el.currentTime <= buffered[i].end) {
559
+ start: Math.max(0, this.el.buffered.start(i) -
560
+ this._playableRegionStartTime),
561
+ end: Math.max(0, this.el.buffered.end(i) -
562
+ this._playableRegionStartTime),
563
+ },
564
+ ];
565
+ if (this.el.currentTime >= buffered[i].start &&
566
+ this.el.currentTime <= buffered[i].end) {
512
567
  bufferedPos = i;
513
568
  }
514
569
  }
515
570
  const progress = {
516
571
  start: buffered[bufferedPos].start,
517
572
  current: buffered[bufferedPos].end,
518
- total: this.getDuration()
573
+ total: this.getDuration(),
519
574
  };
520
575
  this.trigger(Events.PLAYBACK_PROGRESS, progress, buffered);
521
576
  }
@@ -528,7 +583,9 @@ export default class HlsPlayback extends HTML5Video {
528
583
  trace(`${T} play`, { hls: !!this._hls, ...this.options.hlsPlayback });
529
584
  !this._hls && this._setup();
530
585
  assert.ok(this._hls, 'Hls.js instance is not available');
531
- !this._manifestParsed && !this.options.hlsPlayback.preload && this._hls.loadSource(this.options.src);
586
+ !this._manifestParsed &&
587
+ !this.options.hlsPlayback.preload &&
588
+ this._hls.loadSource(this.options.src);
532
589
  super.play();
533
590
  this._startTimeUpdateTimer();
534
591
  }
@@ -536,6 +593,7 @@ export default class HlsPlayback extends HTML5Video {
536
593
  if (!this._hls) {
537
594
  return;
538
595
  }
596
+ ;
539
597
  this.el.pause();
540
598
  if (this.dvrEnabled) {
541
599
  this._updateDvr(true);
@@ -558,7 +616,9 @@ export default class HlsPlayback extends HTML5Video {
558
616
  this._playbackType = (data.details.live ? Playback.LIVE : Playback.VOD);
559
617
  this._onLevelUpdated(evt, data);
560
618
  // Live stream subtitle tracks detection hack (may not immediately available)
561
- if (this._ccTracksUpdated && this._playbackType === Playback.LIVE && this.hasClosedCaptionsTracks) {
619
+ if (this._ccTracksUpdated &&
620
+ this._playbackType === Playback.LIVE &&
621
+ this.hasClosedCaptionsTracks) {
562
622
  this._onSubtitleLoaded();
563
623
  }
564
624
  if (prevPlaybackType !== this._playbackType) {
@@ -590,7 +650,7 @@ export default class HlsPlayback extends HTML5Video {
590
650
  }
591
651
  // #EXT-X-PROGRAM-DATE-TIME
592
652
  if (fragments[0].rawProgramDateTime) {
593
- this._programDateTime = fragments[0].rawProgramDateTime;
653
+ this._programDateTime = Number(fragments[0].rawProgramDateTime);
594
654
  }
595
655
  if (this._playableRegionStartTime !== fragments[0].start) {
596
656
  startTimeChanged = true;
@@ -601,7 +661,7 @@ export default class HlsPlayback extends HTML5Video {
601
661
  // set the correlation to map to middle of the extrapolation window
602
662
  this._localStartTimeCorrelation = {
603
663
  local: this._now,
604
- remote: (fragments[0].start + (this._extrapolatedWindowDuration / 2)) * 1000
664
+ remote: (fragments[0].start + this._extrapolatedWindowDuration / 2) * 1000,
605
665
  };
606
666
  }
607
667
  else {
@@ -616,17 +676,19 @@ export default class HlsPlayback extends HTML5Video {
616
676
  // reset correlation so that it sits at the beginning of the first available chunk
617
677
  this._localStartTimeCorrelation = {
618
678
  local: this._now,
619
- remote: fragments[0].start * 1000
679
+ remote: fragments[0].start * 1000,
620
680
  };
621
681
  }
622
- else if (startTime > previousPlayableRegionStartTime + this._extrapolatedWindowDuration) {
682
+ else if (startTime >
683
+ previousPlayableRegionStartTime + this._extrapolatedWindowDuration) {
623
684
  // start time was past the end of the old extrapolation window (so would have been capped)
624
685
  // see if now that time would be inside the window, and if it would be set the correlation
625
686
  // so that it resumes from the time it was at at the end of the old window
626
687
  // update the correlation so that the time starts counting again from the value it's on now
627
688
  this._localStartTimeCorrelation = {
628
689
  local: this._now,
629
- remote: Math.max(fragments[0].start, previousPlayableRegionStartTime + this._extrapolatedWindowDuration) * 1000
690
+ remote: Math.max(fragments[0].start, previousPlayableRegionStartTime +
691
+ this._extrapolatedWindowDuration) * 1000,
630
692
  };
631
693
  }
632
694
  }
@@ -638,7 +700,8 @@ export default class HlsPlayback extends HTML5Video {
638
700
  if (this._playbackType === Playback.LIVE) {
639
701
  const fragmentTargetDuration = data.details.targetduration;
640
702
  const hlsjsConfig = this.options.playback.hlsjsConfig || {};
641
- const liveSyncDurationCount = hlsjsConfig.liveSyncDurationCount || HLSJS.DefaultConfig.liveSyncDurationCount;
703
+ const liveSyncDurationCount = hlsjsConfig.liveSyncDurationCount ||
704
+ HLSJS.DefaultConfig.liveSyncDurationCount;
642
705
  const hiddenAreaDuration = fragmentTargetDuration * liveSyncDurationCount;
643
706
  if (hiddenAreaDuration <= newDuration) {
644
707
  newDuration -= hiddenAreaDuration;
@@ -662,7 +725,7 @@ export default class HlsPlayback extends HTML5Video {
662
725
  // set the correlation to map to the end
663
726
  this._localEndTimeCorrelation = {
664
727
  local: this._now,
665
- remote: endTime * 1000
728
+ remote: endTime * 1000,
666
729
  };
667
730
  }
668
731
  else {
@@ -674,16 +737,17 @@ export default class HlsPlayback extends HTML5Video {
674
737
  if (extrapolatedEndTime > endTime) {
675
738
  this._localEndTimeCorrelation = {
676
739
  local: this._now,
677
- remote: endTime * 1000
740
+ remote: endTime * 1000,
678
741
  };
679
742
  }
680
- else if (extrapolatedEndTime < endTime - this._extrapolatedWindowDuration) {
743
+ else if (extrapolatedEndTime <
744
+ endTime - this._extrapolatedWindowDuration) {
681
745
  // our extrapolated end time is now earlier than the extrapolation window from the actual end time
682
746
  // (maybe a chunk became available early)
683
747
  // reset correlation so that it sits at the beginning of the extrapolation window from the end time
684
748
  this._localEndTimeCorrelation = {
685
749
  local: this._now,
686
- remote: (endTime - this._extrapolatedWindowDuration) * 1000
750
+ remote: (endTime - this._extrapolatedWindowDuration) * 1000,
687
751
  };
688
752
  }
689
753
  else if (extrapolatedEndTime > previousEndTime) {
@@ -691,7 +755,7 @@ export default class HlsPlayback extends HTML5Video {
691
755
  // set the correlation so that it resumes from the time it was at at the end of the old window
692
756
  this._localEndTimeCorrelation = {
693
757
  local: this._now,
694
- remote: previousEndTime * 1000
758
+ remote: previousEndTime * 1000,
695
759
  };
696
760
  }
697
761
  }
@@ -729,13 +793,14 @@ export default class HlsPlayback extends HTML5Video {
729
793
  const currentLevel = this._hls.levels[data.level];
730
794
  if (currentLevel) {
731
795
  // TODO should highDefinition be private and maybe have a read only accessor if it's used somewhere
732
- this.highDefinition = (currentLevel.height >= 720 || (currentLevel.bitrate / 1000) >= 2000);
796
+ this.highDefinition =
797
+ currentLevel.height >= 720 || currentLevel.bitrate / 1000 >= 2000;
733
798
  this.trigger(Events.PLAYBACK_HIGHDEFINITIONUPDATE, this.highDefinition);
734
799
  this.trigger(Events.PLAYBACK_BITRATE, {
735
800
  height: currentLevel.height,
736
801
  width: currentLevel.width,
737
802
  bitrate: currentLevel.bitrate,
738
- level: data.level
803
+ level: data.level,
739
804
  });
740
805
  }
741
806
  }
@@ -744,21 +809,29 @@ export default class HlsPlayback extends HTML5Video {
744
809
  // - the duration does not include content after hlsjs's live sync point
745
810
  // - the playable region duration is longer than the configured duration to enable dvr after
746
811
  // - the playback type is LIVE.
747
- return (this._durationExcludesAfterLiveSyncPoint && this._duration >= this._minDvrSize && this.getPlaybackType() === Playback.LIVE);
812
+ return (this._durationExcludesAfterLiveSyncPoint &&
813
+ this._duration >= this._minDvrSize &&
814
+ this.getPlaybackType() === Playback.LIVE);
748
815
  }
749
816
  getPlaybackType() {
750
817
  return this._playbackType;
751
818
  }
752
819
  isSeekEnabled() {
753
- return (this._playbackType === Playback.VOD || this.dvrEnabled);
820
+ return this._playbackType === Playback.VOD || this.dvrEnabled;
754
821
  }
755
822
  }
756
823
  HlsPlayback.canPlay = function (resource, mimeType) {
757
824
  const resourceParts = resource.split('?')[0].match(/.*\.(.*)$/) || [];
758
- const isHls = ((resourceParts.length > 1 && resourceParts[1].toLowerCase() === 'm3u8') || listContainsIgnoreCase(mimeType, ['application/vnd.apple.mpegurl', 'application/x-mpegURL']));
825
+ const isHls = (resourceParts.length > 1 && resourceParts[1].toLowerCase() === 'm3u8') ||
826
+ listContainsIgnoreCase(mimeType, [
827
+ 'application/vnd.apple.mpegurl',
828
+ 'application/x-mpegURL',
829
+ ]);
759
830
  const hasSupport = HLSJS.isSupported();
760
831
  trace(`${T} canPlay`, {
761
- hasSupport, isHls, resource,
832
+ hasSupport,
833
+ isHls,
834
+ resource,
762
835
  });
763
836
  return !!(hasSupport && isHls);
764
837
  };
package/lib/types.d.ts CHANGED
@@ -38,7 +38,7 @@ export type PlaybackType = 'live' | 'vod';
38
38
  /**
39
39
  * @beta
40
40
  */
41
- export type MediaTransport = 'dash' | 'hls' | 'mpegts';
41
+ export type MediaTransport = 'dash' | 'hls';
42
42
  /**
43
43
  * @beta
44
44
  */
@@ -49,7 +49,7 @@ export type TransportPreference = MediaTransport | 'auto';
49
49
  */
50
50
  export type PlayerPlugin = {
51
51
  new (...args: any[]): unknown;
52
- type: 'core' | 'container';
52
+ name: string;
53
53
  };
54
54
  /**
55
55
  * Configuration options for the player
@@ -143,7 +143,7 @@ export interface PlayerConfig extends Record<string, unknown> {
143
143
  /**
144
144
  * Localization strings for the player UI.
145
145
  */
146
- strings: TranslationSettings;
146
+ strings?: TranslationSettings;
147
147
  }
148
148
  /**
149
149
  * @beta
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,qBAAqB,CAAA;AAE9D;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAA;AAEvE;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,OAAO,CAAA;AAE1D;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,KAAK,CAAA;AAEzC;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAA;AAEtD;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,MAAM,CAAA;AAEzD;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAA;IAC7B,IAAI,EAAE,MAAM,GAAG,WAAW,CAAA;CAC3B,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,MAAM,WAAW,YAAa,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC3D;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAElB;;;;OAIG;IACH,IAAI,CAAC,EAAE,YAAY,CAAA;IAEnB;;;OAGG;IACH,KAAK,CAAC,EAAE,mBAAmB,CAAA;IAE3B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;IAEd;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;IAEd;;;;OAIG;IACH,YAAY,CAAC,EAAE,YAAY,CAAA;IAE3B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,mBAAmB,CAAA;IAEvC;;OAEG;IACH,OAAO,EAAE,iBAAiB,EAAE,CAAA;IAE5B;;OAEG;IACH,OAAO,EAAE,mBAAmB,CAAA;CAC7B;AAED;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,CAAA;AAE5B;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAA;AAEnC;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAElD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,CACvC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAChD,CAAA;AAED;;;GAGG;AACH,oBAAY,WAAW;IACrB;;OAEG;IACH,KAAK,UAAU;IACf;;OAEG;IACH,IAAI,SAAS;IACb;;OAEG;IACH,KAAK,UAAU;IACf;;OAEG;IACH,IAAI,SAAS;IACb;;OAEG;IACH,KAAK,UAAU;CAChB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,qBAAqB,CAAA;AAE9D;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAA;AAEvE;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,OAAO,CAAA;AAE1D;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,KAAK,CAAA;AAEzC;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,KAAK,CAAA;AAE3C;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,MAAM,CAAA;AAEzD;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAA;IAC7B,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,MAAM,WAAW,YAAa,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC3D;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAElB;;;;OAIG;IACH,IAAI,CAAC,EAAE,YAAY,CAAA;IAEnB;;;OAGG;IACH,KAAK,CAAC,EAAE,mBAAmB,CAAA;IAE3B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;IAEd;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;IAEd;;;;OAIG;IACH,YAAY,CAAC,EAAE,YAAY,CAAA;IAE3B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,mBAAmB,CAAA;IAEvC;;OAEG;IACH,OAAO,EAAE,iBAAiB,EAAE,CAAA;IAE5B;;OAEG;IACH,OAAO,CAAC,EAAE,mBAAmB,CAAA;CAC9B;AAED;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,CAAA;AAE5B;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAA;AAEnC;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAElD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,CACvC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAChD,CAAA;AAED;;;GAGG;AACH,oBAAY,WAAW;IACrB;;OAEG;IACH,KAAK,UAAU;IACf;;OAEG;IACH,IAAI,SAAS;IACb;;OAEG;IACH,KAAK,UAAU;IACf;;OAEG;IACH,IAAI,SAAS;IACb;;OAEG;IACH,KAAK,UAAU;CAChB"}
@@ -1,11 +1,19 @@
1
- import type { PlayerMediaSource, TransportPreference } from '../types';
1
+ import type { PlayerMediaSource, PlayerMediaSourceDesc, TransportPreference } from '../types';
2
2
  export type SourceVariants = {
3
- dash: string | null;
4
- master: string | null;
5
- hls: string | null;
6
- mpegts: string | null;
3
+ dash: PlayerMediaSourceDesc | null;
4
+ hls: PlayerMediaSourceDesc | null;
5
+ mpegts: PlayerMediaSourceDesc | null;
7
6
  };
7
+ /**
8
+ *
9
+ * @param sources
10
+ * @deprecated
11
+ * @returns
12
+ */
8
13
  export declare function buildSourcesSet(sources: PlayerMediaSource[]): SourceVariants;
9
- export declare function buildSourcesPriorityList(sources: SourceVariants, priorityTransport?: TransportPreference): PlayerMediaSource[];
14
+ export declare function buildMediaSourcesList(sources: PlayerMediaSourceDesc[], priorityTransport?: TransportPreference): PlayerMediaSourceDesc[];
10
15
  export declare function unwrapSource(s: PlayerMediaSource): string;
16
+ export declare function wrapSource(s: PlayerMediaSource): PlayerMediaSourceDesc;
17
+ export declare function isDashSource(source: string, mimeType?: string): boolean;
18
+ export declare function isHlsSource(source: string, mimeType?: string): boolean;
11
19
  //# sourceMappingURL=mediaSources.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mediaSources.d.ts","sourceRoot":"","sources":["../../src/utils/mediaSources.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAEtE,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB,CAAA;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,cAAc,CAkB5E;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,cAAc,EACvB,iBAAiB,GAAE,mBAA4B,GAC9C,iBAAiB,EAAE,CAmDrB;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAEzD"}
1
+ {"version":3,"file":"mediaSources.d.ts","sourceRoot":"","sources":["../../src/utils/mediaSources.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAG7F,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,qBAAqB,GAAG,IAAI,CAAA;IAClC,GAAG,EAAE,qBAAqB,GAAG,IAAI,CAAA;IACjC,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAAA;CACrC,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,cAAc,CAiB5E;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,qBAAqB,EAAE,EAChC,iBAAiB,GAAE,mBAA4B,GAC9C,qBAAqB,EAAE,CAsBzB;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAEzD;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,iBAAiB,GAAG,qBAAqB,CAEtE;AAYD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,WAK7D;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,WAO5D"}