rx-player 3.30.1-dev.2023032300 → 3.30.1-dev.2023032800

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 (40) hide show
  1. package/CHANGELOG.md +8 -2
  2. package/VERSION +1 -1
  3. package/dist/_esm5.processed/compat/eme/load_session.js +1 -1
  4. package/dist/_esm5.processed/config.d.ts +2 -0
  5. package/dist/_esm5.processed/core/adaptive/adaptive_representation_selector.js +4 -2
  6. package/dist/_esm5.processed/core/adaptive/buffer_based_chooser.js +4 -4
  7. package/dist/_esm5.processed/core/adaptive/network_analyzer.js +8 -5
  8. package/dist/_esm5.processed/core/api/playback_observer.js +1 -0
  9. package/dist/_esm5.processed/core/api/public_api.js +3 -2
  10. package/dist/_esm5.processed/core/decrypt/utils/clean_old_loaded_sessions.js +2 -0
  11. package/dist/_esm5.processed/core/decrypt/utils/loaded_sessions_store.js +5 -1
  12. package/dist/_esm5.processed/core/init/media_source_content_initializer.js +6 -5
  13. package/dist/_esm5.processed/core/init/utils/content_time_boundaries_observer.d.ts +28 -1
  14. package/dist/_esm5.processed/core/init/utils/content_time_boundaries_observer.js +22 -9
  15. package/dist/_esm5.processed/core/init/utils/media_source_duration_updater.d.ts +58 -0
  16. package/dist/_esm5.processed/core/init/utils/{media_duration_updater.js → media_source_duration_updater.js} +71 -85
  17. package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +3 -3
  18. package/dist/_esm5.processed/default_config.d.ts +25 -0
  19. package/dist/_esm5.processed/default_config.js +27 -2
  20. package/dist/_esm5.processed/utils/is_null_or_undefined.d.ts +1 -1
  21. package/dist/_esm5.processed/utils/is_null_or_undefined.js +1 -1
  22. package/dist/rx-player.js +168 -120
  23. package/dist/rx-player.min.js +1 -1
  24. package/package.json +1 -1
  25. package/sonar-project.properties +1 -1
  26. package/src/compat/eme/load_session.ts +1 -1
  27. package/src/core/adaptive/adaptive_representation_selector.ts +6 -2
  28. package/src/core/adaptive/buffer_based_chooser.ts +4 -4
  29. package/src/core/adaptive/network_analyzer.ts +9 -4
  30. package/src/core/api/playback_observer.ts +1 -0
  31. package/src/core/api/public_api.ts +3 -2
  32. package/src/core/decrypt/utils/clean_old_loaded_sessions.ts +2 -1
  33. package/src/core/decrypt/utils/loaded_sessions_store.ts +8 -1
  34. package/src/core/init/media_source_content_initializer.ts +7 -5
  35. package/src/core/init/utils/content_time_boundaries_observer.ts +46 -10
  36. package/src/core/init/utils/{media_duration_updater.ts → media_source_duration_updater.ts} +87 -111
  37. package/src/core/stream/orchestrator/stream_orchestrator.ts +4 -4
  38. package/src/default_config.ts +29 -2
  39. package/src/utils/is_null_or_undefined.ts +1 -1
  40. package/dist/_esm5.processed/core/init/utils/media_duration_updater.d.ts +0 -56
@@ -20,90 +20,83 @@ import TaskCanceller from "../../../utils/task_canceller";
20
20
  /** Number of seconds in a regular year. */
21
21
  var YEAR_IN_SECONDS = 365 * 24 * 3600;
22
22
  /**
23
- * Keep the MediaSource's duration up-to-date with what is being played.
24
- * @class MediaDurationUpdater
23
+ * Keep the MediaSource's `duration` attribute up-to-date with the duration of
24
+ * the content played on it.
25
+ * @class MediaSourceDurationUpdater
25
26
  */
