rx-player 3.27.0 → 3.27.1-dev.2022041500

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 (79) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/VERSION +1 -1
  3. package/dist/_esm5.processed/core/abr/abr_manager.d.ts +7 -3
  4. package/dist/_esm5.processed/core/abr/abr_manager.js +4 -3
  5. package/dist/_esm5.processed/core/abr/representation_estimator.d.ts +13 -8
  6. package/dist/_esm5.processed/core/abr/representation_estimator.js +4 -4
  7. package/dist/_esm5.processed/core/api/public_api.js +13 -14
  8. package/dist/_esm5.processed/core/init/content_time_boundaries_observer.d.ts +52 -0
  9. package/dist/_esm5.processed/core/init/content_time_boundaries_observer.js +223 -0
  10. package/dist/_esm5.processed/core/init/create_stream_playback_observer.js +17 -6
  11. package/dist/_esm5.processed/core/init/get_initial_time.d.ts +30 -5
  12. package/dist/_esm5.processed/core/init/get_initial_time.js +20 -13
  13. package/dist/_esm5.processed/core/init/load_on_media_source.js +16 -3
  14. package/dist/_esm5.processed/core/init/media_duration_updater.d.ts +56 -0
  15. package/dist/_esm5.processed/core/init/media_duration_updater.js +188 -0
  16. package/dist/_esm5.processed/core/stream/adaptation/adaptation_stream.d.ts +2 -5
  17. package/dist/_esm5.processed/core/stream/adaptation/create_representation_estimator.d.ts +3 -2
  18. package/dist/_esm5.processed/core/stream/adaptation/create_representation_estimator.js +3 -3
  19. package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +2 -22
  20. package/dist/_esm5.processed/core/stream/period/period_stream.d.ts +2 -5
  21. package/dist/_esm5.processed/core/stream/period/period_stream.js +6 -4
  22. package/dist/_esm5.processed/core/stream/representation/get_buffer_status.d.ts +4 -2
  23. package/dist/_esm5.processed/core/stream/representation/get_buffer_status.js +85 -42
  24. package/dist/_esm5.processed/core/stream/representation/representation_stream.js +3 -3
  25. package/dist/_esm5.processed/manifest/manifest.d.ts +14 -5
  26. package/dist/_esm5.processed/manifest/manifest.js +31 -12
  27. package/dist/_esm5.processed/manifest/period.d.ts +6 -0
  28. package/dist/_esm5.processed/manifest/period.js +9 -0
  29. package/dist/_esm5.processed/manifest/representation_index/types.d.ts +7 -2
  30. package/dist/_esm5.processed/parsers/manifest/dash/common/get_minimum_and_maximum_positions.d.ts +5 -1
  31. package/dist/_esm5.processed/parsers/manifest/dash/common/get_minimum_and_maximum_positions.js +6 -4
  32. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/base.js +2 -1
  33. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/list.d.ts +4 -0
  34. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/list.js +4 -2
  35. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/template.js +4 -2
  36. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.js +3 -3
  37. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_mpd.js +28 -20
  38. package/dist/_esm5.processed/parsers/manifest/local/parse_local_manifest.js +3 -2
  39. package/dist/_esm5.processed/parsers/manifest/metaplaylist/metaplaylist_parser.js +9 -3
  40. package/dist/_esm5.processed/parsers/manifest/smooth/create_parser.js +26 -17
  41. package/dist/_esm5.processed/parsers/manifest/types.d.ts +45 -17
  42. package/dist/_esm5.processed/parsers/manifest/utils/{get_maximum_position.d.ts → get_maximum_positions.d.ts} +4 -1
  43. package/dist/_esm5.processed/parsers/manifest/utils/{get_maximum_position.js → get_maximum_positions.js} +10 -6
  44. package/dist/rx-player.js +854 -351
  45. package/dist/rx-player.min.js +1 -1
  46. package/package.json +1 -1
  47. package/sonar-project.properties +1 -1
  48. package/src/core/abr/abr_manager.ts +11 -3
  49. package/src/core/abr/representation_estimator.ts +17 -10
  50. package/src/core/api/public_api.ts +13 -15
  51. package/src/core/init/content_time_boundaries_observer.ts +312 -0
  52. package/src/core/init/create_stream_playback_observer.ts +18 -7
  53. package/src/core/init/get_initial_time.ts +52 -19
  54. package/src/core/init/load_on_media_source.ts +22 -5
  55. package/src/core/init/media_duration_updater.ts +268 -0
  56. package/src/core/stream/adaptation/adaptation_stream.ts +2 -5
  57. package/src/core/stream/adaptation/create_representation_estimator.ts +6 -3
  58. package/src/core/stream/orchestrator/stream_orchestrator.ts +2 -29
  59. package/src/core/stream/period/period_stream.ts +12 -9
  60. package/src/core/stream/representation/get_buffer_status.ts +102 -41
  61. package/src/core/stream/representation/representation_stream.ts +3 -3
  62. package/src/manifest/__tests__/manifest.test.ts +94 -68
  63. package/src/manifest/manifest.ts +73 -33
  64. package/src/manifest/period.ts +10 -0
  65. package/src/manifest/representation_index/types.ts +7 -2
  66. package/src/parsers/manifest/dash/common/get_minimum_and_maximum_positions.ts +10 -5
  67. package/src/parsers/manifest/dash/common/indexes/base.ts +4 -3
  68. package/src/parsers/manifest/dash/common/indexes/list.ts +8 -1
  69. package/src/parsers/manifest/dash/common/indexes/template.ts +8 -3
  70. package/src/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.ts +7 -7
  71. package/src/parsers/manifest/dash/common/parse_mpd.ts +38 -20
  72. package/src/parsers/manifest/local/parse_local_manifest.ts +3 -2
  73. package/src/parsers/manifest/metaplaylist/metaplaylist_parser.ts +9 -4
  74. package/src/parsers/manifest/smooth/create_parser.ts +36 -18
  75. package/src/parsers/manifest/types.ts +45 -17
  76. package/src/parsers/manifest/utils/{get_maximum_position.ts → get_maximum_positions.ts} +13 -7
  77. package/dist/_esm5.processed/core/init/duration_updater.d.ts +0 -27
  78. package/dist/_esm5.processed/core/init/duration_updater.js +0 -136
  79. package/src/core/init/duration_updater.ts +0 -206
package/dist/rx-player.js CHANGED
@@ -16734,6 +16734,16 @@ var Period = /*#__PURE__*/function () {
16734
16734
  return adaptationsForType.filter(function (ada) {
16735
16735
  return ada.isSupported;
16736
16736
  });
16737
+ }
16738
+ /**
16739
+ * Returns true if the give time is in the time boundaries of this `Period`.
16740
+ * @param {number} time
16741
+ * @returns {boolean}
16742
+ */
16743
+ ;
16744
+
16745
+ _proto.containsTime = function containsTime(time) {
16746
+ return time >= this.start && (this.end === undefined || time < this.end);
16737
16747
  };
16738
16748
 
16739
16749
  return Period;
@@ -17360,48 +17370,72 @@ var Manifest = /*#__PURE__*/function (_EventEmitter) {
17360
17370
  this._performUpdate(newManifest, MANIFEST_UPDATE_TYPE.Partial);
17361
17371
  }
17362
17372
  /**
17363
- * Get the minimum position currently defined by the Manifest, in seconds.
17373
+ * Returns the theoretical minimum playable position on the content
17374
+ * regardless of the current Adaptation chosen, as estimated at parsing
17375
+ * time.
17364
17376
  * @returns {number}
17365
17377
  */
17366
17378
  ;
17367
17379
 
17368
- _proto.getMinimumPosition = function getMinimumPosition() {
17380
+ _proto.getMinimumSafePosition = function getMinimumSafePosition() {
17369
17381
  var _a, _b;
17370
17382
 
17371
17383
  var windowData = this._timeBounds;
17372
17384
 
17373
17385
  if (windowData.timeshiftDepth === null) {
17374
- return (_a = windowData.absoluteMinimumTime) !== null && _a !== void 0 ? _a : 0;
17386
+ return (_a = windowData.minimumSafePosition) !== null && _a !== void 0 ? _a : 0;
17375
17387
  }
17376
17388
 
17377
17389
  var maximumTimeData = windowData.maximumTimeData;
17378
17390
  var maximumTime;
17379
17391
 
17380
17392
  if (!windowData.maximumTimeData.isLinear) {
17381
- maximumTime = maximumTimeData.value;
17393
+ maximumTime = maximumTimeData.maximumSafePosition;
17382
17394
  } else {
17383
17395
  var timeDiff = performance.now() - maximumTimeData.time;
17384
- maximumTime = maximumTimeData.value + timeDiff / 1000;
17396
+ maximumTime = maximumTimeData.maximumSafePosition + timeDiff / 1000;
17385
17397
  }
17386
17398
 
17387
17399
  var theoricalMinimum = maximumTime - windowData.timeshiftDepth;
17388
- return Math.max((_b = windowData.absoluteMinimumTime) !== null && _b !== void 0 ? _b : 0, theoricalMinimum);
17400
+ return Math.max((_b = windowData.minimumSafePosition) !== null && _b !== void 0 ? _b : 0, theoricalMinimum);
17389
17401
  }
17390
17402
  /**
17391
- * Get the maximum position currently defined by the Manifest, in seconds.
17392
- * @returns {number}
17403
+ * Get the position of the live edge - that is, the position of what is
17404
+ * currently being broadcasted, in seconds.
17405
+ * @returns {number|undefined}
17393
17406
  */
17394
17407
  ;
17395
17408
 
17396
- _proto.getMaximumPosition = function getMaximumPosition() {
17409
+ _proto.getLivePosition = function getLivePosition() {
17397
17410
  var maximumTimeData = this._timeBounds.maximumTimeData;
17398
17411
 
17412
+ if (!this.isLive || maximumTimeData.livePosition === undefined) {
17413
+ return undefined;
17414
+ }
17415
+
17399
17416
  if (!maximumTimeData.isLinear) {
17400
- return maximumTimeData.value;
17417
+ return maximumTimeData.livePosition;
17401
17418
  }
17402
17419
 
17403
17420
  var timeDiff = performance.now() - maximumTimeData.time;
17404
- return maximumTimeData.value + timeDiff / 1000;
17421
+ return maximumTimeData.livePosition + timeDiff / 1000;
17422
+ }
17423
+ /**
17424
+ * Returns the theoretical maximum playable position on the content
17425
+ * regardless of the current Adaptation chosen, as estimated at parsing
17426
+ * time.
17427
+ */
17428
+ ;
17429
+
17430
+ _proto.getMaximumSafePosition = function getMaximumSafePosition() {
17431
+ var maximumTimeData = this._timeBounds.maximumTimeData;
17432
+
17433
+ if (!maximumTimeData.isLinear) {
17434
+ return maximumTimeData.maximumSafePosition;
17435
+ }
17436
+
17437
+ var timeDiff = performance.now() - maximumTimeData.time;
17438
+ return maximumTimeData.maximumSafePosition + timeDiff / 1000;
17405
17439
  }
17406
17440
  /**
17407
17441
  * Look in the Manifest for Representations linked to the given key ID,
@@ -17615,7 +17649,7 @@ var Manifest = /*#__PURE__*/function (_EventEmitter) {
17615
17649
  // This can become a memory problem when playing a content long enough.
17616
17650
  // Let's clean manually Periods behind the minimum possible position.
17617
17651
 
17618
- var min = this.getMinimumPosition();
17652
+ var min = this.getMinimumSafePosition();
17619
17653
 
17620
17654
  while (this.periods.length > 0) {
17621
17655
  var period = this.periods[0];
@@ -19195,6 +19229,8 @@ var BaseRepresentationIndex = /*#__PURE__*/function () {
19195
19229
  ;
19196
19230
 
19197
19231
  _proto.getLastPosition = function getLastPosition() {
19232
+ var _a;
19233
+
19198
19234
  var timeline = this._index.timeline;
19199
19235
 
19200
19236
  if (timeline.length === 0) {
@@ -19202,7 +19238,7 @@ var BaseRepresentationIndex = /*#__PURE__*/function () {
19202
19238
  }
19203
19239
 
19204
19240
  var lastTimelineElement = timeline[timeline.length - 1];
19205
- var lastTime = (0,_utils_index_helpers__WEBPACK_IMPORTED_MODULE_1__/* .getIndexSegmentEnd */ .jH)(lastTimelineElement, null, this._scaledPeriodEnd);
19241
+ var lastTime = Math.min((0,_utils_index_helpers__WEBPACK_IMPORTED_MODULE_1__/* .getIndexSegmentEnd */ .jH)(lastTimelineElement, null, this._scaledPeriodEnd), (_a = this._scaledPeriodEnd) !== null && _a !== void 0 ? _a : Infinity);
19206
19242
  return (0,_utils_index_helpers__WEBPACK_IMPORTED_MODULE_1__/* .fromIndexTime */ .zG)(lastTime, this._index);
19207
19243
  }
19208
19244
  /**
@@ -19623,7 +19659,7 @@ function createDashUrlDetokenizer(time, nb) {
19623
19659
 
19624
19660
  /***/ }),
19625
19661
 
19626
- /***/ 3501:
19662
+ /***/ 4846:
19627
19663
  /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
19628
19664
 
19629
19665
  "use strict";
@@ -19766,7 +19802,7 @@ function getLastPositionFromAdaptation(adaptation) {
19766
19802
 
19767
19803
  return min;
19768
19804
  }
19769
- ;// CONCATENATED MODULE: ./src/parsers/manifest/utils/get_maximum_position.ts
19805
+ ;// CONCATENATED MODULE: ./src/parsers/manifest/utils/get_maximum_positions.ts
19770
19806
  /**
19771
19807
  * Copyright 2015 CANAL+ Group
19772
19808
  *
@@ -19804,7 +19840,10 @@ function getMaximumPosition(periods) {
19804
19840
  var lastPosition = getLastPositionFromAdaptation(firstAudioAdaptationFromPeriod);
19805
19841
 
19806
19842
  if (lastPosition === undefined) {
19807
- return undefined;
19843
+ return {
19844
+ safe: undefined,
19845
+ unsafe: undefined
19846
+ };
19808
19847
  }
19809
19848
 
19810
19849
  maximumAudioPosition = lastPosition;
@@ -19814,7 +19853,10 @@ function getMaximumPosition(periods) {
19814
19853
  var _lastPosition = getLastPositionFromAdaptation(firstVideoAdaptationFromPeriod);
19815
19854
 
19816
19855
  if (_lastPosition === undefined) {
19817
- return undefined;
19856
+ return {
19857
+ safe: undefined,
19858
+ unsafe: undefined
19859
+ };
19818
19860
  }
19819
19861
 
19820
19862
  maximumVideoPosition = _lastPosition;
@@ -19822,22 +19864,39 @@ function getMaximumPosition(periods) {
19822
19864
 
19823
19865
  if (firstAudioAdaptationFromPeriod !== undefined && maximumAudioPosition === null || firstVideoAdaptationFromPeriod !== undefined && maximumVideoPosition === null) {
19824
19866
  log/* default.info */.Z.info("Parser utils: found Period with no segment. ", "Going to previous one to calculate last position");
19825
- return undefined;
19867
+ return {
19868
+ safe: undefined,
19869
+ unsafe: undefined
19870
+ };
19826
19871
  }
19827
19872
 
19828
19873
  if (maximumVideoPosition !== null) {
19829
19874
  if (maximumAudioPosition !== null) {
19830
- return Math.min(maximumAudioPosition, maximumVideoPosition);
19875
+ return {
19876
+ safe: Math.min(maximumAudioPosition, maximumVideoPosition),
19877
+ unsafe: Math.max(maximumAudioPosition, maximumVideoPosition)
19878
+ };
19831
19879
  }
19832
19880
 
19833
- return maximumVideoPosition;
19881
+ return {
19882
+ safe: maximumVideoPosition,
19883
+ unsafe: maximumVideoPosition
19884
+ };
19834
19885
  }
19835
19886
 
19836
19887
  if (maximumAudioPosition !== null) {
19837
- return maximumAudioPosition;
19888
+ return {
19889
+ safe: maximumAudioPosition,
19890
+ unsafe: maximumAudioPosition
19891
+ };
19838
19892
  }
19839
19893
  }
19840
19894
  }
19895
+
19896
+ return {
19897
+ safe: undefined,
19898
+ unsafe: undefined
19899
+ };
19841
19900
  }
