rx-player 3.33.0-dev.2023120600 → 3.33.0

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 (67) hide show
  1. package/CHANGELOG.md +12 -3
  2. package/README.md +2 -33
  3. package/VERSION +1 -1
  4. package/dist/_esm5.processed/compat/browser_detection.d.ts +3 -1
  5. package/dist/_esm5.processed/compat/browser_detection.js +24 -4
  6. package/dist/_esm5.processed/compat/should_prevent_seeking_at_0_initially.d.ts +14 -0
  7. package/dist/_esm5.processed/compat/should_prevent_seeking_at_0_initially.js +17 -0
  8. package/dist/_esm5.processed/config.d.ts +1 -0
  9. package/dist/_esm5.processed/core/api/public_api.js +3 -3
  10. package/dist/_esm5.processed/core/decrypt/attach_media_keys.d.ts +2 -1
  11. package/dist/_esm5.processed/core/decrypt/attach_media_keys.js +2 -1
  12. package/dist/_esm5.processed/core/decrypt/init_media_keys.js +13 -5
  13. package/dist/_esm5.processed/core/init/directfile_content_initializer.js +1 -1
  14. package/dist/_esm5.processed/core/init/media_source_content_initializer.js +1 -1
  15. package/dist/_esm5.processed/core/init/utils/get_loaded_reference.js +7 -5
  16. package/dist/_esm5.processed/core/init/utils/initial_seek_and_play.d.ts +2 -1
  17. package/dist/_esm5.processed/core/init/utils/initial_seek_and_play.js +59 -6
  18. package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +9 -2
  19. package/dist/_esm5.processed/core/segment_buffers/implementations/image/image_segment_buffer.js +1 -1
  20. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +1 -1
  21. package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.js +1 -1
  22. package/dist/_esm5.processed/core/segment_buffers/implementations/types.d.ts +6 -1
  23. package/dist/_esm5.processed/core/segment_buffers/implementations/types.js +7 -2
  24. package/dist/_esm5.processed/core/segment_buffers/index.d.ts +2 -2
  25. package/dist/_esm5.processed/core/segment_buffers/inventory/index.d.ts +2 -2
  26. package/dist/_esm5.processed/core/segment_buffers/inventory/segment_inventory.d.ts +31 -9
  27. package/dist/_esm5.processed/core/segment_buffers/inventory/segment_inventory.js +27 -12
  28. package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +16 -11
  29. package/dist/_esm5.processed/core/stream/representation/utils/get_buffer_status.js +3 -2
  30. package/dist/_esm5.processed/default_config.d.ts +7 -0
  31. package/dist/_esm5.processed/default_config.js +16 -0
  32. package/dist/_esm5.processed/manifest/manifest.js +8 -4
  33. package/dist/_esm5.processed/manifest/period.d.ts +3 -1
  34. package/dist/_esm5.processed/manifest/period.js +16 -3
  35. package/dist/mpd-parser.wasm +0 -0
  36. package/dist/rx-player.d.ts +1 -1
  37. package/dist/rx-player.js +262 -77
  38. package/dist/rx-player.min.d.ts +1 -1
  39. package/dist/rx-player.min.js +1 -1
  40. package/package.json +5 -1
  41. package/scripts/canal-release.patch +24 -28
  42. package/scripts/make-dev-releases +90 -0
  43. package/scripts/update-version +5 -0
  44. package/sonar-project.properties +1 -1
  45. package/src/compat/browser_detection.ts +21 -1
  46. package/src/compat/should_prevent_seeking_at_0_initially.ts +19 -0
  47. package/src/core/api/public_api.ts +3 -3
  48. package/src/core/decrypt/attach_media_keys.ts +5 -2
  49. package/src/core/decrypt/init_media_keys.ts +10 -1
  50. package/src/core/init/directfile_content_initializer.ts +1 -0
  51. package/src/core/init/media_source_content_initializer.ts +1 -0
  52. package/src/core/init/utils/get_loaded_reference.ts +7 -5
  53. package/src/core/init/utils/initial_seek_and_play.ts +59 -5
  54. package/src/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.ts +10 -2
  55. package/src/core/segment_buffers/implementations/image/image_segment_buffer.ts +1 -1
  56. package/src/core/segment_buffers/implementations/text/html/html_text_segment_buffer.ts +1 -1
  57. package/src/core/segment_buffers/implementations/text/native/native_text_segment_buffer.ts +1 -1
  58. package/src/core/segment_buffers/implementations/types.ts +7 -2
  59. package/src/core/segment_buffers/index.ts +2 -0
  60. package/src/core/segment_buffers/inventory/index.ts +2 -0
  61. package/src/core/segment_buffers/inventory/segment_inventory.ts +56 -19
  62. package/src/core/stream/orchestrator/stream_orchestrator.ts +19 -15
  63. package/src/core/stream/representation/utils/get_buffer_status.ts +4 -2
  64. package/src/default_config.ts +17 -0
  65. package/src/manifest/manifest.ts +8 -4
  66. package/src/manifest/period.ts +16 -3
  67. package/scripts/make-releases +0 -26