26
- var MediaDurationUpdater = /** @class */ (function () {
27
+ var MediaSourceDurationUpdater = /** @class */ (function () {
27
28
  /**
28
- * Create a new `MediaDurationUpdater` that will keep the given MediaSource's
29
- * duration as soon as possible.
30
- * This duration will be updated until the `stop` method is called.
31
- * @param {Object} manifest - The Manifest currently played.
32
- * For another content, you will have to create another `MediaDurationUpdater`.
29
+ * Create a new `MediaSourceDurationUpdater`,
33
30
  * @param {MediaSource} mediaSource - The MediaSource on which the content is
34
- * pushed.
31
+ * played.
35
32
  */
36
- function MediaDurationUpdater(manifest, mediaSource) {
37
- var canceller = new TaskCanceller();
38
- var currentKnownDuration = createSharedReference(undefined, canceller.signal);
39
- this._canceller = canceller;
40
- this._currentKnownDuration = currentKnownDuration;
41
- var isMediaSourceOpened = createMediaSourceOpenReference(mediaSource, this._canceller.signal);
42
- /** TaskCanceller triggered each time the MediaSource open status changes. */
43
- var msUpdateCanceller = new TaskCanceller();
44
- msUpdateCanceller.linkToSignal(this._canceller.signal);
33
+ function MediaSourceDurationUpdater(mediaSource) {
34
+ this._mediaSource = mediaSource;
35
+ this._currentMediaSourceDurationUpdateCanceller = null;
36
+ }
37
+ /**
38
+ * Indicate to the `MediaSourceDurationUpdater` the currently known duration
39
+ * of the content.
40
+ *
41
+ * The `MediaSourceDurationUpdater` will then use that value to determine
42
+ * which `duration` attribute should be set on the `MediaSource` associated
43
+ *
44
+ * @param {number} newDuration
45
+ * @param {boolean} addTimeMargin - If set to `true`, the current content is
46
+ * a dynamic content (it might evolve in the future) and the `newDuration`
47
+ * communicated might be greater still. In effect the
48
+ * `MediaSourceDurationUpdater` will actually set a much higher value to the
49
+ * `MediaSource`'s duration to prevent being annoyed by the HTML-related
50
+ * side-effects of having a too low duration (such as the impossibility to
51
+ * seek over that value).
52
+ */
53
+ MediaSourceDurationUpdater.prototype.updateDuration = function (newDuration, addTimeMargin) {
54
+ if (this._currentMediaSourceDurationUpdateCanceller !== null) {
55
+ this._currentMediaSourceDurationUpdateCanceller.cancel();
56
+ }
57
+ this._currentMediaSourceDurationUpdateCanceller = new TaskCanceller();
58
+ var mediaSource = this._mediaSource;
59
+ var currentSignal = this._currentMediaSourceDurationUpdateCanceller.signal;
60
+ var isMediaSourceOpened = createMediaSourceOpenReference(mediaSource, currentSignal);
61
+ /** TaskCanceller triggered each time the MediaSource switches to and from "open". */
62
+ var msOpenStatusCanceller = new TaskCanceller();
63
+ msOpenStatusCanceller.linkToSignal(currentSignal);
45
64
  isMediaSourceOpened.onUpdate(onMediaSourceOpenedStatusChanged, { emitCurrentValue: true,
46
- clearSignal: this._canceller.signal });
65
+ clearSignal: currentSignal });
47
66
  function onMediaSourceOpenedStatusChanged() {
48
- msUpdateCanceller.cancel();
67
+ msOpenStatusCanceller.cancel();
49
68
  if (!isMediaSourceOpened.getValue()) {
50
69
  return;
51
70
  }
52
- msUpdateCanceller = new TaskCanceller();
53
- msUpdateCanceller.linkToSignal(canceller.signal);
54
- /** TaskCanceller triggered each time the content's duration may have changed */
55
- var durationChangeCanceller = new TaskCanceller();
56
- durationChangeCanceller.linkToSignal(msUpdateCanceller.signal);
57
- var reSetDuration = function () {
58
- durationChangeCanceller.cancel();
59
- durationChangeCanceller = new TaskCanceller();
60
- durationChangeCanceller.linkToSignal(msUpdateCanceller.signal);
61
- onDurationMayHaveChanged(durationChangeCanceller.signal);
62
- };
63
- currentKnownDuration.onUpdate(reSetDuration, { emitCurrentValue: false,
64
- clearSignal: msUpdateCanceller.signal });
65
- manifest.addEventListener("manifestUpdate", reSetDuration, msUpdateCanceller.signal);
66
- onDurationMayHaveChanged(durationChangeCanceller.signal);
67
- }
68
- function onDurationMayHaveChanged(cancelSignal) {
69
- var areSourceBuffersUpdating = createSourceBuffersUpdatingReference(mediaSource.sourceBuffers, cancelSignal);
71
+ msOpenStatusCanceller = new TaskCanceller();
72
+ msOpenStatusCanceller.linkToSignal(currentSignal);
73
+ var areSourceBuffersUpdating = createSourceBuffersUpdatingReference(mediaSource.sourceBuffers, msOpenStatusCanceller.signal);
70
74
  /** TaskCanceller triggered each time SourceBuffers' updating status changes */
71
75
  var sourceBuffersUpdatingCanceller = new TaskCanceller();
72
- sourceBuffersUpdatingCanceller.linkToSignal(cancelSignal);
76
+ sourceBuffersUpdatingCanceller.linkToSignal(msOpenStatusCanceller.signal);
73
77
  return areSourceBuffersUpdating.onUpdate(function (areUpdating) {
74
78
  sourceBuffersUpdatingCanceller.cancel();
75
79
  sourceBuffersUpdatingCanceller = new TaskCanceller();
76
- sourceBuffersUpdatingCanceller.linkToSignal(cancelSignal);
80
+ sourceBuffersUpdatingCanceller.linkToSignal(msOpenStatusCanceller.signal);
77
81
  if (areUpdating) {
78
82
  return;
79
83
  }
80
- recursivelyForceDurationUpdate(mediaSource, manifest, currentKnownDuration.getValue(), cancelSignal);
81
- }, { clearSignal: cancelSignal, emitCurrentValue: true });
84
+ recursivelyForceDurationUpdate(mediaSource, newDuration, addTimeMargin, sourceBuffersUpdatingCanceller.signal);
85
+ }, { clearSignal: msOpenStatusCanceller.signal, emitCurrentValue: true });
82
86
  }
83
- }
84
- /**
85
- * By default, the `MediaDurationUpdater` only set a safe estimate for the
86
- * MediaSource's duration.
87
- * A more precize duration can be set by communicating to it a more precize
88
- * media duration through `updateKnownDuration`.
89
- * If the duration becomes unknown, `undefined` can be given to it so the
90
- * `MediaDurationUpdater` goes back to a safe estimate.
91
- * @param {number | undefined} newDuration
92
- */
93
- MediaDurationUpdater.prototype.updateKnownDuration = function (newDuration) {
94
- this._currentKnownDuration.setValueIfChanged(newDuration);
95
87
  };
96
88
  /**
97
- * Stop the `MediaDurationUpdater` from updating and free its resources.
98
- * Once stopped, it is not possible to start it again, beside creating another
99
- * `MediaDurationUpdater`.
89
+ * Abort the last duration-setting operation and free its resources.
100
90
  */
101
- MediaDurationUpdater.prototype.stop = function () {
102
- this._canceller.cancel();
91
+ MediaSourceDurationUpdater.prototype.stopUpdating = function () {
92
+ if (this._currentMediaSourceDurationUpdateCanceller !== null) {
93
+ this._currentMediaSourceDurationUpdateCanceller.cancel();
94
+ this._currentMediaSourceDurationUpdateCanceller = null;
95
+ }
103
96
  };
104
- return MediaDurationUpdater;
97
+ return MediaSourceDurationUpdater;
105
98
  }());