19842
19901
  ;// CONCATENATED MODULE: ./src/parsers/manifest/utils/get_first_time_from_adaptation.ts
19843
19902
  /**
@@ -19986,12 +20045,18 @@ function getMinimumPosition(periods) {
19986
20045
  * @returns {Array.<number>}
19987
20046
  */
19988
20047
 
19989
- function getMinimumAndMaximumPosition(periods) {
20048
+ function getMinimumAndMaximumPositions(periods) {
19990
20049
  if (periods.length === 0) {
19991
20050
  throw new Error("DASH Parser: no period available for a dynamic content");
19992
20051
  }
19993
20052
 
19994
- return [getMinimumPosition(periods), getMaximumPosition(periods)];
20053
+ var minimumSafePosition = getMinimumPosition(periods);
20054
+ var maxPositions = getMaximumPosition(periods);
20055
+ return {
20056
+ minimumSafePosition: minimumSafePosition,
20057
+ maximumSafePosition: maxPositions.safe,
20058
+ maximumUnsafePosition: maxPositions.unsafe
20059
+ };
19995
20060
  }
19996
20061
  ;// CONCATENATED MODULE: ./src/parsers/manifest/dash/common/parse_availability_start_time.ts
19997
20062
  /**
@@ -20618,12 +20683,14 @@ var ListRepresentationIndex = /*#__PURE__*/function () {
20618
20683
  }
20619
20684
 
20620
20685
  var periodStart = context.periodStart,
20686
+ periodEnd = context.periodEnd,
20621
20687
  representationBaseURLs = context.representationBaseURLs,
20622
20688
  representationId = context.representationId,
20623
20689
  representationBitrate = context.representationBitrate,
20624
20690
  isEMSGWhitelisted = context.isEMSGWhitelisted;
20625
20691
  this._isEMSGWhitelisted = isEMSGWhitelisted;
20626
20692
  this._periodStart = periodStart;
20693
+ this._periodEnd = periodEnd;
20627
20694
  var presentationTimeOffset = index.presentationTimeOffset != null ? index.presentationTimeOffset : 0;
20628
20695
  var timescale = (_a = index.timescale) !== null && _a !== void 0 ? _a : 1;
20629
20696
  var indexTimeOffset = presentationTimeOffset - periodStart * timescale;
@@ -20746,10 +20813,12 @@ var ListRepresentationIndex = /*#__PURE__*/function () {
20746
20813
  ;
20747
20814
 
20748
20815
  _proto.getLastPosition = function getLastPosition() {
20816
+ var _a;
20817
+
20749
20818
  var index = this._index;
20750
20819
  var duration = index.duration,
20751
20820
  list = index.list;
20752
- return list.length * duration / index.timescale + this._periodStart;
20821
+ return Math.min(list.length * duration / index.timescale + this._periodStart, (_a = this._periodEnd) !== null && _a !== void 0 ? _a : Infinity);
20753
20822
  }
20754
20823
  /**
20755
20824
  * Returns true if a Segment returned by this index is still considered
@@ -21385,7 +21454,7 @@ var TimelineRepresentationIndex = /*#__PURE__*/function () {
21385
21454
  timescale: timescale
21386
21455
  };
21387
21456
  this._scaledPeriodStart = (0,index_helpers/* toIndexTime */.gT)(periodStart, this._index);
21388
- this._scaledPeriodEnd = periodEnd == null ? undefined : (0,index_helpers/* toIndexTime */.gT)(periodEnd, this._index);
21457
+ this._scaledPeriodEnd = periodEnd === undefined ? undefined : (0,index_helpers/* toIndexTime */.gT)(periodEnd, this._index);
21389
21458
  }
21390
21459
  /**
21391
21460
  * Construct init Segment.
@@ -21475,7 +21544,7 @@ var TimelineRepresentationIndex = /*#__PURE__*/function () {
21475
21544
  this._index.timeline = this._getTimeline();
21476
21545
  }
21477
21546
 
21478
- var lastTime = TimelineRepresentationIndex.getIndexEnd(this._index.timeline, this._scaledPeriodStart);
21547
+ var lastTime = TimelineRepresentationIndex.getIndexEnd(this._index.timeline, this._scaledPeriodEnd);
21479
21548
  return lastTime === null ? null : (0,index_helpers/* fromIndexTime */.zG)(lastTime, this._index);
21480
21549
  }
21481
21550
  /**
@@ -21675,7 +21744,7 @@ var TimelineRepresentationIndex = /*#__PURE__*/function () {
21675
21744
  return null;
21676
21745
  }
21677
21746
 
21678
- return (0,index_helpers/* getIndexSegmentEnd */.jH)(timeline[timeline.length - 1], null, scaledPeriodEnd);
21747
+ return Math.min((0,index_helpers/* getIndexSegmentEnd */.jH)(timeline[timeline.length - 1], null, scaledPeriodEnd), scaledPeriodEnd !== null && scaledPeriodEnd !== void 0 ? scaledPeriodEnd : Infinity);
21679
21748
  }
21680
21749
  /**
21681
21750
  * Allows to generate the "timeline" for this RepresentationIndex.
@@ -21837,7 +21906,7 @@ var TemplateRepresentationIndex = /*#__PURE__*/function () {
21837
21906
  };
21838
21907
  this._isDynamic = isDynamic;
21839
21908
  this._periodStart = periodStart;
21840
- this._scaledPeriodEnd = periodEnd == null ? undefined : (periodEnd - periodStart) * timescale;
21909
+ this._scaledPeriodEnd = periodEnd === undefined ? undefined : (periodEnd - periodStart) * timescale;
21841
21910
  this._isEMSGWhitelisted = isEMSGWhitelisted;
21842
21911
  }