@@ -49,9 +49,15 @@ var SegmentInventory = /** @class */ (function () {
49
49
  * at a time, so each `synchronizeBuffered` call should be given a TimeRanges
50
50
  * coming from the same buffer.
51
51
  * @param {TimeRanges} buffered
52
+ * @param {boolean|undefined} [skipLog=false] - This method normally may
53
+ * trigger a voluminous debug log if debug logs are enabled.
54
+ * As this method might be called very often in some specific debugging
55
+ * situations, setting this value to `true` allows to prevent the call from
56
+ * triggering a log.
52
57
  */
53
- SegmentInventory.prototype.synchronizeBuffered = function (buffered) {
58
+ SegmentInventory.prototype.synchronizeBuffered = function (buffered, skipLog) {
54
59
  var _a, _b, _c, _d, _e, _f, _g;
60
+ if (skipLog === void 0) { skipLog = false; }
55
61
  var inventory = this._inventory;
56
62
  var inventoryIndex = 0; // Current index considered.
57
63
  var thisSegment = inventory[0]; // Current segmentInfos considered
@@ -97,7 +103,9 @@ var SegmentInventory = /** @class */ (function () {
97
103
  var removed = inventory.splice(indexBefore, numberOfSegmentToDelete);
98
104
  for (var _i = 0, removed_1 = removed; _i < removed_1.length; _i++) {
99
105
  var seg = removed_1[_i];
100
- if (seg.bufferedStart === undefined && seg.bufferedEnd === undefined) {
106
+ if (seg.bufferedStart === undefined &&
107
+ seg.bufferedEnd === undefined &&
108
+ seg.status !== 2 /* ChunkStatus.Failed */) {
101
109
  this._bufferedHistory.addBufferedSegment(seg.infos, null);
102
110
  }
103
111
  }
@@ -156,12 +164,14 @@ var SegmentInventory = /** @class */ (function () {
156
164
  var removed = inventory.splice(inventoryIndex, inventory.length - inventoryIndex);
157
165
  for (var _h = 0, removed_2 = removed; _h < removed_2.length; _h++) {
158
166
  var seg = removed_2[_h];
159
- if (seg.bufferedStart === undefined && seg.bufferedEnd === undefined) {
167
+ if (seg.bufferedStart === undefined &&
168
+ seg.bufferedEnd === undefined &&
169
+ seg.status !== 2 /* ChunkStatus.Failed */) {
160
170
  this._bufferedHistory.addBufferedSegment(seg.infos, null);
161
171
  }
162
172
  }
163
173
  }
164
- if (bufferType !== undefined && log.hasLevel("DEBUG")) {
174
+ if (!skipLog && bufferType !== undefined && log.hasLevel("DEBUG")) {
165
175
  log.debug("SI: current ".concat(bufferType, " inventory timeline:\n") +
166
176
  prettyPrintInventory(this._inventory));
167
177
  }
@@ -173,7 +183,7 @@ var SegmentInventory = /** @class */ (function () {
173
183
  * segment have been inserted, you should call the `completeSegment` method.
174
184
  * @param {Object} chunkInformation
175
185
  */
176
- SegmentInventory.prototype.insertChunk = function (_a) {
186
+ SegmentInventory.prototype.insertChunk = function (_a, succeed) {
177
187
  var period = _a.period, adaptation = _a.adaptation, representation = _a.representation, segment = _a.segment, chunkSize = _a.chunkSize, start = _a.start, end = _a.end;
178
188
  if (segment.isInit) {
179
189
  return;
@@ -184,7 +194,8 @@ var SegmentInventory = /** @class */ (function () {
184
194
  return;
185
195
  }
186
196
  var inventory = this._inventory;
187
- var newSegment = { partiallyPushed: true, chunkSize: chunkSize, splitted: false, start: start, end: end, precizeStart: false,
197
+ var newSegment = { status: succeed ? 0 /* ChunkStatus.PartiallyPushed */ :
198
+ 2 /* ChunkStatus.Failed */, chunkSize: chunkSize, splitted: false, start: start, end: end, precizeStart: false,
188
199
  precizeEnd: false,
189
200
  bufferedStart: undefined,
190
201
  bufferedEnd: undefined,
@@ -377,7 +388,7 @@ var SegmentInventory = /** @class */ (function () {
377
388
  // newSegment : |====|
378
389
  // ===> : |--|====|-|
379
390
  log.warn("SI: Segment pushed is contained in a previous one", bufferType, start, end, segmentI.start, segmentI.end);
380
- var nextSegment = { partiallyPushed: segmentI.partiallyPushed,
391
+ var nextSegment = { status: segmentI.status,
381
392
  /**
382
393
  * Note: this sadly means we're doing as if
383
394
  * that chunk is present two times.
@@ -535,7 +546,9 @@ var SegmentInventory = /** @class */ (function () {
535
546
  this._inventory.splice(firstI + 1, length_1);
536
547
  i -= length_1;
537
548
  }
538
- this._inventory[firstI].partiallyPushed = false;
549
+ if (this._inventory[firstI].status === 0 /* ChunkStatus.PartiallyPushed */) {
550
+ this._inventory[firstI].status = 1 /* ChunkStatus.Complete */;
551
+ }
539
552
  this._inventory[firstI].chunkSize = segmentSize;
540
553
  this._inventory[firstI].end = lastEnd;
541
554
  this._inventory[firstI].bufferedEnd = lastBufferedEnd;
@@ -551,8 +564,10 @@ var SegmentInventory = /** @class */ (function () {
551
564
  for (var _i = 0, resSegments_1 = resSegments; _i < resSegments_1.length; _i++) {
552
565
  var seg = resSegments_1[_i];
553
566
  if (seg.bufferedStart !== undefined && seg.bufferedEnd !== undefined) {
554
- this._bufferedHistory.addBufferedSegment(seg.infos, { start: seg.bufferedStart,
555
- end: seg.bufferedEnd });
567
+ if (seg.status !== 2 /* ChunkStatus.Failed */) {
568
+ this._bufferedHistory.addBufferedSegment(seg.infos, { start: seg.bufferedStart,
569
+ end: seg.bufferedEnd });
570
+ }
556
571
  }
557
572
  else {
558
573
  log.debug("SI: buffered range not known after sync. Skipping history.", seg.start, seg.end);
@@ -597,7 +612,7 @@ export default SegmentInventory;
597
612
  */
598
613
  function bufferedStartLooksCoherent(thisSegment) {
599
614
  if (thisSegment.bufferedStart === undefined ||
600
- thisSegment.partiallyPushed) {
615
+ thisSegment.status !== 1 /* ChunkStatus.Complete */) {
601
616
  return false;
602
617
  }
603
618
  var start = thisSegment.start, end = thisSegment.end;
@@ -618,7 +633,7 @@ function bufferedStartLooksCoherent(thisSegment) {
618
633
  */
619
634
  function bufferedEndLooksCoherent(thisSegment) {
620
635
  if (thisSegment.bufferedEnd === undefined ||
621
- thisSegment.partiallyPushed) {
636
+ thisSegment.status !== 1 /* ChunkStatus.Complete */) {
622
637
  return false;
623
638
  }
624
639
  var start = thisSegment.start, end = thisSegment.end;
@@ -125,23 +125,22 @@ import getTimeRangesForContent from "./get_time_ranges_for_content";
125
125
  export default function StreamOrchestrator(content, playbackObserver, representationEstimator, segmentBuffersStore, segmentFetcherCreator, options, callbacks, orchestratorCancelSignal) {
126
126
  var manifest = content.manifest, initialPeriod = content.initialPeriod;
127
127
  var maxBufferAhead = options.maxBufferAhead, maxBufferBehind = options.maxBufferBehind, wantedBufferAhead = options.wantedBufferAhead, maxVideoBufferSize = options.maxVideoBufferSize;
128
- var _a = config.getCurrent(), MAXIMUM_MAX_BUFFER_AHEAD = _a.MAXIMUM_MAX_BUFFER_AHEAD, MAXIMUM_MAX_BUFFER_BEHIND = _a.MAXIMUM_MAX_BUFFER_BEHIND;
128
+ var _a = config.getCurrent(), MINIMUM_MAX_BUFFER_AHEAD = _a.MINIMUM_MAX_BUFFER_AHEAD, MAXIMUM_MAX_BUFFER_AHEAD = _a.MAXIMUM_MAX_BUFFER_AHEAD, MAXIMUM_MAX_BUFFER_BEHIND = _a.MAXIMUM_MAX_BUFFER_BEHIND;
129
129
  // Keep track of a unique BufferGarbageCollector created per
130
130
  // SegmentBuffer.
131
131
  var garbageCollectors = new WeakMapMemory(function (segmentBuffer) {
132
+ var _a, _b;
132
133
  var bufferType = segmentBuffer.bufferType;
133
- var defaultMaxBehind = MAXIMUM_MAX_BUFFER_BEHIND[bufferType] != null ?
134
- MAXIMUM_MAX_BUFFER_BEHIND[bufferType] :
135
- Infinity;
136
- var defaultMaxAhead = MAXIMUM_MAX_BUFFER_AHEAD[bufferType] != null ?
137
- MAXIMUM_MAX_BUFFER_AHEAD[bufferType] :
138
- Infinity;
134
+ var defaultMaxBehind = (_a = MAXIMUM_MAX_BUFFER_BEHIND[bufferType]) !== null && _a !== void 0 ? _a : Infinity;
135
+ var maxAheadHigherBound = (_b = MAXIMUM_MAX_BUFFER_AHEAD[bufferType]) !== null && _b !== void 0 ? _b : Infinity;
139
136
  return function (gcCancelSignal) {
140
137
  BufferGarbageCollector({ segmentBuffer: segmentBuffer, playbackObserver: playbackObserver, maxBufferBehind: createMappedReference(maxBufferBehind, function (val) {
141
138
  return Math.min(val, defaultMaxBehind);
142
139
  }, gcCancelSignal),
143
140
  maxBufferAhead: createMappedReference(maxBufferAhead, function (val) {
144
- return Math.min(val, defaultMaxAhead);
141
+ var _a;
142
+ var lowerBound = Math.max(val, (_a = MINIMUM_MAX_BUFFER_AHEAD[bufferType]) !== null && _a !== void 0 ? _a : 0);
143
+ return Math.min(lowerBound, maxAheadHigherBound);
145
144
  }, gcCancelSignal) }, gcCancelSignal);
146
145
  };
147
146
  });
@@ -195,6 +194,7 @@ export default function StreamOrchestrator(content, playbackObserver, representa
195
194
  var nextPeriod = (_c = manifest.getPeriodForTime(time)) !== null && _c !== void 0 ? _c : manifest.getNextPeriod(time);
196
195
  if (nextPeriod === undefined) {
197
196
  log.warn("Stream: The wanted position is not found in the Manifest.");
197
+ enableOutOfBoundsCheck = true;
198
198
  return;
199
199
  }
200
200
  launchConsecutiveStreamsForPeriod(nextPeriod);
@@ -258,7 +258,7 @@ export default function StreamOrchestrator(content, playbackObserver, representa
258
258
  }
259
259
  /**
260
260
  * React to a Manifest's decipherability updates.
261
- * @param {Array.<Object>}
261
+ * @param {Array.<Object>} updates
262
262
  * @returns {Promise}
263
263
  */
264
264
  function onDecipherabilityUpdates(updates) {
@@ -400,8 +400,13 @@ export default function StreamOrchestrator(content, playbackObserver, representa
400
400
  playbackObserver.listen(function (_a, stopListeningObservations) {
401
401
  var _b, _c;
402
402
  var position = _a.position;
403
- if (basePeriod.end !== undefined &&
404
- ((_b = position.pending) !== null && _b !== void 0 ? _b : position.last) >= basePeriod.end) {
403
+ var wantedPosition = (_b = position.pending) !== null && _b !== void 0 ? _b : position.last;
404
+ if (basePeriod.end !== undefined && wantedPosition >= basePeriod.end) {
405
+ var nextPeriod = manifest.getPeriodAfter(basePeriod);
406
+ // Handle special wantedPosition === basePeriod.end cases
407
+ if (basePeriod.containsTime(wantedPosition, nextPeriod)) {
408
+ return;
409
+ }
405
410
  log.info("Stream: Destroying PeriodStream as the current playhead moved above it", bufferType, basePeriod.start, (_c = position.pending) !== null && _c !== void 0 ? _c : position.last, basePeriod.end);
406
411
  stopListeningObservations();
407
412
  consecutivePeriodStreamCb.periodStreamCleared({ type: bufferType,
@@ -163,7 +163,8 @@ function getRangeOfNeededSegments(content, initialWantedTime, bufferGoal) {
163
163
  */
164
164
  function isPeriodTheCurrentAndLastOne(manifest, period, time) {
165
165
  var _a;
166
- return period.containsTime(time) &&
166
+ var nextPeriod = manifest.getPeriodAfter(period);
167
+ return period.containsTime(time, nextPeriod) &&
167
168
  manifest.isLastPeriodKnown &&
168
169
  period.id === ((_a = manifest.periods[manifest.periods.length - 1]) === null || _a === void 0 ? void 0 : _a.id);
169
170
  }
@@ -184,7 +185,7 @@ function getPlayableBufferedSegments(neededRange, segmentInventory) {
184
185
  for (var i = segmentInventory.length - 1; i >= 0; i--) {
185
186
  var eltInventory = segmentInventory[i];
186
187
  var representation = eltInventory.infos.representation;
187
- if (!eltInventory.partiallyPushed &&
188
+ if (eltInventory.status === 1 /* ChunkStatus.Complete */ &&
188
189
  representation.decipherable !== false &&
189
190
  representation.isSupported) {
190
191
  var inventorySegment = eltInventory.infos.segment;
@@ -179,6 +179,13 @@ declare const DEFAULT_CONFIG: {
179
179
  * @type {Object}
180
180
  */
181
181
  MAXIMUM_MAX_BUFFER_AHEAD: Partial<Record<"audio" | "video" | "image" | "text", number>>;
182
+ /**
183
+ * Minimum possible buffer ahead for each type of buffer, to avoid Garbage
184
+ * Collecting too much data when it would have adverse effects.
185
+ * Equal to `0` if not defined here.
186
+ * @type {Object}
187
+ */
188
+ MINIMUM_MAX_BUFFER_AHEAD: Partial<Record<"audio" | "video" | "image" | "text", number>>;
182
189
  /**
183
190
  * Maximum possible buffer behind for each type of buffer, to avoid too much
184
191
  * memory usage when playing for a long time.
@@ -182,6 +182,22 @@ var DEFAULT_CONFIG = {
182
182
  },
183
183
  /* eslint-enable @typescript-eslint/consistent-type-assertions */
184
184
  /* eslint-disable @typescript-eslint/consistent-type-assertions */
185
+ /**
186
+ * Minimum possible buffer ahead for each type of buffer, to avoid Garbage
187
+ * Collecting too much data when it would have adverse effects.
188
+ * Equal to `0` if not defined here.
189
+ * @type {Object}
190
+ */
191
+ MINIMUM_MAX_BUFFER_AHEAD: {
192
+ // Text segments are both much lighter on resources and might
193
+ // actually be much larger than other types of segments in terms
194
+ // of duration. Let's make an exception here by authorizing a
195
+ // larger text buffer ahead, to avoid unnecesarily reloading the
196
+ // same text track.
197
+ text: 2 * 60,
198
+ },
199
+ /* eslint-enable @typescript-eslint/consistent-type-assertions */
200
+ /* eslint-disable @typescript-eslint/consistent-type-assertions */
185
201
  /**
186
202
  * Maximum possible buffer behind for each type of buffer, to avoid too much
187
203
  * memory usage when playing for a long time.
@@ -132,10 +132,14 @@ var Manifest = /** @class */ (function (_super) {
132
132
  * @returns {Object|undefined}
133
133
  */
134
134
  Manifest.prototype.getPeriodForTime = function (time) {
135
- return arrayFind(this.periods, function (period) {
136
- return time >= period.start &&
137
- (period.end === undefined || period.end > time);
138
- });
135
+ var nextPeriod = null;
136
+ for (var i = this.periods.length - 1; i >= 0; i--) {
137
+ var period = this.periods[i];
138
+ if (period.containsTime(time, nextPeriod)) {
139
+ return period;
140
+ }
141
+ nextPeriod = period;
142
+ }
139
143
  };
140
144
  /**
141
145
  * Returns the first Period starting strictly after the given time.
@@ -68,7 +68,9 @@ export default class Period {
68
68
  /**
69
69
  * Returns true if the give time is in the time boundaries of this `Period`.
70
70
  * @param {number} time
71
+ * @param {object|null} nextPeriod - Period coming chronologically just
72
+ * after in the same Manifest. `null` if this instance is the last `Period`.
71
73
  * @returns {boolean}
72
74
  */
73
- containsTime(time: number): boolean;
75
+ containsTime(time: number, nextPeriod: Period | null): boolean;
74
76
  }
@@ -130,11 +130,24 @@ var Period = /** @class */ (function () {
130
130
  /**
131
131
  * Returns true if the give time is in the time boundaries of this `Period`.
132
132
  * @param {number} time
133
+ * @param {object|null} nextPeriod - Period coming chronologically just
134
+ * after in the same Manifest. `null` if this instance is the last `Period`.
133
135
  * @returns {boolean}
134
136
  */
135
- Period.prototype.containsTime = function (time) {
136
- return time >= this.start && (this.end === undefined ||
137
- time < this.end);
137
+ Period.prototype.containsTime = function (time, nextPeriod) {
138
+ if (time >= this.start && (this.end === undefined || time < this.end)) {
139
+ return true;
140
+ }
141
+ else if (time === this.end && (nextPeriod === null ||
142
+ nextPeriod.start > this.end)) {
143
+ // The last possible timed position of a Period is ambiguous as it is
144
+ // frequently in common with the start of the next one: is it part of
145
+ // the current or of the next Period?
146
+ // Here we only consider it part of the current Period if it is the
147
+ // only one with that position.
148
+ return true;
149
+ }
150
+ return false;
138
151
  };
139
152
  return Period;
140
153
  }());
Binary file
@@ -1,3 +1,3 @@
1
1
 
2
- import RxPlayer from "./_esm5.processed/index";
2
+ import RxPlayer from "./_esm5.processed/core/api/index";
3
3
  export default RxPlayer;