106
- export default MediaDurationUpdater;
99
+ export default MediaSourceDurationUpdater;
107
100
  /**
108
101
  * Checks that duration can be updated on the MediaSource, and then
109
102
  * sets it.
@@ -113,27 +106,20 @@ export default MediaDurationUpdater;
113
106
  * - `null` if it hasn'nt been updated
114
107
  *
115
108
  * @param {MediaSource} mediaSource
116
- * @param {Object} manifest
109
+ * @param {number} duration
110
+ * @param {boolean} addTimeMargin
117
111
  * @returns {string}
118
112
  */
119
- function setMediaSourceDuration(mediaSource, manifest, knownDuration) {
120
- var _a;
121
- var newDuration = knownDuration;
122
- if (newDuration === undefined) {
123
- if (manifest.isDynamic) {
124
- newDuration = (_a = manifest.getLivePosition()) !== null && _a !== void 0 ? _a : manifest.getMaximumSafePosition();
125
- }
126
- else {
127
- newDuration = manifest.getMaximumSafePosition();
128
- }
129
- }
130
- if (manifest.isDynamic) {
113
+ function setMediaSourceDuration(mediaSource, duration, addTimeMargin) {
114
+ var newDuration = duration;
115
+ if (addTimeMargin) {
131
116
  // Some targets poorly support setting a very high number for durations.
132
- // Yet, in dynamic contents, we would prefer setting a value as high as possible
133
- // to still be able to seek anywhere we want to (even ahead of the Manifest if
134
- // we want to). As such, we put it at a safe default value of 2^32 excepted
135
- // when the maximum position is already relatively close to that value, where
136
- // we authorize exceptionally going over it.
117
+ // Yet, in contents whose end is not yet known (e.g. live contents), we
118
+ // would prefer setting a value as high as possible to still be able to
119
+ // seek anywhere we want to (even ahead of the Manifest if we want to).
120
+ // As such, we put it at a safe default value of 2^32 excepted when the
121
+ // maximum position is already relatively close to that value, where we
122
+ // authorize exceptionally going over it.
137
123
  newDuration = Math.max(Math.pow(2, 32), newDuration + YEAR_IN_SECONDS);
138
124
  }
139
125
  var maxBufferedEnd = 0;
@@ -242,23 +228,23 @@ function createMediaSourceOpenReference(mediaSource, cancelSignal) {
242
228
  }
243
229
  /**
244
230
  * Immediately tries to set the MediaSource's duration to the most appropriate
245
- * one according to the Manifest and duration given.
231
+ * one.
246
232
  *
247
233
  * If it fails, wait 2 seconds and retries.
248
234
  *
249
235
  * @param {MediaSource} mediaSource
250
- * @param {Object} manifest
251
- * @param {number|undefined} duration
236
+ * @param {number} duration
237
+ * @param {boolean} addTimeMargin
252
238
  * @param {Object} cancelSignal
253
239
  */
254
- function recursivelyForceDurationUpdate(mediaSource, manifest, duration, cancelSignal) {
255
- var res = setMediaSourceDuration(mediaSource, manifest, duration);
240
+ function recursivelyForceDurationUpdate(mediaSource, duration, addTimeMargin, cancelSignal) {
241
+ var res = setMediaSourceDuration(mediaSource, duration, addTimeMargin);
256
242
  if (res === "success" /* MediaSourceDurationUpdateStatus.Success */) {
257
243
  return;
258
244
  }
259
245
  var timeoutId = setTimeout(function () {
260
246
  unregisterClear();
261
- recursivelyForceDurationUpdate(mediaSource, manifest, duration, cancelSignal);
247
+ recursivelyForceDurationUpdate(mediaSource, duration, addTimeMargin, cancelSignal);
262
248
  }, 2000);
263
249
  var unregisterClear = cancelSignal.register(function () {
264
250
  clearTimeout(timeoutId);
@@ -411,7 +411,7 @@ export default function StreamOrchestrator(content, playbackObserver, representa
411
411
  var nextPeriod = manifest.getPeriodAfter(basePeriod);
412
412
  if (nextPeriod !== null) {
413
413
  // current Stream is full, create the next one if not
414
- createNextPeriodStream(nextPeriod);
414
+ checkOrCreateNextPeriodStream(nextPeriod);
415
415
  }
416
416
  }
417
417
  else if (nextStreamInfo !== null) {
@@ -436,12 +436,12 @@ export default function StreamOrchestrator(content, playbackObserver, representa
436
436
  * Create `PeriodStream` for the next Period, specified under `nextPeriod`.
437
437
  * @param {Object} nextPeriod
438
438
  */
439
- function createNextPeriodStream(nextPeriod) {
439
+ function checkOrCreateNextPeriodStream(nextPeriod) {
440
440
  if (nextStreamInfo !== null) {
441
441
  if (nextStreamInfo.period.id === nextPeriod.id) {
442
442
  return;
443
443
  }
444
- log.warn("Stream: Creating next `PeriodStream` while it was already created.", bufferType);
444
+ log.warn("Stream: Creating next `PeriodStream` while one was already created.", bufferType, nextPeriod.id, nextStreamInfo.period.id);
445
445
  consecutivePeriodStreamCb.periodStreamCleared({ type: bufferType,
446
446
  period: nextStreamInfo.period });
447
447
  nextStreamInfo.canceller.cancel();
@@ -420,6 +420,31 @@ declare const DEFAULT_CONFIG: {
420
420
  * @type {Number}
421
421
  */
422
422
  SAMPLING_INTERVAL_NO_MEDIASOURCE: number;
423
+ /**
424
+ * Amount of buffer to have ahead of the current position before we may
425
+ * consider buffer-based adaptive estimates, in seconds.
426
+ *
427
+ * For example setting it to `10` means that we need to have ten seconds of
428
+ * buffer ahead of the current position before relying on buffer-based
429
+ * adaptive estimates.
430
+ *
431
+ * To avoid getting in-and-out of the buffer-based logic all the time, it
432
+ * should be set higher than `ABR_EXIT_BUFFER_BASED_ALGO`.
433
+ */
434
+ ABR_ENTER_BUFFER_BASED_ALGO: number;
435
+ /**
436
+ * Below this amount of buffer ahead of the current position, in seconds, we
437
+ * will stop using buffer-based estimate in our adaptive logic to select a
438
+ * quality.
439
+ *
440
+ * For example setting it to `5` means that if we have less than 5 seconds of
441
+ * buffer ahead of the current position, we should stop relying on
442
+ * buffer-based estimates to choose a quality.
443
+ *
444
+ * To avoid getting in-and-out of the buffer-based logic all the time, it
445
+ * should be set lower than `ABR_ENTER_BUFFER_BASED_ALGO`.
446
+ */
447
+ ABR_EXIT_BUFFER_BASED_ALGO: number;
423
448
  /**
424
449
  * Minimum number of bytes sampled before we trust the estimate.
425
450
  * If we have not sampled much data, our estimate may not be accurate
@@ -444,6 +444,31 @@ var DEFAULT_CONFIG = {
444
444
  * @type {Number}
445
445
  */
446
446
  SAMPLING_INTERVAL_NO_MEDIASOURCE: 500,
447
+ /**
448
+ * Amount of buffer to have ahead of the current position before we may
449
+ * consider buffer-based adaptive estimates, in seconds.
450
+ *
451
+ * For example setting it to `10` means that we need to have ten seconds of
452
+ * buffer ahead of the current position before relying on buffer-based
453
+ * adaptive estimates.
454
+ *
455
+ * To avoid getting in-and-out of the buffer-based logic all the time, it
456
+ * should be set higher than `ABR_EXIT_BUFFER_BASED_ALGO`.
457
+ */
458
+ ABR_ENTER_BUFFER_BASED_ALGO: 10,
459
+ /**
460
+ * Below this amount of buffer ahead of the current position, in seconds, we
461
+ * will stop using buffer-based estimate in our adaptive logic to select a
462
+ * quality.
463
+ *
464
+ * For example setting it to `5` means that if we have less than 5 seconds of
465
+ * buffer ahead of the current position, we should stop relying on
466
+ * buffer-based estimates to choose a quality.
467
+ *
468
+ * To avoid getting in-and-out of the buffer-based logic all the time, it
469
+ * should be set lower than `ABR_ENTER_BUFFER_BASED_ALGO`.
470
+ */
471
+ ABR_EXIT_BUFFER_BASED_ALGO: 5,
447
472
  /**
448
473
  * Minimum number of bytes sampled before we trust the estimate.
449
474
  * If we have not sampled much data, our estimate may not be accurate
@@ -479,8 +504,8 @@ var DEFAULT_CONFIG = {
479
504
  * @type {Object}
480
505
  */
481
506
  ABR_REGULAR_FACTOR: {
482
- DEFAULT: 0.8,
483
- LOW_LATENCY: 0.8,
507
+ DEFAULT: 0.72,
508
+ LOW_LATENCY: 0.72,
484
509
  },
485
510
  /**
486
511
  * If a media buffer has less than ABR_STARVATION_GAP in seconds ahead of the
@@ -19,6 +19,6 @@
19
19
  * not always understood by newcomers to the code, and which can be overused when
20
20
  * only one of the possibility can arise.
21
21
  * @param {*} x
22
- * @returns {*}
22
+ * @returns {boolean}
23
23
  */
24
24
  export default function isNullOrUndefined(x: unknown): x is null | undefined | void;
@@ -19,7 +19,7 @@
19
19
  * not always understood by newcomers to the code, and which can be overused when
20
20
  * only one of the possibility can arise.
21
21
  * @param {*} x
22
- * @returns {*}
22
+ * @returns {boolean}
23
23
  */
24
24
  export default function isNullOrUndefined(x) {
25
25
  return x === null || x === undefined;