21843
21912
  /**
@@ -21944,6 +22013,8 @@ var TemplateRepresentationIndex = /*#__PURE__*/function () {
21944
22013
  ;
21945
22014
 
21946
22015
  _proto.getLastPosition = function getLastPosition() {
22016
+ var _a;
22017
+
21947
22018
  var lastSegmentStart = this._getLastSegmentStart();
21948
22019
 
21949
22020
  if (lastSegmentStart == null) {
@@ -21953,7 +22024,7 @@ var TemplateRepresentationIndex = /*#__PURE__*/function () {
21953
22024
  return lastSegmentStart;
21954
22025
  }
21955
22026
 
21956
- var lastSegmentEnd = lastSegmentStart + this._index.duration;
22027
+ var lastSegmentEnd = Math.min(lastSegmentStart + this._index.duration, (_a = this._scaledPeriodEnd) !== null && _a !== void 0 ? _a : Infinity);
21957
22028
  return lastSegmentEnd / this._index.timescale + this._periodStart;
21958
22029
  }
21959
22030
  /**
@@ -23591,64 +23662,77 @@ function parseCompleteIntermediateRepresentation(mpdIR, args, warnings, xlinkInf
23591
23662
  lifetime = rootAttributes.minimumUpdatePeriod === 0 ? config/* default.getCurrent */.Z.getCurrent().DASH_FALLBACK_LIFETIME_WHEN_MINIMUM_UPDATE_PERIOD_EQUAL_0 : rootAttributes.minimumUpdatePeriod;
23592
23663
  }
23593
23664
 
23594
- var _getMinimumAndMaximum = getMinimumAndMaximumPosition(parsedPeriods),
23595
- contentStart = _getMinimumAndMaximum[0],
23596
- contentEnd = _getMinimumAndMaximum[1];
23665
+ var _getMinimumAndMaximum = getMinimumAndMaximumPositions(parsedPeriods),
23666
+ minimumSafePosition = _getMinimumAndMaximum.minimumSafePosition,
23667
+ maximumSafePosition = _getMinimumAndMaximum.maximumSafePosition,
23668
+ maximumUnsafePosition = _getMinimumAndMaximum.maximumUnsafePosition;
23597
23669
 
23598
23670
  var now = performance.now();
23599
23671
 
23600
23672
  if (!isDynamic) {
23601
- minimumTime = contentStart !== undefined ? contentStart : ((_a = parsedPeriods[0]) === null || _a === void 0 ? void 0 : _a.start) !== undefined ? parsedPeriods[0].start : 0;
23602
- var maximumTime = mediaPresentationDuration !== null && mediaPresentationDuration !== void 0 ? mediaPresentationDuration : Infinity;
23673
+ minimumTime = minimumSafePosition !== undefined ? minimumSafePosition : ((_a = parsedPeriods[0]) === null || _a === void 0 ? void 0 : _a.start) !== undefined ? parsedPeriods[0].start : 0;
23674
+ var finalMaximumSafePosition = mediaPresentationDuration !== null && mediaPresentationDuration !== void 0 ? mediaPresentationDuration : Infinity;
23603
23675
 
23604
23676
  if (parsedPeriods[parsedPeriods.length - 1] !== undefined) {
23605
23677
  var lastPeriod = parsedPeriods[parsedPeriods.length - 1];
23606
23678
  var lastPeriodEnd = (_b = lastPeriod.end) !== null && _b !== void 0 ? _b : lastPeriod.duration !== undefined ? lastPeriod.start + lastPeriod.duration : undefined;
23607
23679
 
23608
- if (lastPeriodEnd !== undefined && lastPeriodEnd < maximumTime) {
23609
- maximumTime = lastPeriodEnd;
23680
+ if (lastPeriodEnd !== undefined && lastPeriodEnd < finalMaximumSafePosition) {
23681
+ finalMaximumSafePosition = lastPeriodEnd;
23610
23682
  }
23611
23683
  }
23612
23684
 
23613
- if (contentEnd !== undefined && contentEnd < maximumTime) {
23614
- maximumTime = contentEnd;
23685
+ if (maximumSafePosition !== undefined && maximumSafePosition < finalMaximumSafePosition) {
23686
+ finalMaximumSafePosition = maximumSafePosition;
23615
23687
  }
23616
23688
 
23617
23689
  maximumTimeData = {
23618
23690
  isLinear: false,
23619
- value: maximumTime,
23691
+ maximumSafePosition: finalMaximumSafePosition,
23692
+ livePosition: undefined,
23620
23693
  time: now
23621
23694
  };
23622
23695
  } else {
23623
- minimumTime = contentStart;
23696
+ minimumTime = minimumSafePosition;
23624
23697
  timeshiftDepth = timeShiftBufferDepth !== null && timeShiftBufferDepth !== void 0 ? timeShiftBufferDepth : null;
23625
23698
 
23626
- var _maximumTime;
23699
+ var _finalMaximumSafePosition;
23700
+
23701
+ var livePosition;
23627
23702
 
23628
- if (contentEnd !== undefined) {
23629
- _maximumTime = contentEnd;
23703
+ if (maximumUnsafePosition !== undefined) {
23704
+ livePosition = maximumUnsafePosition;
23705
+ }
23706
+
23707
+ if (maximumSafePosition !== undefined) {
23708
+ _finalMaximumSafePosition = maximumSafePosition;
23630
23709
  } else {
23631
23710
  var ast = availabilityStartTime !== null && availabilityStartTime !== void 0 ? availabilityStartTime : 0;
23632
23711
  var externalClockOffset = args.externalClockOffset;
23633
23712
 
23634
23713
  if (externalClockOffset === undefined) {
23635
23714
  log/* default.warn */.Z.warn("DASH Parser: use system clock to define maximum position");
23636
- _maximumTime = Date.now() / 1000 - ast;
23715
+ _finalMaximumSafePosition = Date.now() / 1000 - ast;
23637
23716
  } else {
23638
23717
  var serverTime = performance.now() + externalClockOffset;
23639
- _maximumTime = serverTime / 1000 - ast;
23718
+ _finalMaximumSafePosition = serverTime / 1000 - ast;
23640
23719
  }
23641
23720
  }
23642
23721
 
23722
+ if (livePosition === undefined) {
23723
+ livePosition = _finalMaximumSafePosition;
23724
+ }
23725
+
23643
23726
  maximumTimeData = {
23644
23727
  isLinear: true,
23645
- value: _maximumTime,
23728
+ maximumSafePosition: _finalMaximumSafePosition,
23729
+ livePosition: livePosition,
23646
23730
  time: now
23647
23731
  }; // if the minimum calculated time is even below the buffer depth, perhaps we
23648
23732
  // can go even lower in terms of depth
23649
23733
 
23650
- if (timeshiftDepth !== null && minimumTime !== undefined && _maximumTime - minimumTime > timeshiftDepth) {
23651
- timeshiftDepth = _maximumTime - minimumTime;
23734
+ if (timeshiftDepth !== null && minimumTime !== undefined && _finalMaximumSafePosition - minimumTime > timeshiftDepth) {
23735
+ timeshiftDepth = _finalMaximumSafePosition - minimumTime;
23652
23736
  }
23653
23737
  } // `isLastPeriodKnown` should be `true` in two cases for DASH contents:
23654
23738
  // 1. When the content is static, because we know that no supplementary
@@ -23671,7 +23755,7 @@ function parseCompleteIntermediateRepresentation(mpdIR, args, warnings, xlinkInf
23671
23755
  suggestedPresentationDelay: rootAttributes.suggestedPresentationDelay,
23672
23756
  transportType: "dash",
23673
23757
  timeBounds: {
23674
- absoluteMinimumTime: minimumTime,
23758
+ minimumSafePosition: minimumTime,
23675
23759
  timeshiftDepth: timeshiftDepth,
23676
23760
  maximumTimeData: maximumTimeData
23677
23761
  },
@@ -35261,8 +35345,15 @@ function createSmoothStreamingParser(parserOptions) {
35261
35345
  var maximumTimeData;
35262
35346
  var firstVideoAdaptation = adaptations.video !== undefined ? adaptations.video[0] : undefined;
35263
35347
  var firstAudioAdaptation = adaptations.audio !== undefined ? adaptations.audio[0] : undefined;
35264
- var firstTimeReference;
35265
- var lastTimeReference;
35348
+ /** Minimum time that can be reached regardless of the StreamIndex chosen. */
35349
+
35350
+ var safeMinimumTime;
35351
+ /** Maximum time that can be reached regardless of the StreamIndex chosen. */
35352
+
35353
+ var safeMaximumTime;
35354
+ /** Maximum time that can be reached in absolute on the content. */
35355
+
35356
+ var unsafeMaximumTime;
35266
35357
 
35267
35358
  if (firstVideoAdaptation !== undefined || firstAudioAdaptation !== undefined) {
35268
35359
  var firstTimeReferences = [];
@@ -35303,42 +35394,54 @@ function createSmoothStreamingParser(parserOptions) {
35303
35394
  }
35304
35395
 
35305
35396
  if (firstTimeReferences.length > 0) {
35306
- firstTimeReference = Math.max.apply(Math, firstTimeReferences);
35397
+ safeMinimumTime = Math.max.apply(Math, firstTimeReferences);
35307
35398
  }
35308
35399
 
35309
35400
  if (lastTimeReferences.length > 0) {
35310
- lastTimeReference = Math.min.apply(Math, lastTimeReferences);
35401
+ safeMaximumTime = Math.min.apply(Math, lastTimeReferences);
35402
+ unsafeMaximumTime = Math.max.apply(Math, lastTimeReferences);
35311
35403
  }
35312
35404
  }
35313
35405
 
35314
35406
  var manifestDuration = root.getAttribute("Duration");
35315
- var duration = manifestDuration != null && +manifestDuration !== 0 ? +manifestDuration / timescale : undefined;
35407
+ var duration = manifestDuration !== null && +manifestDuration !== 0 ? +manifestDuration / timescale : undefined;
35316
35408
 
35317
35409
  if (isLive) {
35318
35410
  suggestedPresentationDelay = parserOptions.suggestedPresentationDelay;
35319
35411
  availabilityStartTime = referenceDateTime;
35320
- minimumTime = firstTimeReference !== null && firstTimeReference !== void 0 ? firstTimeReference : availabilityStartTime;
35321
- var maximumTime = lastTimeReference != null ? lastTimeReference : Date.now() / 1000 - availabilityStartTime;
35412
+ minimumTime = safeMinimumTime !== null && safeMinimumTime !== void 0 ? safeMinimumTime : availabilityStartTime;
35413
+ var livePosition = unsafeMaximumTime;
35414
+
35415
+ if (livePosition === undefined) {
35416
+ livePosition = Date.now() / 1000 - availabilityStartTime;
35417
+ }
35418
+
35419
+ var maximumSafePosition = safeMaximumTime;
35420
+
35421
+ if (maximumSafePosition === undefined) {
35422
+ maximumSafePosition = livePosition;
35423
+ }
35424
+
35322
35425
  maximumTimeData = {
35323
35426
  isLinear: true,
35324
- value: maximumTime,
35427
+ maximumSafePosition: maximumSafePosition,
35428
+ livePosition: livePosition,
35325
35429
  time: performance.now()
35326
35430
  };
35327
35431
  timeshiftDepth = timeShiftBufferDepth !== null && timeShiftBufferDepth !== void 0 ? timeShiftBufferDepth : null;
35328
35432
  } else {
35329
- minimumTime = firstTimeReference !== null && firstTimeReference !== void 0 ? firstTimeReference : 0;
35330
-
35331
- var _maximumTime = lastTimeReference !== undefined ? lastTimeReference : duration !== undefined ? minimumTime + duration : Infinity;
35332
-
35433
+ minimumTime = safeMinimumTime !== null && safeMinimumTime !== void 0 ? safeMinimumTime : 0;
35434
+ var maximumTime = safeMaximumTime !== undefined ? safeMaximumTime : duration !== undefined ? minimumTime + duration : Infinity;
35333
35435
  maximumTimeData = {
35334
35436
  isLinear: false,
35335
- value: _maximumTime,
35437
+ maximumSafePosition: maximumTime,
35438
+ livePosition: undefined,
35336
35439
  time: performance.now()
35337
35440
  };
35338
35441
  }
35339
35442
 
35340
35443
  var periodStart = isLive ? 0 : minimumTime;
35341
- var periodEnd = isLive ? undefined : maximumTimeData.value;
35444
+ var periodEnd = isLive ? undefined : maximumTimeData.maximumSafePosition;
35342
35445
  var manifest = {
35343
35446
  availabilityStartTime: availabilityStartTime === undefined ? 0 : availabilityStartTime,
35344
35447
  clockOffset: serverTimeOffset,
@@ -35346,7 +35449,7 @@ function createSmoothStreamingParser(parserOptions) {
35346
35449
  isDynamic: isLive,
35347
35450
  isLastPeriodKnown: true,
35348
35451
  timeBounds: {
35349
- absoluteMinimumTime: minimumTime,
35452
+ minimumSafePosition: minimumTime,
35350
35453
  timeshiftDepth: timeshiftDepth,
35351
35454
  maximumTimeData: maximumTimeData
35352
35455
  },
@@ -50529,6 +50632,7 @@ function getFilteredRepresentations(representations, filters) {
50529
50632
 
50530
50633
  function RepresentationEstimator(_ref) {
50531
50634
  var bandwidthEstimator = _ref.bandwidthEstimator,
50635
+ context = _ref.context,
50532
50636
  observation$ = _ref.observation$,
50533
50637
  filters$ = _ref.filters$,
50534
50638
  initialBitrate = _ref.initialBitrate,
@@ -50668,7 +50772,8 @@ function RepresentationEstimator(_ref) {
50668
50772
  bufferBasedBitrate = _ref4$[4],
50669
50773
  currentRepresentation = _ref4[1];
50670
50774
  var bufferGap = observation.bufferGap,
50671
- liveGap = observation.liveGap;
50775
+ position = observation.position,
50776
+ maximumPosition = observation.maximumPosition;
50672
50777
  var filteredReps = getFilteredRepresentations(representations, filters);
50673
50778
  var requests = requestsStore.getRequests();
50674
50779
 
@@ -50730,7 +50835,7 @@ function RepresentationEstimator(_ref) {
50730
50835
 
50731
50836
  var chosenRepFromGuessMode = null;
50732
50837
 
50733
- if (lowLatencyMode && currentRepresentation !== null && liveGap !== undefined && liveGap < 40) {
50838
+ if (lowLatencyMode && currentRepresentation !== null && context.manifest.isDynamic && maximumPosition - position < 40) {
50734
50839
  chosenRepFromGuessMode = guessBasedChooser.getGuess(representations, observation, currentRepresentation, currentBestBitrate, requests);
50735
50840
  }
50736
50841
 
@@ -50823,7 +50928,7 @@ var ABRManager = /*#__PURE__*/function () {
50823
50928
  * Take type and an array of the available representations, spit out an
50824
50929
  * observable emitting the best representation (given the network/buffer
50825
50930
  * state).
50826
- * @param {string} type
50931
+ * @param {Object} context
50827
50932
  * @param {Array.<Representation>} representations
50828
50933
  * @param {Observable<Object>} observation$
50829
50934
  * @param {Observable<Object>} streamEvents$
@@ -50833,9 +50938,11 @@ var ABRManager = /*#__PURE__*/function () {
50833
50938
 
50834
50939
  var _proto = ABRManager.prototype;
50835
50940
 
50836
- _proto.get$ = function get$(type, representations, observation$, streamEvents$) {
50941
+ _proto.get$ = function get$(context, representations, observation$, streamEvents$) {
50837
50942
  var _a, _b, _c;
50838
50943
 
50944
+ var type = context.adaptation.type;
50945
+
50839
50946
  var bandwidthEstimator = this._getBandwidthEstimator(type);
50840
50947
 
50841
50948
  var manualBitrate$ = (0,take_first_set/* default */.Z)((_a = this._manualBitrates[type]) === null || _a === void 0 ? void 0 : _a.asObservable(), (0,of.of)(-1));
@@ -50845,6 +50952,7 @@ var ABRManager = /*#__PURE__*/function () {
50845
50952
  var filters$ = createFilters(this._throttlers.limitWidth[type], this._throttlers.throttleBitrate[type], this._throttlers.throttle[type]);
50846
50953
  return RepresentationEstimator({
50847
50954
  bandwidthEstimator: bandwidthEstimator,
50955
+ context: context,
50848
50956
  streamEvents$: streamEvents$,
50849
50957
  observation$: observation$,
50850
50958
  filters$: filters$,
@@ -51087,6 +51195,7 @@ var events_generators = __webpack_require__(8343);
51087
51195
  */
51088
51196
 
51089
51197
 
51198
+
51090
51199
  /**
51091
51200
  * Returns the calculated initial time for the content described by the given
51092
51201
  * Manifest:
@@ -51102,27 +51211,35 @@ var events_generators = __webpack_require__(8343);
51102
51211
  */
51103
51212
 
51104
51213
  function getInitialTime(manifest, lowLatencyMode, startAt) {
51105
- if (startAt != null) {
51106
- var min = manifest.getMinimumPosition();
51107
- var max = manifest.getMaximumPosition();
51214
+ if (!(0,is_null_or_undefined/* default */.Z)(startAt)) {
51215
+ var min = manifest.getMinimumSafePosition();
51216
+ var max;
51217
+
51218
+ if (manifest.isLive) {
51219
+ max = manifest.getLivePosition();
51220
+ }
51221
+
51222
+ if (max === undefined) {
51223
+ max = manifest.getMaximumSafePosition();
51224
+ }
51108
51225
 
51109
- if (startAt.position != null) {
51226
+ if (!(0,is_null_or_undefined/* default */.Z)(startAt.position)) {
51110
51227
  log/* default.debug */.Z.debug("Init: using startAt.minimumPosition");
51111
51228
  return Math.max(Math.min(startAt.position, max), min);
51112
- } else if (startAt.wallClockTime != null) {
51229
+ } else if (!(0,is_null_or_undefined/* default */.Z)(startAt.wallClockTime)) {
51113
51230
  log/* default.debug */.Z.debug("Init: using startAt.wallClockTime");
51114
- var ast = manifest.availabilityStartTime == null ? 0 : manifest.availabilityStartTime;
51231
+ var ast = manifest.availabilityStartTime === undefined ? 0 : manifest.availabilityStartTime;
51115
51232
  var position = startAt.wallClockTime - ast;
51116
51233
  return Math.max(Math.min(position, max), min);
51117
- } else if (startAt.fromFirstPosition != null) {
51234
+ } else if (!(0,is_null_or_undefined/* default */.Z)(startAt.fromFirstPosition)) {
51118
51235
  log/* default.debug */.Z.debug("Init: using startAt.fromFirstPosition");
51119
51236
  var fromFirstPosition = startAt.fromFirstPosition;
51120
51237
  return fromFirstPosition <= 0 ? min : Math.min(max, min + fromFirstPosition);
51121
- } else if (startAt.fromLastPosition != null) {
51238
+ } else if (!(0,is_null_or_undefined/* default */.Z)(startAt.fromLastPosition)) {
51122
51239
  log/* default.debug */.Z.debug("Init: using startAt.fromLastPosition");
51123
51240
  var fromLastPosition = startAt.fromLastPosition;
51124
51241
  return fromLastPosition >= 0 ? max : Math.max(min, max + fromLastPosition);
51125
- } else if (startAt.percentage != null) {
51242
+ } else if (!(0,is_null_or_undefined/* default */.Z)(startAt.percentage)) {
51126
51243
  log/* default.debug */.Z.debug("Init: using startAt.percentage");
51127
51244
  var percentage = startAt.percentage;
51128
51245
 
@@ -51138,24 +51255,24 @@ function getInitialTime(manifest, lowLatencyMode, startAt) {
51138
51255
  }
51139
51256
  }
51140
51257
 
51141
- var minimumPosition = manifest.getMinimumPosition();
51258
+ var minimumPosition = manifest.getMinimumSafePosition();
51142
51259
 
51143
51260
  if (manifest.isLive) {
51144
51261
  var suggestedPresentationDelay = manifest.suggestedPresentationDelay,
51145
51262
  clockOffset = manifest.clockOffset;
51146
- var maximumPosition = manifest.getMaximumPosition();
51263
+ var maximumPosition = manifest.getMaximumSafePosition();
51147
51264
  var liveTime;
51148
51265
 
51149
51266
  var _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(),
51150
51267
  DEFAULT_LIVE_GAP = _config$getCurrent.DEFAULT_LIVE_GAP;
51151
51268
 
51152
- if (clockOffset == null) {
51269
+ if (clockOffset === undefined) {
51153
51270
  log/* default.info */.Z.info("Init: no clock offset found for a live content, " + "starting close to maximum available position");
51154
51271
  liveTime = maximumPosition;
51155
51272
  } else {
51156
51273
  log/* default.info */.Z.info("Init: clock offset found for a live content, " + "checking if we can start close to it");
51157
51274
 
51158
- var _ast = manifest.availabilityStartTime == null ? 0 : manifest.availabilityStartTime;
51275
+ var _ast = manifest.availabilityStartTime === undefined ? 0 : manifest.availabilityStartTime;
51159
51276
 
51160
51277
  var clockRelativeLiveTime = (performance.now() + clockOffset) / 1000 - _ast;
51161
51278
 
@@ -53892,6 +54009,7 @@ function getSegmentPriority(segmentTime, wantedStartTimestamp) {
53892
54009
 
53893
54010
 
53894
54011
 
54012
+
53895
54013
  /**
53896
54014
  * Checks on the current buffered data for the given type and Period
53897
54015
  * and returns what should be done to fill the buffer according to the buffer
@@ -53900,25 +54018,20 @@ function getSegmentPriority(segmentTime, wantedStartTimestamp) {
53900
54018
  * be filled by any segment, even in the future.
53901
54019
  *
53902
54020
  * @param {Object} content
53903
- * @param {Object} playbackInfo
54021
+ * @param {number} initialWantedTime
54022
+ * @param {Object} playbackObserver
53904
54023
  * @param {number|undefined} fastSwitchThreshold
53905
54024
  * @param {number} bufferGoal
54025
+ * @param {number} maxBufferSize
53906
54026
  * @param {Object} segmentBuffer
53907
54027
  * @returns {Object}
53908
54028
  */
53909
54029
 
53910
- function getBufferStatus(content, wantedStartPosition, playbackObserver, fastSwitchThreshold, bufferGoal, maxBufferSize, segmentBuffer) {
53911
- var _a;
53912
-
53913
- var period = content.period,
53914
- representation = content.representation;
54030
+ function getBufferStatus(content, initialWantedTime, playbackObserver, fastSwitchThreshold, bufferGoal, maxBufferSize, segmentBuffer) {
53915
54031
  segmentBuffer.synchronizeInventory();
53916
- var wantedEndPosition = wantedStartPosition + bufferGoal;
53917
- var neededRange = {
53918
- start: Math.max(wantedStartPosition, period.start),
53919
- end: Math.min(wantedEndPosition, (_a = period.end) !== null && _a !== void 0 ? _a : Infinity)
53920
- };
53921
- var shouldRefreshManifest = representation.index.shouldRefresh(wantedStartPosition, wantedEndPosition);
54032
+ var representation = content.representation;
54033
+ var neededRange = getRangeOfNeededSegments(content, initialWantedTime, bufferGoal);
54034
+ var shouldRefreshManifest = representation.index.shouldRefresh(neededRange.start, neededRange.end);
53922
54035
  /**
53923
54036
  * Every segment awaiting an "EndOfSegment" operation, which indicates that a
53924
54037
  * completely-loaded segment is still being pushed to the SegmentBuffer.
@@ -53957,7 +54070,7 @@ function getBufferStatus(content, wantedStartPosition, playbackObserver, fastSwi
53957
54070
 
53958
54071
  var prioritizedNeededSegments = segmentsToLoad.map(function (segment) {
53959
54072
  return {
53960
- priority: getSegmentPriority(segment.time, wantedStartPosition),
54073
+ priority: getSegmentPriority(segment.time, initialWantedTime),
53961
54074
  segment: segment
53962
54075
  };
53963
54076
  });
@@ -53966,31 +54079,7 @@ function getBufferStatus(content, wantedStartPosition, playbackObserver, fastSwi
53966
54079
  * needed segments for this Representation until the end of the Period.
53967
54080
  */
53968
54081
 
53969
- var hasFinishedLoading;
53970
- var lastPosition = representation.index.getLastPosition();
53971
-
53972
- if (!representation.index.isInitialized() || period.end === undefined || prioritizedNeededSegments.length > 0 || segmentsOnHold.length > 0) {
53973
- hasFinishedLoading = false;
53974
- } else {
53975
- if (lastPosition === undefined) {
53976
- // We do not know the end of this index.
53977
- // If we reached the end of the period, check that all segments are
53978
- // available.
53979
- hasFinishedLoading = neededRange.end >= period.end && representation.index.isFinished();
53980
- } else if (lastPosition === null) {
53981
- // There is no available segment in the index currently. If the index
53982
- // tells us it has finished generating new segments, we're done.
53983
- hasFinishedLoading = representation.index.isFinished();
53984
- } else {
53985
- // We have a declared end. Check that our range went until the last
53986
- // position available in the index. If that's the case and we're left
53987
- // with no segments after filtering them, it means we already have
53988
- // downloaded the last segments and have nothing left to do: full.
53989
- var endOfRange = period.end !== undefined ? Math.min(period.end, lastPosition) : lastPosition;
53990
- hasFinishedLoading = neededRange.end >= endOfRange && representation.index.isFinished();
53991
- }
53992
- }
53993
-
54082
+ var hasFinishedLoading = neededRange.hasReachedPeriodEnd && prioritizedNeededSegments.length === 0 && segmentsOnHold.length === 0;
53994
54083
  var imminentDiscontinuity;
53995
54084
 
53996
54085
  if (!representation.index.isInitialized() || // TODO better handle contents not chronologically generated
@@ -54029,6 +54118,79 @@ function getBufferStatus(content, wantedStartPosition, playbackObserver, fastSwi
54029
54118
  shouldRefreshManifest: shouldRefreshManifest
54030
54119
  };
54031
54120
  }
54121
+ /**
54122
+ * Returns both the time range of segments that should be loaded (from a
54123
+ * starting position to an ending position) and whether the end of the Period is
54124
+ * reached by that range.
54125
+ * @param {Object} content
54126
+ * @param {number} initialWantedTime
54127
+ * @param {number} bufferGoal
54128
+ * @returns {Object}
54129
+ */
54130
+
54131
+ function getRangeOfNeededSegments(content, initialWantedTime, bufferGoal) {
54132
+ var _a;
54133
+
54134
+ var wantedStartPosition;
54135
+ var manifest = content.manifest,
54136
+ period = content.period,
54137
+ representation = content.representation;
54138
+ var lastIndexPosition = representation.index.getLastPosition();
54139
+ var representationIndex = representation.index; // There is an exception for when the current initially wanted time is already
54140
+ // after the last position with segments AND when we're playing the absolute
54141
+ // last Period in the Manifest.
54142
+ // In that case, we want to actually request at least the last segment to
54143
+ // avoid ending the last Period - and by extension the content - with a
54144
+ // segment which isn't the last one.
54145
+
54146
+ if (!(0,is_null_or_undefined/* default */.Z)(lastIndexPosition) && initialWantedTime >= lastIndexPosition && representationIndex.isInitialized() && representationIndex.isFinished() && isPeriodTheCurrentAndLastOne(manifest, period, initialWantedTime)) {
54147
+ wantedStartPosition = lastIndexPosition - 1;
54148
+ } else {
54149
+ wantedStartPosition = initialWantedTime;
54150
+ }
54151
+
54152
+ var wantedEndPosition = wantedStartPosition + bufferGoal;
54153
+ var hasReachedPeriodEnd;
54154
+
54155
+ if (!representation.index.isInitialized() || !representation.index.isFinished() || period.end === undefined) {
54156
+ hasReachedPeriodEnd = false;
54157
+ } else if (lastIndexPosition === undefined) {
54158
+ // We do not know the end of this index.
54159
+ hasReachedPeriodEnd = wantedEndPosition >= period.end;
54160
+ } else if (lastIndexPosition === null) {
54161
+ // There is no available segment in the index currently.
54162
+ hasReachedPeriodEnd = true;
54163
+ } else {
54164
+ // We have a declared end. Check that our range went until the last
54165
+ // position available in the index. If that's the case and we're left
54166
+ // with no segments after filtering them, it means we already have
54167
+ // downloaded the last segments and have nothing left to do: full.
54168
+ hasReachedPeriodEnd = wantedEndPosition >= lastIndexPosition;
54169
+ }
54170
+
54171
+ return {
54172
+ start: Math.max(wantedStartPosition, period.start),
54173
+ end: Math.min(wantedEndPosition, (_a = period.end) !== null && _a !== void 0 ? _a : Infinity),
54174
+ hasReachedPeriodEnd: hasReachedPeriodEnd
54175
+ };
54176
+ }
54177
+ /**
54178
+ * Returns `true` if the given Period is both:
54179
+ * - the one being played (the current position is known from `time`)
54180
+ * - the absolute last one in the Manifest (that is, there will never be a
54181
+ * Period after it).
54182
+ * @param {Object} manifest
54183
+ * @param {Object} period
54184
+ * @param {number} time
54185
+ * @returns {boolean}
54186
+ */
54187
+
54188
+
54189
+ function isPeriodTheCurrentAndLastOne(manifest, period, time) {
54190
+ var _a;
54191
+
54192
+ return period.containsTime(time) && manifest.isLastPeriodKnown && period.id === ((_a = manifest.periods[manifest.periods.length - 1]) === null || _a === void 0 ? void 0 : _a.id);
54193
+ }
54032
54194
  /**
54033
54195
  * From the given SegmentInventory, filters the "playable" (in a supported codec
54034
54196
  * and not known to be undecipherable) buffered Segment Objects which overlap
@@ -54038,6 +54200,7 @@ function getBufferStatus(content, wantedStartPosition, playbackObserver, fastSwi
54038
54200
  * @returns {Array.<Object>}
54039
54201
  */
54040
54202
 
54203
+
54041
54204
  function getPlayableBufferedSegments(neededRange, segmentInventory) {
54042
54205
  var _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(),
54043
54206
  MINIMUM_SEGMENT_SIZE = _config$getCurrent.MINIMUM_SEGMENT_SIZE;
@@ -54491,8 +54654,8 @@ function RepresentationStream(_ref) {
54491
54654
  maxBufferSize = _ref2$[2],
54492
54655
  terminate = _ref2$[3],
54493
54656
  fastSwitchThreshold = _ref2[1];
54494
- var wantedStartPosition = observation.position + observation.wantedTimeOffset;
54495
- var status = getBufferStatus(content, wantedStartPosition, playbackObserver, fastSwitchThreshold, bufferGoal, maxBufferSize, segmentBuffer);
54657
+ var initialWantedTime = observation.position + observation.wantedTimeOffset;
54658
+ var status = getBufferStatus(content, initialWantedTime, playbackObserver, fastSwitchThreshold, bufferGoal, maxBufferSize, segmentBuffer);
54496
54659
  var neededSegments = status.neededSegments;
54497
54660
  var neededInitSegment = null; // Add initialization segment if required
54498
54661
 
@@ -54568,7 +54731,7 @@ function RepresentationStream(_ref) {
54568
54731
  UPTO_CURRENT_POSITION_CLEANUP = _config$getCurrent.UPTO_CURRENT_POSITION_CLEANUP;
54569
54732
 
54570
54733
  if (status.isBufferFull) {
54571
- var gcedPosition = Math.max(0, wantedStartPosition - UPTO_CURRENT_POSITION_CLEANUP);
54734
+ var gcedPosition = Math.max(0, initialWantedTime - UPTO_CURRENT_POSITION_CLEANUP);
54572
54735
 
54573
54736
  if (gcedPosition > 0) {
54574
54737
  bufferRemoval = segmentBuffer.removeBuffer(0, gcedPosition) // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
@@ -54744,9 +54907,9 @@ function RepresentationStream(_ref) {
54744
54907
  * @returns {Object}
54745
54908
  */
54746
54909
 
54747
- function createRepresentationEstimator(_ref, abrManager, observation$) {
54748
- var manifest = _ref.manifest,
54749
- adaptation = _ref.adaptation;
54910
+ function createRepresentationEstimator(content, abrManager, observation$) {
54911
+ var manifest = content.manifest,
54912
+ adaptation = content.adaptation;
54750
54913
  var abrFeedbacks$ = new Subject/* Subject */.x();
54751
54914
  var estimator$ = (0,merge/* merge */.T)( // subscribe "first" (hack as it is a merge here) to event
54752
54915
  (0,event_emitter/* fromEvent */.R)(manifest, "decipherabilityUpdate"), // Emit directly a first time on subscription (after subscribing to event)
@@ -54773,7 +54936,7 @@ function createRepresentationEstimator(_ref, abrManager, observation$) {
54773
54936
 
54774
54937
  return true;
54775
54938
  }), (0,switchMap/* switchMap */.w)(function (playableRepresentations) {
54776
- return abrManager.get$(adaptation.type, playableRepresentations, observation$, abrFeedbacks$);
54939
+ return abrManager.get$(content, playableRepresentations, observation$, abrFeedbacks$);
54777
54940
  }));
54778
54941
  return {
54779
54942
  estimator$: estimator$,
@@ -55683,10 +55846,11 @@ function createOrReuseSegmentBuffer(segmentBuffersStore, bufferType, adaptation,
55683
55846
 
55684
55847
 
55685
55848
  function getFirstDeclaredMimeType(adaptation) {
55686
- var representations = adaptation.representations;
55849
+ var representations = adaptation.getPlayableRepresentations();
55687
55850
 
55688
- if (representations[0] == null) {
55689
- return "";
55851
+ if (representations.length === 0) {
55852
+ var noRepErr = new media_error/* default */.Z("NO_PLAYABLE_REPRESENTATION", "No Representation in the chosen " + adaptation.type + " Adaptation can be played");
55853
+ throw noRepErr;
55690
55854
  }
55691
55855
 
55692
55856
  return representations[0].getMimeTypeString();
@@ -56103,28 +56267,9 @@ function StreamOrchestrator(content, playbackObserver, abrManager, segmentBuffer
56103
56267
  return Math.min(val, defaultMaxAhead);
56104
56268
  }))
56105
56269
  });
56106
- }); // trigger warnings when the wanted time is before or after the manifest's
56107
- // segments
56108
-
56109
- var outOfManifest$ = playbackObserver.observe(true).pipe((0,filter_map/* default */.Z)(function (_ref) {
56110
- var position = _ref.position,
56111
- wantedTimeOffset = _ref.wantedTimeOffset;
56112
- var offsetedPosition = wantedTimeOffset + position;
56113
-
56114
- if (offsetedPosition < manifest.getMinimumPosition()) {
56115
- var warning = new media_error/* default */.Z("MEDIA_TIME_BEFORE_MANIFEST", "The current position is behind the " + "earliest time announced in the Manifest.");
56116
- return stream_events_generators/* default.warning */.Z.warning(warning);
56117
- } else if (offsetedPosition > manifest.getMaximumPosition()) {
56118
- var _warning = new media_error/* default */.Z("MEDIA_TIME_AFTER_MANIFEST", "The current position is after the latest " + "time announced in the Manifest.");
56119
-
56120
- return stream_events_generators/* default.warning */.Z.warning(_warning);
56121
- }
56270
+ }); // Every PeriodStreams for every possible types
56122
56271
 
56123
- return null;
56124
- }, null));
56125
- var bufferTypes = segmentBuffersStore.getBufferTypes(); // Every PeriodStreams for every possible types
56126
-
56127
- var streamsArray = bufferTypes.map(function (bufferType) {
56272
+ var streamsArray = segmentBuffersStore.getBufferTypes().map(function (bufferType) {
56128
56273
  return manageEveryStreams(bufferType, initialPeriod).pipe((0,defer_subscriptions/* default */.Z)(), (0,share/* share */.B)());
56129
56274
  }); // Emits the activePeriodChanged events every time the active Period changes.
56130
56275
 
@@ -56139,14 +56284,14 @@ function StreamOrchestrator(content, playbackObserver, abrManager, segmentBuffer
56139
56284
  }), (0,startWith/* startWith */.O)(manifest.isLastPeriodKnown), (0,distinctUntilChanged/* distinctUntilChanged */.x)()); // Emits an "end-of-stream" event once every PeriodStream are complete.
56140
56285
  // Emits a 'resume-stream" when it's not
56141
56286
 
56142
- var endOfStream$ = (0,combineLatest/* combineLatest */.a)([areStreamsComplete.apply(void 0, streamsArray), isLastPeriodKnown$]).pipe((0,map/* map */.U)(function (_ref2) {
56143
- var areComplete = _ref2[0],
56144
- isLastPeriodKnown = _ref2[1];
56287
+ var endOfStream$ = (0,combineLatest/* combineLatest */.a)([areStreamsComplete.apply(void 0, streamsArray), isLastPeriodKnown$]).pipe((0,map/* map */.U)(function (_ref) {
56288
+ var areComplete = _ref[0],
56289
+ isLastPeriodKnown = _ref[1];
56145
56290
  return areComplete && isLastPeriodKnown;
56146
56291
  }), (0,distinctUntilChanged/* distinctUntilChanged */.x)(), (0,map/* map */.U)(function (emitEndOfStream) {
56147
56292
  return emitEndOfStream ? stream_events_generators/* default.endOfStream */.Z.endOfStream() : stream_events_generators/* default.resumeStream */.Z.resumeStream();
56148
56293
  }));
56149
- return merge/* merge.apply */.T.apply(void 0, streamsArray.concat([activePeriodChanged$, endOfStream$, outOfManifest$]));
56294
+ return merge/* merge.apply */.T.apply(void 0, streamsArray.concat([activePeriodChanged$, endOfStream$]));
56150
56295
  /**
56151
56296
  * Manage creation and removal of Streams for every Periods for a given type.
56152
56297
  *
@@ -56228,9 +56373,9 @@ function StreamOrchestrator(content, playbackObserver, abrManager, segmentBuffer
56228
56373
  // than the ones already considered
56229
56374
 
56230
56375
 
56231
- var restartStreamsWhenOutOfBounds$ = playbackObserver.observe(true).pipe((0,filter_map/* default */.Z)(function (_ref3) {
56232
- var position = _ref3.position,
56233
- wantedTimeOffset = _ref3.wantedTimeOffset;
56376
+ var restartStreamsWhenOutOfBounds$ = playbackObserver.observe(true).pipe((0,filter_map/* default */.Z)(function (_ref2) {
56377
+ var position = _ref2.position,
56378
+ wantedTimeOffset = _ref2.wantedTimeOffset;
56234
56379
 
56235
56380
  var _a;
56236
56381
 
@@ -56283,9 +56428,9 @@ function StreamOrchestrator(content, playbackObserver, abrManager, segmentBuffer
56283
56428
 
56284
56429
  enableOutOfBoundsCheck = false;
56285
56430
  destroyStreams$.next();
56286
- return concat/* concat.apply */.z.apply(void 0, rangesToClean.map(function (_ref4) {
56287
- var start = _ref4.start,
56288
- end = _ref4.end;
56431
+ return concat/* concat.apply */.z.apply(void 0, rangesToClean.map(function (_ref3) {
56432
+ var start = _ref3.start,
56433
+ end = _ref3.end;
56289
56434
  return start >= end ? empty/* EMPTY */.E : segmentBuffer.removeBuffer(start, end).pipe((0,ignoreElements/* ignoreElements */.l)());
56290
56435
  }).concat([playbackObserver.observe(true).pipe((0,take/* take */.q)(1), (0,mergeMap/* mergeMap */.z)(function (observation) {
56291
56436
  return (0,concat/* concat */.z)((0,of.of)(stream_events_generators/* default.needsDecipherabilityFlush */.Z.needsDecipherabilityFlush(observation.position, !observation.isPaused, observation.duration)), (0,defer/* defer */.P)(function () {
@@ -56339,9 +56484,9 @@ function StreamOrchestrator(content, playbackObserver, abrManager, segmentBuffer
56339
56484
 
56340
56485
  var destroyNextStreams$ = new Subject/* Subject */.x(); // Emits when the current position goes over the end of the current Stream.
56341
56486
 
56342
- var endOfCurrentStream$ = playbackObserver.observe(true).pipe((0,filter/* filter */.h)(function (_ref5) {
56343
- var position = _ref5.position,
56344
- wantedTimeOffset = _ref5.wantedTimeOffset;
56487
+ var endOfCurrentStream$ = playbackObserver.observe(true).pipe((0,filter/* filter */.h)(function (_ref4) {
56488
+ var position = _ref4.position,
56489
+ wantedTimeOffset = _ref4.wantedTimeOffset;
56345
56490
  return basePeriod.end != null && position + wantedTimeOffset >= basePeriod.end;
56346
56491
  })); // Create Period Stream for the next Period.
56347
56492
 
@@ -56439,7 +56584,7 @@ function StreamOrchestrator(content, playbackObserver, abrManager, segmentBuffer
56439
56584
 
56440
56585
 
56441
56586
  /* harmony default export */ var stream = (orchestrator);
56442
- ;// CONCATENATED MODULE: ./src/core/init/create_stream_playback_observer.ts
56587
+ ;// CONCATENATED MODULE: ./src/core/init/content_time_boundaries_observer.ts
56443
56588
  /**
56444
56589
  * Copyright 2015 CANAL+ Group
56445
56590
  *
@@ -56456,209 +56601,308 @@ function StreamOrchestrator(content, playbackObserver, abrManager, segmentBuffer
56456
56601
  * limitations under the License.
56457
56602
  */
56458
56603
 
56459
- /**
56460
- * Create PlaybackObserver for the `Stream` part of the code.
56461
- * @param {Object} playbackObserver
56462
- * @param {Object} args
56463
- * @returns {Observable}
56464
- */
56465
56604
 
56466
- function createStreamPlaybackObserver(manifest, playbackObserver, _ref) {
56467
- var autoPlay = _ref.autoPlay,
56468
- initialPlayPerformed = _ref.initialPlayPerformed,
56469
- initialSeekPerformed = _ref.initialSeekPerformed,
56470
- speed = _ref.speed,
56471
- startTime = _ref.startTime;
56472
- return playbackObserver.deriveReadOnlyObserver(function mapObservable(observation$) {
56473
- return (0,combineLatest/* combineLatest */.a)([observation$, speed.asObservable()]).pipe((0,map/* map */.U)(function (_ref2) {
56474
- var observation = _ref2[0],
56475
- lastSpeed = _ref2[1];
56476
- return {
56477
- liveGap: manifest.isLive ? manifest.getMaximumPosition() - observation.position : undefined,
56478
- position: observation.position,
56479
- duration: observation.duration,
56480
- isPaused: initialPlayPerformed.getValue() ? observation.paused : !autoPlay,
56481
- readyState: observation.readyState,
56482
- speed: lastSpeed,
56483
- // wantedTimeOffset is an offset to add to the timing's current time to have
56484
- // the "real" wanted position.
56485
- // For now, this is seen when the media element has not yet seeked to its
56486
- // initial position, the currentTime will most probably be 0 where the
56487
- // effective starting position will be _startTime_.
56488
- // Thus we initially set a wantedTimeOffset equal to startTime.
56489
- wantedTimeOffset: initialSeekPerformed.getValue() ? 0 : startTime - observation.position
56490
- };
56491
- }));
56492
- });
56493
- }
56494
- ;// CONCATENATED MODULE: ./src/core/init/duration_updater.ts
56495
- /**
56496
- * Copyright 2015 CANAL+ Group
56497
- *
56498
- * Licensed under the Apache License, Version 2.0 (the "License");
56499
- * you may not use this file except in compliance with the License.
56500
- * You may obtain a copy of the License at
56501
- *
56502
- * http://www.apache.org/licenses/LICENSE-2.0
56503
- *
56504
- * Unless required by applicable law or agreed to in writing, software
56505
- * distributed under the License is distributed on an "AS IS" BASIS,
56506
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
56507
- * See the License for the specific language governing permissions and
56508
- * limitations under the License.
56509
- */
56510
56605
 
56511
56606
 
56512
56607
 
56608
+ // NOTE As of now (RxJS 7.4.0), RxJS defines `ignoreElements` default
56609
+ // first type parameter as `any` instead of the perfectly fine `unknown`,
56610
+ // leading to linter issues, as it forbids the usage of `any`.
56611
+ // This is why we're disabling the eslint rule.
56513
56612
 
56514
- /** Number of seconds in a regular year. */
56613
+ /* eslint-disable @typescript-eslint/no-unsafe-argument */
56515
56614
 
56516
- var YEAR_IN_SECONDS = 365 * 24 * 3600;
56517
56615
  /**
56518
- * Keep the MediaSource duration up-to-date with the Manifest one on
56519
- * subscription:
56520
- * Set the current duration initially and then update if needed after
56521
- * each Manifest updates.
56616
+ * Observes the position and Adaptations being played and deduce various events
56617
+ * related to the available time boundaries:
56618
+ * - Emit when the theoretical duration of the content becomes known or when it
56619
+ * changes.
56620
+ * - Emit warnings when the duration goes out of what is currently
56621
+ * theoretically playable.
56622
+ *
56522
56623
  * @param {Object} manifest
56523
- * @param {MediaSource} mediaSource
56624
+ * @param {Observable} streams
56625
+ * @param {Object} playbackObserver
56524
56626
  * @returns {Observable}
56525
56627
  */
56526
56628
 
56527
- function DurationUpdater(manifest, mediaSource) {
56528
- return (0,defer/* defer */.P)(function () {
56529
- var lastDurationUpdate;
56530
- return setMediaSourceDuration(mediaSource, manifest).pipe((0,mergeMap/* mergeMap */.z)(function (initialDurationUpdate) {
56531
- // only update `lastDurationUpdate` if the MediaSource's duration has
56532
- // been updated.
56533
- if (initialDurationUpdate !== null) {
56534
- lastDurationUpdate = initialDurationUpdate;
56535
- }
56629
+ function ContentTimeBoundariesObserver(manifest, streams, playbackObserver) {
56630
+ /**
56631
+ * Allows to calculate the minimum and maximum playable position on the
56632
+ * whole content.
56633
+ */
56634
+ var maximumPositionCalculator = new MaximumPositionCalculator(manifest); // trigger warnings when the wanted time is before or after the manifest's
56635
+ // segments
56536
56636
 
56537
- return (0,event_emitter/* fromEvent */.R)(manifest, "manifestUpdate").pipe((0,switchMap/* switchMap */.w)(function () {
56538
- return setMediaSourceDuration(mediaSource, manifest, lastDurationUpdate);
56539
- }), (0,tap/* tap */.b)(function (durationUpdate) {
56540
- if (durationUpdate !== null) {
56541
- lastDurationUpdate = durationUpdate;
56542
- }
56543
- }));
56544
- }), // NOTE As of now (RxJS 7.4.0), RxJS defines `ignoreElements` default
56545
- // first type parameter as `any` instead of the perfectly fine `unknown`,
56546
- // leading to linter issues, as it forbids the usage of `any`.
56547
- // This is why we're disabling the eslint rule.
56637
+ var outOfManifest$ = playbackObserver.observe(true).pipe((0,filter_map/* default */.Z)(function (_ref) {
56638
+ var position = _ref.position,
56639
+ wantedTimeOffset = _ref.wantedTimeOffset;
56640
+ var offsetedPosition = wantedTimeOffset + position;
56548
56641
 
56549
- /* eslint-disable-next-line @typescript-eslint/no-unsafe-argument */
56550
- (0,ignoreElements/* ignoreElements */.l)());
56551
- });
56552
- }
56553
- /**
56554
- * Checks that duration can be updated on the MediaSource, and then
56555
- * sets it.
56556
- *
56557
- * Returns either:
56558
- * - the new duration it has been updated to if it has
56559
- * - `null` if it hasn'nt been updated
56560
- *
56561
- * @param {MediaSource} mediaSource
56562
- * @param {Object} manifest
56563
- * @param {number | undefined} lastSetDuration
56564
- * @returns {Observable.<number | null>}
56565
- */
56642
+ if (offsetedPosition < manifest.getMinimumSafePosition()) {
56643
+ var warning = new media_error/* default */.Z("MEDIA_TIME_BEFORE_MANIFEST", "The current position is behind the " + "earliest time announced in the Manifest.");
56644
+ return events_generators/* default.warning */.Z.warning(warning);
56645
+ } else if (offsetedPosition > maximumPositionCalculator.getCurrentMaximumPosition()) {
56646
+ var _warning = new media_error/* default */.Z("MEDIA_TIME_AFTER_MANIFEST", "The current position is after the latest " + "time announced in the Manifest.");
56566
56647
 
56567
- function setMediaSourceDuration(mediaSource, manifest, lastSetDuration) {
56568
- return isMediaSourceOpened$(mediaSource).pipe((0,switchMap/* switchMap */.w)(function (isMediaSourceOpened) {
56569
- if (!isMediaSourceOpened) {
56570
- return empty/* EMPTY */.E;
56648
+ return events_generators/* default.warning */.Z.warning(_warning);
56571
56649
  }
56572
56650
 
56573
- return whenSourceBuffersEndedUpdates$(mediaSource.sourceBuffers);
56574
- }), (0,take/* take */.q)(1), (0,map/* map */.U)(function () {
56575
- var maximumPosition = manifest.getMaximumPosition();
56576
- var isLive = manifest.isLive; // Some targets poorly support setting a very high number for durations.
56577
- // Yet, in live contents, we would prefer setting a value as high as possible
56578
- // to still be able to seek anywhere we want to (even ahead of the Manifest if
56579
- // we want to). As such, we put it at a safe default value of 2^32 excepted
56580
- // when the maximum position is already relatively close to that value, where
56581
- // we authorize exceptionally going over it.
56582
-
56583
- var newDuration = !isLive ? maximumPosition : Math.max(Math.pow(2, 32), maximumPosition + YEAR_IN_SECONDS);
56584
-
56585
- if (mediaSource.duration >= newDuration || // Even if the MediaSource duration is different than the duration that
56586
- // we want to set now, the last duration we wanted to set may be the same,
56587
- // as the MediaSource duration may have been changed by the browser.
56588
- //
56589
- // In that case, we do not want to update it.
56590
- //
56591
- newDuration === lastSetDuration) {
56592
- return null;
56593
- }
56651
+ return null;
56652
+ }, null));
56653
+ /**
56654
+ * Contains the content duration according to the last audio and video
56655
+ * Adaptation chosen for the last Period.
56656
+ * `undefined` if unknown yet.
56657
+ */
56594
56658
 
56595
- if (isNaN(mediaSource.duration) || !isFinite(mediaSource.duration) || newDuration - mediaSource.duration > 0.01) {
56596
- log/* default.info */.Z.info("Init: Updating duration", newDuration);
56597
- mediaSource.duration = newDuration;
56598
- return newDuration;
56659
+ var contentDuration = (0,reference/* default */.Z)(undefined);
56660
+ var updateDurationOnManifestUpdate$ = (0,event_emitter/* fromEvent */.R)(manifest, "manifestUpdate").pipe((0,startWith/* startWith */.O)(null), (0,tap/* tap */.b)(function () {
56661
+ if (!manifest.isDynamic) {
56662
+ var maxPos = maximumPositionCalculator.getCurrentMaximumPosition();
56663
+ contentDuration.setValue(maxPos);
56664
+ } else {
56665
+ // TODO handle finished dynamic contents?
56666
+ contentDuration.setValue(undefined);
56599
56667
  }
56668
+ }), (0,ignoreElements/* ignoreElements */.l)());
56669
+ var updateDurationAndTimeBoundsOnTrackChange$ = streams.pipe((0,tap/* tap */.b)(function (message) {
56670
+ if (message.type === "adaptationChange") {
56671
+ var lastPeriod = manifest.periods[manifest.periods.length - 1];
56600
56672
 
56601
- return null;
56602
- }), (0,catchError/* catchError */.K)(function (err) {
56603
- log/* default.warn */.Z.warn("Duration Updater: Can't update duration on the MediaSource.", err);
56604
- return (0,of.of)(null);
56605
- }));
56673
+ if (message.value.period.id === (lastPeriod === null || lastPeriod === void 0 ? void 0 : lastPeriod.id)) {
56674
+ if (message.value.type === "audio") {
56675
+ maximumPositionCalculator.updateLastAudioAdaptation(message.value.adaptation);
56676
+
56677
+ if (!manifest.isDynamic) {
56678
+ contentDuration.setValue(maximumPositionCalculator.getCurrentMaximumPosition());
56679
+ }
56680
+ } else if (message.value.type === "video") {
56681
+ maximumPositionCalculator.updateLastVideoAdaptation(message.value.adaptation);
56682
+
56683
+ if (!manifest.isDynamic) {
56684
+ contentDuration.setValue(maximumPositionCalculator.getCurrentMaximumPosition());
56685
+ }
56686
+ }
56687
+ }
56688
+ }
56689
+ }), (0,ignoreElements/* ignoreElements */.l)());
56690
+ return (0,merge/* merge */.T)(updateDurationOnManifestUpdate$, updateDurationAndTimeBoundsOnTrackChange$, outOfManifest$, contentDuration.asObservable().pipe(skipWhile(function (val) {
56691
+ return val === undefined;
56692
+ }), (0,distinctUntilChanged/* distinctUntilChanged */.x)(), (0,map/* map */.U)(function (value) {
56693
+ return {
56694
+ type: "contentDurationUpdate",
56695
+ value: value
56696
+ };
56697
+ })));
56606
56698
  }
56607
56699
  /**
56608
- * Returns an Observable which will emit only when all the SourceBuffers ended
56609
- * all pending updates.
56610
- * @param {SourceBufferList} sourceBuffers
56611
- * @returns {Observable}
56700
+ * Calculate the last position from the last chosen audio and video Adaptations
56701
+ * for the last Period (or a default one, if no Adaptations has been chosen).
56702
+ * @class MaximumPositionCalculator
56612
56703
  */
56613
56704
 
56705
+ var MaximumPositionCalculator = /*#__PURE__*/function () {
56706
+ /**
56707
+ * @param {Object} manifest
56708
+ */
56709
+ function MaximumPositionCalculator(manifest) {
56710
+ this._manifest = manifest;
56711
+ this._lastAudioAdaptation = undefined;
56712
+ this._lastVideoAdaptation = undefined;
56713
+ }
56714
+ /**
56715
+ * Update the last known audio Adaptation for the last Period.
56716
+ * If no Adaptation has been set, it should be set to `null`.
56717
+ *
56718
+ * Allows to calculate the maximum position more precizely in
56719
+ * `getCurrentMaximumPosition`.
56720
+ * @param {Object|null} adaptation
56721
+ */
56722
+
56614
56723
 
56615
- function whenSourceBuffersEndedUpdates$(sourceBuffers) {
56616
- if (sourceBuffers.length === 0) {
56617
- return (0,of.of)(undefined);
56724
+ var _proto = MaximumPositionCalculator.prototype;
56725
+
56726
+ _proto.updateLastAudioAdaptation = function updateLastAudioAdaptation(adaptation) {
56727
+ this._lastAudioAdaptation = adaptation;
56618
56728
  }
56729
+ /**
56730
+ * Update the last known video Adaptation for the last Period.
56731
+ * If no Adaptation has been set, it should be set to `null`.
56732
+ *
56733
+ * Allows to calculate the maximum position more precizely in
56734
+ * `getCurrentMaximumPosition`.
56735
+ * @param {Object|null} adaptation
56736
+ */
56737
+ ;
56619
56738
 
56620
- var sourceBufferUpdatingStatuses = [];
56739
+ _proto.updateLastVideoAdaptation = function updateLastVideoAdaptation(adaptation) {
56740
+ this._lastVideoAdaptation = adaptation;
56741
+ }
56742
+ /**
56743
+ * Returns an estimate of the maximum position reachable under the current
56744
+ * circumstances.
56745
+ * @returns {number}
56746
+ */
56747
+ ;
56621
56748
 
56622
- var _loop = function _loop(i) {
56623
- var sourceBuffer = sourceBuffers[i];
56624
- sourceBufferUpdatingStatuses.push((0,merge/* merge */.T)((0,fromEvent/* fromEvent */.R)(sourceBuffer, "updatestart").pipe((0,map/* map */.U)(function () {
56625
- return true;
56626
- })), (0,fromEvent/* fromEvent */.R)(sourceBuffer, "update").pipe((0,map/* map */.U)(function () {
56627
- return false;
56628
- })), (0,observable_interval/* interval */.F)(500).pipe((0,map/* map */.U)(function () {
56629
- return sourceBuffer.updating;
56630
- }))).pipe((0,startWith/* startWith */.O)(sourceBuffer.updating), (0,distinctUntilChanged/* distinctUntilChanged */.x)()));
56749
+ _proto.getCurrentMaximumPosition = function getCurrentMaximumPosition() {
56750
+ var _a;
56751
+
56752
+ if (this._manifest.isDynamic) {
56753
+ return (_a = this._manifest.getLivePosition()) !== null && _a !== void 0 ? _a : this._manifest.getMaximumSafePosition();
56754
+ }
56755
+
56756
+ if (this._lastVideoAdaptation === undefined || this._lastAudioAdaptation === undefined) {
56757
+ return this._manifest.getMaximumSafePosition();
56758
+ } else if (this._lastAudioAdaptation === null) {
56759
+ if (this._lastVideoAdaptation === null) {
56760
+ return this._manifest.getMaximumSafePosition();
56761
+ } else {
56762
+ var lastVideoPosition = getLastPositionFromAdaptation(this._lastVideoAdaptation);
56763
+
56764
+ if (typeof lastVideoPosition !== "number") {
56765
+ return this._manifest.getMaximumSafePosition();
56766
+ }
56767
+
56768
+ return lastVideoPosition;
56769
+ }
56770
+ } else if (this._lastVideoAdaptation === null) {
56771
+ var lastAudioPosition = getLastPositionFromAdaptation(this._lastAudioAdaptation);
56772
+
56773
+ if (typeof lastAudioPosition !== "number") {
56774
+ return this._manifest.getMaximumSafePosition();
56775
+ }
56776
+
56777
+ return lastAudioPosition;
56778
+ } else {
56779
+ var _lastAudioPosition = getLastPositionFromAdaptation(this._lastAudioAdaptation);
56780
+
56781
+ var _lastVideoPosition = getLastPositionFromAdaptation(this._lastVideoAdaptation);
56782
+
56783
+ if (typeof _lastAudioPosition !== "number" || typeof _lastVideoPosition !== "number") {
56784
+ return this._manifest.getMaximumSafePosition();
56785
+ } else {
56786
+ return Math.min(_lastAudioPosition, _lastVideoPosition);
56787
+ }
56788
+ }
56631
56789
  };
56632
56790
 
56633
- for (var i = 0; i < sourceBuffers.length; i++) {
56634
- _loop(i);
56791
+ return MaximumPositionCalculator;
56792
+ }();
56793
+ /**
56794
+ * Returns "last time of reference" from the adaptation given.
56795
+ * `undefined` if a time could not be found.
56796
+ * Null if the Adaptation has no segments (it could be that it didn't started or
56797
+ * that it already finished for example).
56798
+ *
56799
+ * We consider the earliest last time from every representations in the given
56800
+ * adaptation.
56801
+ * @param {Object} adaptation
56802
+ * @returns {Number|undefined|null}
56803
+ */
56804
+
56805
+
56806
+ function getLastPositionFromAdaptation(adaptation) {
56807
+ var representations = adaptation.representations;
56808
+ var min = null;
56809
+ /**
56810
+ * Some Manifest parsers use the exact same `IRepresentationIndex` reference
56811
+ * for each Representation of a given Adaptation, because in the actual source
56812
+ * Manifest file, indexing data is often defined at Adaptation-level.
56813
+ * This variable allows to optimize the logic here when this is the case.
56814
+ */
56815
+
56816
+ var lastIndex;
56817
+
56818
+ for (var i = 0; i < representations.length; i++) {
56819
+ if (representations[i].index !== lastIndex) {
56820
+ lastIndex = representations[i].index;
56821
+ var lastPosition = representations[i].index.getLastPosition();
56822
+
56823
+ if (lastPosition === undefined) {
56824
+ // we cannot tell
56825
+ return undefined;
56826
+ }
56827
+
56828
+ if (lastPosition !== null) {
56829
+ min = min == null ? lastPosition : Math.min(min, lastPosition);
56830
+ }
56831
+ }
56635
56832
  }
56636
56833
 
56637
- return (0,combineLatest/* combineLatest */.a)(sourceBufferUpdatingStatuses).pipe((0,filter/* filter */.h)(function (areUpdating) {
56638
- return areUpdating.every(function (isUpdating) {
56639
- return !isUpdating;
56640
- });
56641
- }), (0,map/* map */.U)(function () {
56642
- return undefined;
56643
- }));
56834
+ if (min === null) {
56835
+ // It means that all positions were null === no segments (yet?)
56836
+ return null;
56837
+ }
56838
+
56839
+ return min;
56644
56840
  }
56841
+ ;// CONCATENATED MODULE: ./src/core/init/create_stream_playback_observer.ts
56645
56842
  /**
56646
- * Emit a boolean that tells if the media source is opened or not.
56647
- * @param {MediaSource} mediaSource
56648
- * @returns {Object}
56843
+ * Copyright 2015 CANAL+ Group
56844
+ *
56845
+ * Licensed under the Apache License, Version 2.0 (the "License");
56846
+ * you may not use this file except in compliance with the License.
56847
+ * You may obtain a copy of the License at
56848
+ *
56849
+ * http://www.apache.org/licenses/LICENSE-2.0
56850
+ *
56851
+ * Unless required by applicable law or agreed to in writing, software
56852
+ * distributed under the License is distributed on an "AS IS" BASIS,
56853
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
56854
+ * See the License for the specific language governing permissions and
56855
+ * limitations under the License.
56649
56856
  */
56650
56857
 
56858
+ /**
56859
+ * Create PlaybackObserver for the `Stream` part of the code.
56860
+ * @param {Object} playbackObserver
56861
+ * @param {Object} args
56862
+ * @returns {Observable}
56863
+ */
56651
56864
 
56652
- function isMediaSourceOpened$(mediaSource) {
56653
- return (0,merge/* merge */.T)((0,event_listeners/* onSourceOpen$ */.ym)(mediaSource).pipe((0,map/* map */.U)(function () {
56654
- return true;
56655
- })), (0,event_listeners/* onSourceEnded$ */.ep)(mediaSource).pipe((0,map/* map */.U)(function () {
56656
- return false;
56657
- })), (0,event_listeners/* onSourceClose$ */.UG)(mediaSource).pipe((0,map/* map */.U)(function () {
56658
- return false;
56659
- }))).pipe((0,startWith/* startWith */.O)(mediaSource.readyState === "open"), (0,distinctUntilChanged/* distinctUntilChanged */.x)());
56865
+ function createStreamPlaybackObserver(manifest, playbackObserver, _ref) {
56866
+ var autoPlay = _ref.autoPlay,
56867
+ initialPlayPerformed = _ref.initialPlayPerformed,
56868
+ initialSeekPerformed = _ref.initialSeekPerformed,
56869
+ speed = _ref.speed,
56870
+ startTime = _ref.startTime;
56871
+ return playbackObserver.deriveReadOnlyObserver(function mapObservable(observation$) {
56872
+ return (0,combineLatest/* combineLatest */.a)([observation$, speed.asObservable()]).pipe((0,map/* map */.U)(function (_ref2) {
56873
+ var observation = _ref2[0],
56874
+ lastSpeed = _ref2[1];
56875
+ var wantedTimeOffset = 0;
56876
+
56877
+ if (!initialSeekPerformed.getValue()) {
56878
+ wantedTimeOffset = startTime - observation.position;
56879
+ } else if (!manifest.isDynamic || manifest.isLastPeriodKnown) {
56880
+ var lastPeriod = manifest.periods[manifest.periods.length - 1];
56881
+
56882
+ if (lastPeriod !== undefined && lastPeriod.end !== undefined && observation.position > lastPeriod.end) {
56883
+ wantedTimeOffset = lastPeriod.end - observation.position - 1;
56884
+ }
56885
+ }
56886
+
56887
+ return {
56888
+ // TODO more exact according to the current Adaptation chosen?
56889
+ maximumPosition: manifest.getMaximumSafePosition(),
56890
+ position: observation.position,
56891
+ duration: observation.duration,
56892
+ isPaused: initialPlayPerformed.getValue() ? observation.paused : !autoPlay,
56893
+ readyState: observation.readyState,
56894
+ speed: lastSpeed,
56895
+ // wantedTimeOffset is an offset to add to the timing's current time to have
56896
+ // the "real" wanted position.
56897
+ // For now, this is seen when the media element has not yet seeked to its
56898
+ // initial position, the currentTime will most probably be 0 where the
56899
+ // effective starting position will be _startTime_.
56900
+ // Thus we initially set a wantedTimeOffset equal to startTime.
56901
+ wantedTimeOffset: wantedTimeOffset
56902
+ };
56903
+ }));
56904
+ });
56660
56905
  }
56661
- /* eslint-enable @typescript-eslint/no-unsafe-argument */
56662
56906
  // EXTERNAL MODULE: ./src/core/init/emit_loaded_event.ts + 1 modules
56663
56907
  var emit_loaded_event = __webpack_require__(5039);
56664
56908
  ;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/util/argsOrArgArray.js
@@ -56830,6 +57074,253 @@ function maintainEndOfStream(mediaSource) {
56830
57074
  }
56831
57075
  // EXTERNAL MODULE: ./src/core/init/initial_seek_and_play.ts + 2 modules
56832
57076
  var initial_seek_and_play = __webpack_require__(7920);
57077
+ // EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/observable/timer.js
57078
+ var timer = __webpack_require__(6625);
57079
+ ;// CONCATENATED MODULE: ./src/core/init/media_duration_updater.ts
57080
+ /**
57081
+ * Copyright 2015 CANAL+ Group
57082
+ *
57083
+ * Licensed under the Apache License, Version 2.0 (the "License");
57084
+ * you may not use this file except in compliance with the License.
57085
+ * You may obtain a copy of the License at
57086
+ *
57087
+ * http://www.apache.org/licenses/LICENSE-2.0
57088
+ *
57089
+ * Unless required by applicable law or agreed to in writing, software
57090
+ * distributed under the License is distributed on an "AS IS" BASIS,
57091
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
57092
+ * See the License for the specific language governing permissions and
57093
+ * limitations under the License.
57094
+ */
57095
+
57096
+
57097
+
57098
+
57099
+
57100
+ /** Number of seconds in a regular year. */
57101
+
57102
+ var YEAR_IN_SECONDS = 365 * 24 * 3600;
57103
+ /**
57104
+ * Keep the MediaSource's duration up-to-date with what is being played.
57105
+ * @class MediaDurationUpdater
57106
+ */
57107
+
57108
+ var MediaDurationUpdater = /*#__PURE__*/function () {
57109
+ /**
57110
+ * Create a new `MediaDurationUpdater` that will keep the given MediaSource's
57111
+ * duration as soon as possible.
57112
+ * This duration will be updated until the `stop` method is called.
57113
+ * @param {Object} manifest - The Manifest currently played.
57114
+ * For another content, you will have to create another `MediaDurationUpdater`.
57115
+ * @param {MediaSource} mediaSource - The MediaSource on which the content is
57116
+ * pushed.
57117
+ */
57118
+ function MediaDurationUpdater(manifest, mediaSource) {
57119
+ var _this = this;
57120
+
57121
+ this._lastKnownDuration = (0,reference/* default */.Z)(undefined);
57122
+ this._subscription = isMediaSourceOpened$(mediaSource).pipe((0,switchMap/* switchMap */.w)(function (canUpdate) {
57123
+ return canUpdate ? (0,combineLatest/* combineLatest */.a)([_this._lastKnownDuration.asObservable(), (0,event_emitter/* fromEvent */.R)(manifest, "manifestUpdate").pipe((0,startWith/* startWith */.O)(null))]) : empty/* EMPTY */.E;
57124
+ }), (0,switchMap/* switchMap */.w)(function (_ref) {
57125
+ var lastKnownDuration = _ref[0];
57126
+ return areSourceBuffersUpdating$(mediaSource.sourceBuffers).pipe((0,switchMap/* switchMap */.w)(function (areSBUpdating) {
57127
+ return areSBUpdating ? empty/* EMPTY */.E : recursivelyTryUpdatingDuration();
57128
+
57129
+ function recursivelyTryUpdatingDuration() {
57130
+ var res = setMediaSourceDuration(mediaSource, manifest, lastKnownDuration);
57131
+
57132
+ if (res === "success"
57133
+ /* Success */
57134
+ ) {
57135
+ return empty/* EMPTY */.E;
57136
+ }
57137
+
57138
+ return (0,timer/* timer */.H)(2000).pipe((0,mergeMap/* mergeMap */.z)(function () {
57139
+ return recursivelyTryUpdatingDuration();
57140
+ }));
57141
+ }
57142
+ }));
57143
+ })).subscribe();
57144
+ }
57145
+ /**
57146
+ * By default, the `MediaDurationUpdater` only set a safe estimate for the
57147
+ * MediaSource's duration.
57148
+ * A more precize duration can be set by communicating to it a more precize
57149
+ * media duration through `updateKnownDuration`.
57150
+ * If the duration becomes unknown, `undefined` can be given to it so the
57151
+ * `MediaDurationUpdater` goes back to a safe estimate.
57152
+ * @param {number | undefined} newDuration
57153
+ */
57154
+
57155
+
57156
+ var _proto = MediaDurationUpdater.prototype;
57157
+
57158
+ _proto.updateKnownDuration = function updateKnownDuration(newDuration) {
57159
+ this._lastKnownDuration.setValue(newDuration);
57160
+ }
57161
+ /**
57162
+ * Stop the `MediaDurationUpdater` from updating and free its resources.
57163
+ * Once stopped, it is not possible to start it again, beside creating another
57164
+ * `MediaDurationUpdater`.
57165
+ */
57166
+ ;
57167
+
57168
+ _proto.stop = function stop() {
57169
+ this._subscription.unsubscribe();
57170
+ };
57171
+
57172
+ return MediaDurationUpdater;
57173
+ }();
57174
+ /**
57175
+ * Checks that duration can be updated on the MediaSource, and then
57176
+ * sets it.
57177
+ *
57178
+ * Returns either:
57179
+ * - the new duration it has been updated to if it has
57180
+ * - `null` if it hasn'nt been updated
57181
+ *
57182
+ * @param {MediaSource} mediaSource
57183
+ * @param {Object} manifest
57184
+ * @returns {string}
57185
+ */
57186
+
57187
+
57188
+
57189
+
57190
+ function setMediaSourceDuration(mediaSource, manifest, knownDuration) {
57191
+ var _a;
57192
+
57193
+ var newDuration = knownDuration;
57194
+
57195
+ if (newDuration === undefined) {
57196
+ if (manifest.isDynamic) {
57197
+ var maxPotentialPos = (_a = manifest.getLivePosition()) !== null && _a !== void 0 ? _a : manifest.getMaximumSafePosition(); // Some targets poorly support setting a very high number for durations.
57198
+ // Yet, in dynamic contents, we would prefer setting a value as high as possible
57199
+ // to still be able to seek anywhere we want to (even ahead of the Manifest if
57200
+ // we want to). As such, we put it at a safe default value of 2^32 excepted
57201
+ // when the maximum position is already relatively close to that value, where
57202
+ // we authorize exceptionally going over it.
57203
+
57204
+ newDuration = Math.max(Math.pow(2, 32), maxPotentialPos + YEAR_IN_SECONDS);
57205
+ } else {
57206
+ newDuration = manifest.getMaximumSafePosition();
57207
+ }
57208
+ }
57209
+
57210
+ var maxBufferedEnd = 0;
57211
+
57212
+ for (var i = 0; i < mediaSource.sourceBuffers.length; i++) {
57213
+ var sourceBuffer = mediaSource.sourceBuffers[i];
57214
+ var sbBufferedLen = sourceBuffer.buffered.length;
57215
+
57216
+ if (sbBufferedLen > 0) {
57217
+ maxBufferedEnd = Math.max(sourceBuffer.buffered.end(sbBufferedLen - 1));
57218
+ }
57219
+ }
57220
+
57221
+ if (newDuration === mediaSource.duration) {
57222
+ return "success"
57223
+ /* Success */
57224
+ ;
57225
+ } else if (maxBufferedEnd > newDuration) {
57226
+ // We already buffered further than the duration we want to set.
57227
+ // Keep the duration that was set at that time as a security.
57228
+ if (maxBufferedEnd < mediaSource.duration) {
57229
+ try {
57230
+ log/* default.info */.Z.info("Init: Updating duration to what is currently buffered", maxBufferedEnd);
57231
+ mediaSource.duration = newDuration;
57232
+ } catch (err) {
57233
+ log/* default.warn */.Z.warn("Duration Updater: Can't update duration on the MediaSource.", err);
57234
+ return "failed"
57235
+ /* Failed */
57236
+ ;
57237
+ }
57238
+ }
57239
+
57240
+ return "partial"
57241
+ /* Partial */
57242
+ ;
57243
+ } else {
57244
+ var oldDuration = mediaSource.duration;
57245
+
57246
+ try {
57247
+ log/* default.info */.Z.info("Init: Updating duration", newDuration);
57248
+ mediaSource.duration = newDuration;
57249
+ } catch (err) {
57250
+ log/* default.warn */.Z.warn("Duration Updater: Can't update duration on the MediaSource.", err);
57251
+ return "failed"
57252
+ /* Failed */
57253
+ ;
57254
+ }
57255
+
57256
+ var deltaToExpected = Math.abs(mediaSource.duration - newDuration);
57257
+
57258
+ if (deltaToExpected >= 0.1) {
57259
+ var deltaToBefore = Math.abs(mediaSource.duration - oldDuration);
57260
+ return deltaToExpected < deltaToBefore ? "partial"
57261
+ /* Partial */
57262
+ : "failed"
57263
+ /* Failed */
57264
+ ;
57265
+ }
57266
+
57267
+ return "success"
57268
+ /* Success */
57269
+ ;
57270
+ }
57271
+ }
57272
+ /**
57273
+ * Returns an Observable which will emit only when all the SourceBuffers ended
57274
+ * all pending updates.
57275
+ * @param {SourceBufferList} sourceBuffers
57276
+ * @returns {Observable}
57277
+ */
57278
+
57279
+
57280
+ function areSourceBuffersUpdating$(sourceBuffers) {
57281
+ if (sourceBuffers.length === 0) {
57282
+ return (0,of.of)(false);
57283
+ }
57284
+
57285
+ var sourceBufferUpdatingStatuses = [];
57286
+
57287
+ var _loop = function _loop(i) {
57288
+ var sourceBuffer = sourceBuffers[i];
57289
+ sourceBufferUpdatingStatuses.push((0,merge/* merge */.T)((0,fromEvent/* fromEvent */.R)(sourceBuffer, "updatestart").pipe((0,map/* map */.U)(function () {
57290
+ return true;
57291
+ })), (0,fromEvent/* fromEvent */.R)(sourceBuffer, "update").pipe((0,map/* map */.U)(function () {
57292
+ return false;
57293
+ })), (0,observable_interval/* interval */.F)(500).pipe((0,map/* map */.U)(function () {
57294
+ return sourceBuffer.updating;
57295
+ }))).pipe((0,startWith/* startWith */.O)(sourceBuffer.updating), (0,distinctUntilChanged/* distinctUntilChanged */.x)()));
57296
+ };
57297
+
57298
+ for (var i = 0; i < sourceBuffers.length; i++) {
57299
+ _loop(i);
57300
+ }
57301
+
57302
+ return (0,combineLatest/* combineLatest */.a)(sourceBufferUpdatingStatuses).pipe((0,map/* map */.U)(function (areUpdating) {
57303
+ return areUpdating.some(function (isUpdating) {
57304
+ return isUpdating;
57305
+ });
57306
+ }), (0,distinctUntilChanged/* distinctUntilChanged */.x)());
57307
+ }
57308
+ /**
57309
+ * Emit a boolean that tells if the media source is opened or not.
57310
+ * @param {MediaSource} mediaSource
57311
+ * @returns {Object}
57312
+ */
57313
+
57314
+
57315
+ function isMediaSourceOpened$(mediaSource) {
57316
+ return (0,merge/* merge */.T)((0,event_listeners/* onSourceOpen$ */.ym)(mediaSource).pipe((0,map/* map */.U)(function () {
57317
+ return true;
57318
+ })), (0,event_listeners/* onSourceEnded$ */.ep)(mediaSource).pipe((0,map/* map */.U)(function () {
57319
+ return false;
57320
+ })), (0,event_listeners/* onSourceClose$ */.UG)(mediaSource).pipe((0,map/* map */.U)(function () {
57321
+ return false;
57322
+ }))).pipe((0,startWith/* startWith */.O)(mediaSource.readyState === "open"), (0,distinctUntilChanged/* distinctUntilChanged */.x)());
57323
+ }
56833
57324
  // EXTERNAL MODULE: ./src/core/init/stall_avoider.ts + 1 modules
56834
57325
  var stall_avoider = __webpack_require__(467);
56835
57326
  ;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/pairwise.js
@@ -57160,6 +57651,7 @@ var update_playback_rate = __webpack_require__(2983);
57160
57651
 
57161
57652
 
57162
57653
 
57654
+
57163
57655
  /**
57164
57656
  * Returns a function allowing to load or reload the content in arguments into
57165
57657
  * a single or multiple MediaSources.
@@ -57187,7 +57679,7 @@ function createMediaSourceLoader(_ref) {
57187
57679
  /** Maintains the MediaSource's duration up-to-date with the Manifest */
57188
57680
 
57189
57681
 
57190
- var durationUpdater$ = DurationUpdater(manifest, mediaSource);
57682
+ var mediaDurationUpdater = new MediaDurationUpdater(manifest, mediaSource);
57191
57683
  var initialPeriod = (_a = manifest.getPeriodForTime(initialTime)) !== null && _a !== void 0 ? _a : manifest.getNextPeriod(initialTime);
57192
57684
 
57193
57685
  if (initialPeriod === undefined) {
@@ -57270,6 +57762,17 @@ function createMediaSourceLoader(_ref) {
57270
57762
  return (0,of.of)(evt);
57271
57763
  }
57272
57764
  }));
57765
+ var contentTimeObserver = ContentTimeBoundariesObserver(manifest, streams$, streamObserver).pipe((0,mergeMap/* mergeMap */.z)(function (evt) {
57766
+ switch (evt.type) {
57767
+ case "contentDurationUpdate":
57768
+ log/* default.debug */.Z.debug("Init: Duration has to be updated.", evt.value);
57769
+ mediaDurationUpdater.updateKnownDuration(evt.value);
57770
+ return empty/* EMPTY */.E;
57771
+
57772
+ default:
57773
+ return (0,of.of)(evt);
57774
+ }
57775
+ }));
57273
57776
  /**
57274
57777
  * On subscription, keep the playback speed synchronized to the speed set by
57275
57778
  * the user on the media element and force a speed of `0` when the buffer is
@@ -57292,14 +57795,13 @@ function createMediaSourceLoader(_ref) {
57292
57795
  var loadingEvts$ = seekAndPlay$.pipe((0,switchMap/* switchMap */.w)(function (evt) {
57293
57796
  return evt.type === "warning" ? (0,of.of)(evt) : (0,emit_loaded_event/* default */.Z)(observation$, mediaElement, segmentBuffersStore, false);
57294
57797
  }));
57295
- return (0,merge/* merge */.T)(durationUpdater$, loadingEvts$, playbackRate$, stallAvoider$, streams$, streamEvents$).pipe(finalize(function () {
57296
- // clean-up every created SegmentBuffers
57798
+ return (0,merge/* merge */.T)(loadingEvts$, playbackRate$, stallAvoider$, streams$, contentTimeObserver, streamEvents$).pipe(finalize(function () {
57799
+ mediaDurationUpdater.stop(); // clean-up every created SegmentBuffers
57800
+
57297
57801
  segmentBuffersStore.disposeAll();
57298
57802
  }));
57299
57803
  };
57300
57804
  }
57301
- // EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/observable/timer.js
57302
- var timer = __webpack_require__(6625);
57303
57805
  ;// CONCATENATED MODULE: ./src/utils/rx-throttle.ts
57304
57806
  /**
57305
57807
  * Copyright 2015 CANAL+ Group
@@ -60490,7 +60992,7 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
60490
60992
  videoElement.preload = "auto";
60491
60993
  _this.version =
60492
60994
  /* PLAYER_VERSION */
60493
- "3.27.0";
60995
+ "3.27.1-dev.2022041500";
60494
60996
  _this.log = log/* default */.Z;
60495
60997
  _this.state = "STOPPED";
60496
60998
  _this.videoElement = videoElement;
@@ -61744,14 +62246,7 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
61744
62246
  throw new Error("invalid time given");
61745
62247
  }
61746
62248
 
61747
- var seekAt = positionWanted;
61748
-
61749
- if (manifest !== null && !manifest.isLive) {
61750
- var maximumTime = manifest.getMaximumPosition();
61751
- seekAt = maximumTime !== undefined ? Math.min(positionWanted, maximumTime - 0.001) : positionWanted;
61752
- }
61753
-
61754
- this.videoElement.currentTime = seekAt;
62249
+ this.videoElement.currentTime = positionWanted;
61755
62250
  return positionWanted;
61756
62251
  }
61757
62252
  /**
@@ -62510,7 +63005,7 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
62510
63005
  var manifest = this._priv_contentInfos.manifest;
62511
63006
 
62512
63007
  if (manifest !== null) {
62513
- return manifest.getMinimumPosition();
63008
+ return manifest.getMinimumSafePosition();
62514
63009
  }
62515
63010
 
62516
63011
  return null;
@@ -62539,7 +63034,11 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
62539
63034
  }
62540
63035
 
62541
63036
  if (manifest !== null) {
62542
- return manifest.getMaximumPosition();
63037
+ if (!manifest.isDynamic && this.videoElement !== null) {
63038
+ return this.videoElement.duration;
63039
+ }
63040
+
63041
+ return manifest.getMaximumSafePosition();
62543
63042
  }
62544
63043
 
62545
63044
  return null;
@@ -63212,7 +63711,7 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
63212
63711
  }
63213
63712
 
63214
63713
  this._priv_lastContentPlaybackInfos.lastPlaybackPosition = observation.position;
63215
- var maximumPosition = manifest !== null ? manifest.getMaximumPosition() : undefined;
63714
+ var maximumPosition = manifest !== null ? manifest.getMaximumSafePosition() : undefined;
63216
63715
  var positionData = {
63217
63716
  position: observation.position,
63218
63717
  duration: observation.duration,
@@ -63222,10 +63721,14 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
63222
63721
  bufferGap: isFinite(observation.bufferGap) ? observation.bufferGap : 0
63223
63722
  };
63224
63723
 
63225
- if (manifest !== null && maximumPosition !== undefined && manifest.isLive && observation.position > 0) {
63724
+ if (manifest !== null && manifest.isLive && observation.position > 0) {
63226
63725
  var ast = (_a = manifest.availabilityStartTime) !== null && _a !== void 0 ? _a : 0;
63227
63726
  positionData.wallClockTime = observation.position + ast;
63228
- positionData.liveGap = maximumPosition - observation.position;
63727
+ var livePosition = manifest.getLivePosition();
63728
+
63729
+ if (livePosition !== undefined) {
63730
+ positionData.liveGap = livePosition - observation.position;
63731
+ }
63229
63732
  } else if (isDirectFile && this.videoElement !== null) {
63230
63733
  var startDate = getStartDate(this.videoElement);
63231
63734
 
@@ -63322,7 +63825,7 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
63322
63825
 
63323
63826
  Player.version =
63324
63827
  /* PLAYER_VERSION */
63325
- "3.27.0";
63828
+ "3.27.1-dev.2022041500";
63326
63829
  /* harmony default export */ var public_api = (Player);
63327
63830
  ;// CONCATENATED MODULE: ./src/core/api/index.ts
63328
63831
  /**
@@ -63394,7 +63897,7 @@ function initializeFeaturesObject() {
63394
63897
 
63395
63898
  if (true) {
63396
63899
  features_object/* default.transports.dash */.Z.transports.dash = (__webpack_require__(5877)/* ["default"] */ .Z);
63397
- features_object/* default.dashParsers.js */.Z.dashParsers.js = (__webpack_require__(3501)/* ["default"] */ .Z);
63900
+ features_object/* default.dashParsers.js */.Z.dashParsers.js = (__webpack_require__(4846)/* ["default"] */ .Z);
63398
63901
  }
63399
63902
 
63400
63903
  if (false) {}