rx-player 4.0.0-dev.2023110700 → 4.0.0-dev.2023111400

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 (102) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/VERSION +1 -1
  3. package/dist/_esm5.processed/core/api/option_utils.d.ts +2 -0
  4. package/dist/_esm5.processed/core/api/option_utils.js +6 -0
  5. package/dist/_esm5.processed/core/api/public_api.d.ts +2 -1
  6. package/dist/_esm5.processed/core/api/public_api.js +14 -4
  7. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/text_track_cues_store.js +54 -6
  8. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/utils.d.ts +2 -1
  9. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/utils.js +19 -2
  10. package/dist/_esm5.processed/manifest/representation.js +18 -5
  11. package/dist/_esm5.processed/parsers/manifest/dash/common/convert_supplemental_codecs.d.ts +17 -0
  12. package/dist/_esm5.processed/parsers/manifest/dash/common/convert_supplemental_codecs.js +26 -0
  13. package/dist/_esm5.processed/parsers/manifest/dash/common/flatten_overlapping_periods.js +5 -0
  14. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representations.js +29 -17
  15. package/dist/_esm5.processed/parsers/manifest/dash/js-parser/node_parsers/AdaptationSet.js +3 -0
  16. package/dist/_esm5.processed/parsers/manifest/dash/js-parser/node_parsers/Representation.js +3 -0
  17. package/dist/_esm5.processed/parsers/manifest/dash/node_parser_types.d.ts +2 -0
  18. package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/AdaptationSet.js +4 -0
  19. package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/Representation.js +4 -0
  20. package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/types.d.ts +2 -1
  21. package/dist/_esm5.processed/parsers/manifest/types.d.ts +1 -0
  22. package/dist/commonjs/compat/patch_webkit_source_buffer.js +2 -2
  23. package/dist/commonjs/core/api/option_utils.d.ts +2 -0
  24. package/dist/commonjs/core/api/option_utils.js +6 -0
  25. package/dist/commonjs/core/api/public_api.d.ts +2 -1
  26. package/dist/commonjs/core/api/public_api.js +14 -4
  27. package/dist/commonjs/core/segment_buffers/implementations/text/html/text_track_cues_store.js +54 -6
  28. package/dist/commonjs/core/segment_buffers/implementations/text/html/utils.d.ts +2 -1
  29. package/dist/commonjs/core/segment_buffers/implementations/text/html/utils.js +19 -2
  30. package/dist/commonjs/core/stream/adaptation/adaptation_stream.js +2 -2
  31. package/dist/commonjs/core/stream/orchestrator/stream_orchestrator.js +3 -3
  32. package/dist/commonjs/core/stream/period/period_stream.js +2 -2
  33. package/dist/commonjs/manifest/representation.js +18 -5
  34. package/dist/commonjs/parsers/manifest/dash/common/convert_supplemental_codecs.d.ts +17 -0
  35. package/dist/commonjs/parsers/manifest/dash/common/convert_supplemental_codecs.js +30 -0
  36. package/dist/commonjs/parsers/manifest/dash/common/flatten_overlapping_periods.js +5 -0
  37. package/dist/commonjs/parsers/manifest/dash/common/parse_representations.js +29 -17
  38. package/dist/commonjs/parsers/manifest/dash/js-parser/node_parsers/AdaptationSet.js +3 -0
  39. package/dist/commonjs/parsers/manifest/dash/js-parser/node_parsers/Representation.js +3 -0
  40. package/dist/commonjs/parsers/manifest/dash/node_parser_types.d.ts +2 -0
  41. package/dist/commonjs/parsers/manifest/dash/wasm-parser/ts/generators/AdaptationSet.js +4 -0
  42. package/dist/commonjs/parsers/manifest/dash/wasm-parser/ts/generators/Representation.js +4 -0
  43. package/dist/commonjs/parsers/manifest/dash/wasm-parser/ts/types.d.ts +2 -1
  44. package/dist/commonjs/parsers/manifest/types.d.ts +1 -0
  45. package/dist/commonjs/utils/queue_microtask.d.ts +2 -0
  46. package/dist/commonjs/utils/queue_microtask.js +7 -0
  47. package/dist/es2017/compat/patch_webkit_source_buffer.js +2 -2
  48. package/dist/es2017/core/api/option_utils.d.ts +2 -0
  49. package/dist/es2017/core/api/option_utils.js +6 -0
  50. package/dist/es2017/core/api/public_api.d.ts +2 -1
  51. package/dist/es2017/core/api/public_api.js +13 -3
  52. package/dist/es2017/core/segment_buffers/implementations/text/html/text_track_cues_store.js +54 -6
  53. package/dist/es2017/core/segment_buffers/implementations/text/html/utils.d.ts +2 -1
  54. package/dist/es2017/core/segment_buffers/implementations/text/html/utils.js +18 -2
  55. package/dist/es2017/core/stream/adaptation/adaptation_stream.js +2 -2
  56. package/dist/es2017/core/stream/orchestrator/stream_orchestrator.js +3 -3
  57. package/dist/es2017/core/stream/period/period_stream.js +2 -2
  58. package/dist/es2017/manifest/representation.js +18 -5
  59. package/dist/es2017/parsers/manifest/dash/common/convert_supplemental_codecs.d.ts +17 -0
  60. package/dist/es2017/parsers/manifest/dash/common/convert_supplemental_codecs.js +26 -0
  61. package/dist/es2017/parsers/manifest/dash/common/flatten_overlapping_periods.js +5 -0
  62. package/dist/es2017/parsers/manifest/dash/common/parse_representations.js +29 -17
  63. package/dist/es2017/parsers/manifest/dash/js-parser/node_parsers/AdaptationSet.js +3 -0
  64. package/dist/es2017/parsers/manifest/dash/js-parser/node_parsers/Representation.js +3 -0
  65. package/dist/es2017/parsers/manifest/dash/node_parser_types.d.ts +2 -0
  66. package/dist/es2017/parsers/manifest/dash/wasm-parser/ts/generators/AdaptationSet.js +4 -0
  67. package/dist/es2017/parsers/manifest/dash/wasm-parser/ts/generators/Representation.js +4 -0
  68. package/dist/es2017/parsers/manifest/dash/wasm-parser/ts/types.d.ts +2 -1
  69. package/dist/es2017/parsers/manifest/types.d.ts +1 -0
  70. package/dist/es2017/utils/queue_microtask.d.ts +2 -0
  71. package/dist/es2017/utils/queue_microtask.js +5 -0
  72. package/dist/mpd-parser.wasm +0 -0
  73. package/dist/rx-player.js +179 -118
  74. package/dist/rx-player.min.js +1 -1
  75. package/package.json +1 -4
  76. package/sonar-project.properties +1 -1
  77. package/src/compat/patch_webkit_source_buffer.ts +2 -2
  78. package/src/core/api/option_utils.ts +8 -0
  79. package/src/core/api/public_api.ts +15 -3
  80. package/src/core/segment_buffers/implementations/text/html/__tests__/utils.test.ts +15 -0
  81. package/src/core/segment_buffers/implementations/text/html/text_track_cues_store.ts +57 -6
  82. package/src/core/segment_buffers/implementations/text/html/utils.ts +19 -2
  83. package/src/core/stream/adaptation/adaptation_stream.ts +2 -2
  84. package/src/core/stream/orchestrator/stream_orchestrator.ts +3 -3
  85. package/src/core/stream/period/period_stream.ts +2 -2
  86. package/src/manifest/representation.ts +19 -6
  87. package/src/parsers/manifest/dash/common/__tests__/convert_supplemental_codecs.test.ts +37 -0
  88. package/src/parsers/manifest/dash/common/__tests__/flatten_overlapping_period.test.ts +20 -0
  89. package/src/parsers/manifest/dash/common/convert_supplemental_codecs.ts +32 -0
  90. package/src/parsers/manifest/dash/common/flatten_overlapping_periods.ts +5 -0
  91. package/src/parsers/manifest/dash/common/parse_representations.ts +30 -17
  92. package/src/parsers/manifest/dash/js-parser/node_parsers/AdaptationSet.ts +4 -0
  93. package/src/parsers/manifest/dash/js-parser/node_parsers/Representation.ts +4 -0
  94. package/src/parsers/manifest/dash/node_parser_types.ts +2 -0
  95. package/src/parsers/manifest/dash/wasm-parser/rs/events.rs +2 -0
  96. package/src/parsers/manifest/dash/wasm-parser/rs/processor/attributes.rs +2 -0
  97. package/src/parsers/manifest/dash/wasm-parser/ts/generators/AdaptationSet.ts +4 -0
  98. package/src/parsers/manifest/dash/wasm-parser/ts/generators/Representation.ts +4 -0
  99. package/src/parsers/manifest/dash/wasm-parser/ts/types.ts +2 -0
  100. package/src/parsers/manifest/types.ts +2 -0
  101. package/src/utils/queue_microtask.ts +7 -0
  102. package/src/typings/next-tick.d.ts +0 -23
@@ -16,7 +16,7 @@
16
16
  import { IErrorCode, IErrorType } from "../../errors";
17
17
  import { IFeature } from "../../features";
18
18
  import Manifest, { Adaptation, Representation } from "../../manifest";
19
- import { IAudioRepresentation, IAudioTrack, IAudioTrackSetting, IAvailableAudioTrack, IAvailableTextTrack, IAvailableVideoTrack, IBrokenRepresentationsLockContext, IConstructorOptions, IKeySystemConfigurationOutput, ILoadVideoOptions, ILockedAudioRepresentationsSettings, ILockedVideoRepresentationsSettings, ITrackUpdateEventPayload, IRepresentationListUpdateContext, IPeriod, IPeriodChangeEvent, IPlayerError, IPlayerState, IPositionUpdate, IStreamEvent, ITextTrack, IVideoRepresentation, ITextTrackSetting, IVideoTrack, IVideoTrackSetting } from "../../public_types";
19
+ import { IAudioRepresentation, IAudioTrack, IAudioTrackSetting, IAvailableAudioTrack, IAvailableTextTrack, IAvailableVideoTrack, IBrokenRepresentationsLockContext, IConstructorOptions, IKeySystemConfigurationOutput, IKeySystemOption, ILoadVideoOptions, ILockedAudioRepresentationsSettings, ILockedVideoRepresentationsSettings, ITrackUpdateEventPayload, IRepresentationListUpdateContext, IPeriod, IPeriodChangeEvent, IPlayerError, IPlayerState, IPositionUpdate, IStreamEvent, ITextTrack, IVideoRepresentation, ITextTrackSetting, IVideoTrack, IVideoTrackSetting } from "../../public_types";
20
20
  import EventEmitter, { IListener } from "../../utils/event_emitter";
21
21
  import Logger from "../../utils/logger";
22
22
  import { IBufferedChunk, IBufferType } from "../segment_buffers";
@@ -159,6 +159,7 @@ declare class Player extends EventEmitter<IPublicAPIEvent> {
159
159
  position?: number;
160
160
  relative?: number;
161
161
  };
162
+ keySystems?: IKeySystemOption[];
162
163
  autoPlay?: boolean;
163
164
  }): void;
164
165
  createDebugElement(element: HTMLElement): {
@@ -116,7 +116,7 @@ var Player = /** @class */ (function (_super) {
116
116
  // Workaround to support Firefox autoplay on FF 42.
117
117
  // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1194624
118
118
  videoElement.preload = "auto";
119
- _this.version = /* PLAYER_VERSION */ "4.0.0-dev.2023110700";
119
+ _this.version = /* PLAYER_VERSION */ "4.0.0-dev.2023111400";
120
120
  _this.log = log_1.default;
121
121
  _this.state = "STOPPED";
122
122
  _this.videoElement = videoElement;
@@ -256,8 +256,8 @@ var Player = /** @class */ (function (_super) {
256
256
  * @param {Object} reloadOpts
257
257
  */
258
258
  Player.prototype.reload = function (reloadOpts) {
259
- var _a, _b;
260
- var _c = this._priv_reloadingMetadata, options = _c.options, manifest = _c.manifest, reloadPosition = _c.reloadPosition, reloadInPause = _c.reloadInPause;
259
+ var _a, _b, _c;
260
+ var _d = this._priv_reloadingMetadata, options = _d.options, manifest = _d.manifest, reloadPosition = _d.reloadPosition, reloadInPause = _d.reloadInPause;
261
261
  if (options === undefined) {
262
262
  throw new Error("API: Can't reload without having previously loaded a content.");
263
263
  }
@@ -284,6 +284,13 @@ var Player = /** @class */ (function (_super) {
284
284
  else if (reloadInPause !== undefined) {
285
285
  autoPlay = !reloadInPause;
286
286
  }
287
+ var keySystems;
288
+ if ((reloadOpts === null || reloadOpts === void 0 ? void 0 : reloadOpts.keySystems) !== undefined) {
289
+ keySystems = reloadOpts.keySystems;
290
+ }
291
+ else if (((_c = this._priv_reloadingMetadata.options) === null || _c === void 0 ? void 0 : _c.keySystems) !== undefined) {
292
+ keySystems = this._priv_reloadingMetadata.options.keySystems;
293
+ }
287
294
  var newOptions = __assign(__assign({}, options), { initialManifest: manifest });
288
295
  if (startAt !== undefined) {
289
296
  newOptions.startAt = startAt;
@@ -291,6 +298,9 @@ var Player = /** @class */ (function (_super) {
291
298
  if (autoPlay !== undefined) {
292
299
  newOptions.autoPlay = autoPlay;
293
300
  }
301
+ if (keySystems !== undefined) {
302
+ newOptions.keySystems = keySystems;
303
+ }
294
304
  this._priv_initializeContentPlayback(newOptions);
295
305
  };
296
306
  Player.prototype.createDebugElement = function (element) {
@@ -2222,5 +2232,5 @@ var Player = /** @class */ (function (_super) {
2222
2232
  };
2223
2233
  return Player;
2224
2234
  }(event_emitter_1.default));
2225
- Player.version = /* PLAYER_VERSION */ "4.0.0-dev.2023110700";
2235
+ Player.version = /* PLAYER_VERSION */ "4.0.0-dev.2023111400";
2226
2236
  exports.default = Player;
@@ -33,6 +33,22 @@ var __read = (this && this.__read) || function (o, n) {
33
33
  Object.defineProperty(exports, "__esModule", { value: true });
34
34
  var assert_1 = require("../../../../../utils/assert");
35
35
  var utils_1 = require("./utils");
36
+ /**
37
+ * first or last IHTMLCue in a group can have a slighlty different start
38
+ * or end time than the start or end time of the ICuesGroup due to parsing
39
+ * approximation.
40
+ * DELTA_CUES_GROUP defines the tolerance level when comparing the start/end
41
+ * of a IHTMLCue to the start/end of a ICuesGroup.
42
+ * Having this value too high may lead to have unwanted subtitle displayed
43
+ * Having this value too low may lead to have subtitles not displayed
44
+ */
45
+ var DELTA_CUES_GROUP = 1e-3;
46
+ /**
47
+ * segment_duration / RELATIVE_DELTA_RATIO = relative_delta
48
+ *
49
+ * relative_delta is the tolerance to determine if two segements are the same
50
+ */
51
+ var RELATIVE_DELTA_RATIO = 5;
36
52
  /**
37
53
  * Manage the buffer of the HTMLTextSegmentBuffer.
38
54
  * Allows to add, remove and recuperate cues at given times.
@@ -75,6 +91,18 @@ var TextTrackCuesStore = /** @class */ (function () {
75
91
  ret.push(cues[j].element);
76
92
  }
77
93
  }
94
+ // first or last IHTMLCue in a group can have a slighlty different start
95
+ // or end time than the start or end time of the ICuesGroup due to parsing
96
+ // approximation.
97
+ // Add a tolerance of 1ms to fix this issue
98
+ if (ret.length === 0 && cues.length > 0) {
99
+ for (var j = 0; j < cues.length; j++) {
100
+ if ((0, utils_1.areNearlyEqual)(time, cues[j].start, DELTA_CUES_GROUP)
101
+ || (0, utils_1.areNearlyEqual)(time, cues[j].end, DELTA_CUES_GROUP)) {
102
+ ret.push(cues[j].element);
103
+ }
104
+ }
105
+ }
78
106
  return ret;
79
107
  }
80
108
  }
@@ -161,6 +189,11 @@ var TextTrackCuesStore = /** @class */ (function () {
161
189
  TextTrackCuesStore.prototype.insert = function (cues, start, end) {
162
190
  var cuesBuffer = this._cuesBuffer;
163
191
  var cuesInfosToInsert = { start: start, end: end, cues: cues };
192
+ // it's preferable to have a delta depending on the duration of the segment
193
+ // if the delta is one fifth of the length of the segment:
194
+ // a segment of [0, 2] is the "same" segment as [0, 2.1]
195
+ // but [0, 0.04] is not the "same" segement as [0,04, 0.08]
196
+ var relativeDelta = Math.abs(start - end) / RELATIVE_DELTA_RATIO;
164
197
  /**
165
198
  * Called when we found the index of the next cue relative to the cue we
166
199
  * want to insert (that is a cue starting after its start or at the same
@@ -172,7 +205,7 @@ var TextTrackCuesStore = /** @class */ (function () {
172
205
  function onIndexOfNextCueFound(indexOfNextCue) {
173
206
  var nextCue = cuesBuffer[indexOfNextCue];
174
207
  if (nextCue === undefined || // no cue
175
- (0, utils_1.areNearlyEqual)(cuesInfosToInsert.end, nextCue.end)) // samey end
208
+ (0, utils_1.areNearlyEqual)(cuesInfosToInsert.end, nextCue.end, relativeDelta)) // samey end
176
209
  {
177
210
  // ours: |AAAAA|
178
211
  // the current one: |BBBBB|
@@ -208,8 +241,8 @@ var TextTrackCuesStore = /** @class */ (function () {
208
241
  for (var cueIdx = 0; cueIdx < cuesBuffer.length; cueIdx++) {
209
242
  var cuesInfos = cuesBuffer[cueIdx];
210
243
  if (start < cuesInfos.end) {
211
- if ((0, utils_1.areNearlyEqual)(start, cuesInfos.start)) {
212
- if ((0, utils_1.areNearlyEqual)(end, cuesInfos.end)) {
244
+ if ((0, utils_1.areNearlyEqual)(start, cuesInfos.start, relativeDelta)) {
245
+ if ((0, utils_1.areNearlyEqual)(end, cuesInfos.end, relativeDelta)) {
213
246
  // exact same segment
214
247
  // ours: |AAAAA|
215
248
  // the current one: |BBBBB|
@@ -257,7 +290,7 @@ var TextTrackCuesStore = /** @class */ (function () {
257
290
  cuesBuffer.splice(cueIdx, 0, cuesInfosToInsert);
258
291
  return;
259
292
  }
260
- else if ((0, utils_1.areNearlyEqual)(end, cuesInfos.start)) {
293
+ else if ((0, utils_1.areNearlyEqual)(end, cuesInfos.start, relativeDelta)) {
261
294
  // our cue goes just before the current one:
262
295
  // ours: |AAAAAAA|
263
296
  // the current one: |BBBB|
@@ -269,7 +302,7 @@ var TextTrackCuesStore = /** @class */ (function () {
269
302
  cuesBuffer.splice(cueIdx, 0, cuesInfosToInsert);
270
303
  return;
271
304
  }
272
- else if ((0, utils_1.areNearlyEqual)(end, cuesInfos.end)) {
305
+ else if ((0, utils_1.areNearlyEqual)(end, cuesInfos.end, relativeDelta)) {
273
306
  // ours: |AAAAAAA|
274
307
  // the current one: |BBBB|
275
308
  // Result: |AAAAAAA|
@@ -297,7 +330,7 @@ var TextTrackCuesStore = /** @class */ (function () {
297
330
  return;
298
331
  }
299
332
  // else -> start > cuesInfos.start
300
- if ((0, utils_1.areNearlyEqual)(cuesInfos.end, end)) {
333
+ if ((0, utils_1.areNearlyEqual)(cuesInfos.end, end, relativeDelta)) {
301
334
  // ours: |AAAAAA|
302
335
  // the current one: |BBBBBBBB|
303
336
  // Result: |BBAAAAAA|
@@ -333,6 +366,21 @@ var TextTrackCuesStore = /** @class */ (function () {
333
366
  }
334
367
  }
335
368
  }
369
+ if (cuesBuffer.length) {
370
+ var lastCue = cuesBuffer[cuesBuffer.length - 1];
371
+ if ((0, utils_1.areNearlyEqual)(lastCue.end, start, relativeDelta)) {
372
+ // Match the end of the previous cue to the start of the following one
373
+ // if they are close enough. If there is a small gap between two segments
374
+ // it can lead to having no subtitles for a short time, this is noticeable when
375
+ // two successive segments displays the same text, making it diseappear
376
+ // and reappear quickly, which gives the impression of blinking
377
+ //
378
+ // ours: |AAAAA|
379
+ // the current one: |BBBBB|...
380
+ // Result: |BBBBBBBAAAAA|
381
+ lastCue.end = start;
382
+ }
383
+ }
336
384
  // no cues group has the end after our current start.
337
385
  // These cues should be the last one
338
386
  cuesBuffer.push(cuesInfosToInsert);
@@ -18,9 +18,10 @@ import { ICuesGroup, IHTMLCue } from "./types";
18
18
  * @see MAX_DELTA_BUFFER_TIME
19
19
  * @param {Number} a
20
20
  * @param {Number} b
21
+ * @param {Number} delta
21
22
  * @returns {Boolean}
22
23
  */
23
- export declare function areNearlyEqual(a: number, b: number): boolean;
24
+ export declare function areNearlyEqual(a: number, b: number, delta?: number): boolean;
24
25
  /**
25
26
  * Get all cues which have data before the given time.
26
27
  * @param {Object} cues
@@ -47,6 +47,21 @@ exports.removeCuesInfosBetween = exports.getCuesAfter = exports.getCuesBefore =
47
47
  * Setting a value too high might lead to two segments targeting different times
48
48
  * to be wrongly believed to target the same time. In worst case scenarios, this
49
49
  * could lead to wanted text tracks being removed.
50
+ *
51
+ * When comparing 2 segments s1 and s2, you may want to take into account the duration
52
+ * of the segments:
53
+ * - if s1 is [0, 2] and s2 is [0, 2.1] s1 and s2 can be considered as nearly equal as
54
+ * there is a relative difference of: (2.1-2) / 2 = 5%;
55
+ * Formula: (end_s1 - end_s2) / duration_s2 = relative_difference
56
+ * - if s1 is [0, 0.04] and s2 is [0.04, 0.08] s1 and s2 may not considered as nearly
57
+ * equal as there is a relative difference of: (0.04-0.08) / 0.04 = 100%
58
+ *
59
+ * To compare relatively to the duration of a segment you can provide and additional
60
+ * parameter "delta" that remplace MAX_DELTA_BUFFER_TIME.
61
+ * If parameter "delta" is higher than MAX_DELTA_BUFFER_TIME, MAX_DELTA_BUFFER_TIME
62
+ * is used instead of delta. This ensure that segments are nearly equal when comparing
63
+ * relatively AND absolutely.
64
+ *
50
65
  * @type Number
51
66
  */
52
67
  var MAX_DELTA_BUFFER_TIME = 0.2;
@@ -54,10 +69,12 @@ var MAX_DELTA_BUFFER_TIME = 0.2;
54
69
  * @see MAX_DELTA_BUFFER_TIME
55
70
  * @param {Number} a
56
71
  * @param {Number} b
72
+ * @param {Number} delta
57
73
  * @returns {Boolean}
58
74
  */
59
- function areNearlyEqual(a, b) {
60
- return Math.abs(a - b) <= MAX_DELTA_BUFFER_TIME;
75
+ function areNearlyEqual(a, b, delta) {
76
+ if (delta === void 0) { delta = MAX_DELTA_BUFFER_TIME; }
77
+ return Math.abs(a - b) <= Math.min(delta, MAX_DELTA_BUFFER_TIME);
61
78
  }
62
79
  exports.areNearlyEqual = areNearlyEqual;
63
80
  /**
@@ -47,7 +47,6 @@ var __values = (this && this.__values) || function(o) {
47
47
  throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
48
48
  };
49
49
  Object.defineProperty(exports, "__esModule", { value: true });
50
- var next_tick_1 = require("next-tick");
51
50
  var config_1 = require("../../../config");
52
51
  var errors_1 = require("../../../errors");
53
52
  var log_1 = require("../../../log");
@@ -55,6 +54,7 @@ var assert_unreachable_1 = require("../../../utils/assert_unreachable");
55
54
  var cancellable_sleep_1 = require("../../../utils/cancellable_sleep");
56
55
  var noop_1 = require("../../../utils/noop");
57
56
  var object_assign_1 = require("../../../utils/object_assign");
57
+ var queue_microtask_1 = require("../../../utils/queue_microtask");
58
58
  var reference_1 = require("../../../utils/reference");
59
59
  var task_canceller_1 = require("../../../utils/task_canceller");
60
60
  var representation_1 = require("../representation");
@@ -194,7 +194,7 @@ function AdaptationStream(_a, callbacks, parentCancelSignal) {
194
194
  // conditions where the inner logic would be called synchronously before
195
195
  // the next observation (which may reflect very different playback conditions)
196
196
  // is actually received.
197
- return [2 /*return*/, (0, next_tick_1.default)(function () {
197
+ return [2 /*return*/, (0, queue_microtask_1.default)(function () {
198
198
  playbackObserver.listen(function () {
199
199
  if (fnCancelSignal.isCancelled()) {
200
200
  return;
@@ -98,10 +98,10 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
98
98
  return to.concat(ar || Array.prototype.slice.call(from));
99
99
  };
100
100
  Object.defineProperty(exports, "__esModule", { value: true });
101
- var next_tick_1 = require("next-tick");
102
101
  var config_1 = require("../../../config");
103
102
  var errors_1 = require("../../../errors");
104
103
  var log_1 = require("../../../log");
104
+ var queue_microtask_1 = require("../../../utils/queue_microtask");
105
105
  var reference_1 = require("../../../utils/reference");
106
106
  var sorted_list_1 = require("../../../utils/sorted_list");
107
107
  var task_canceller_1 = require("../../../utils/task_canceller");
@@ -381,7 +381,7 @@ function StreamOrchestrator(content, playbackObserver, representationEstimator,
381
381
  // Schedule micro task before checking the last playback observation
382
382
  // to reduce the risk of race conditions where the next observation
383
383
  // was going to be emitted synchronously.
384
- (0, next_tick_1.default)(function () {
384
+ (0, queue_microtask_1.default)(function () {
385
385
  var _a;
386
386
  if (orchestratorCancelSignal.isCancelled()) {
387
387
  return;
@@ -538,7 +538,7 @@ function StreamOrchestrator(content, playbackObserver, representationEstimator,
538
538
  // conditions where the inner logic would be called synchronously before
539
539
  // the next observation (which may reflect very different playback
540
540
  // conditions) is actually received.
541
- return (0, next_tick_1.default)(function () {
541
+ return (0, queue_microtask_1.default)(function () {
542
542
  if (innerCancelSignal.isCancelled()) {
543
543
  return;
544
544
  }
@@ -73,11 +73,11 @@ var __values = (this && this.__values) || function(o) {
73
73
  throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
74
74
  };
75
75
  Object.defineProperty(exports, "__esModule", { value: true });
76
- var next_tick_1 = require("next-tick");
77
76
  var config_1 = require("../../../config");
78
77
  var errors_1 = require("../../../errors");
79
78
  var log_1 = require("../../../log");
80
79
  var object_assign_1 = require("../../../utils/object_assign");
80
+ var queue_microtask_1 = require("../../../utils/queue_microtask");
81
81
  var ranges_1 = require("../../../utils/ranges");
82
82
  var reference_1 = require("../../../utils/reference");
83
83
  var task_canceller_1 = require("../../../utils/task_canceller");
@@ -355,7 +355,7 @@ function PeriodStream(_a, callbacks, parentCancelSignal) {
355
355
  // is actually received.
356
356
  // It can happen when `askForMediaSourceReload` is called as a side-effect of
357
357
  // the same event that triggers the playback observation to be emitted.
358
- (0, next_tick_1.default)(function () {
358
+ (0, queue_microtask_1.default)(function () {
359
359
  playbackObserver.listen(function () {
360
360
  if (cancelSignal.isCancelled()) {
361
361
  return;
@@ -40,6 +40,7 @@ var Representation = /** @class */ (function () {
40
40
  * @param {Object} args
41
41
  */
42
42
  function Representation(args, opts) {
43
+ var _a;
43
44
  this.id = args.id;
44
45
  this.uniqueId = generateRepresentationUniqueId();
45
46
  this.bitrate = args.bitrate;
@@ -68,12 +69,24 @@ var Representation = /** @class */ (function () {
68
69
  this.cdnMetadata = args.cdnMetadata;
69
70
  this.index = args.index;
70
71
  if (opts.type === "audio" || opts.type === "video") {
71
- var mimeTypeStr = this.getMimeTypeString();
72
- var isSupported = (0, compat_1.isCodecSupported)(mimeTypeStr);
73
- if (!isSupported) {
74
- log_1.default.info("Unsupported Representation", mimeTypeStr, this.id, this.bitrate);
72
+ this.isSupported = false;
73
+ // Supplemental codecs are defined as backwards-compatible codecs enhancing
74
+ // the experience of a base layer codec
75
+ if (args.supplementalCodecs !== undefined) {
76
+ var supplementalCodecMimeTypeStr = "".concat((_a = this.mimeType) !== null && _a !== void 0 ? _a : "", ";codecs=\"").concat(args.supplementalCodecs, "\"");
77
+ if ((0, compat_1.isCodecSupported)(supplementalCodecMimeTypeStr)) {
78
+ this.codec = args.supplementalCodecs;
79
+ this.isSupported = true;
80
+ }
81
+ }
82
+ if (!this.isSupported) {
83
+ var mimeTypeStr = this.getMimeTypeString();
84
+ var isSupported = (0, compat_1.isCodecSupported)(mimeTypeStr);
85
+ if (!isSupported) {
86
+ log_1.default.info("Unsupported Representation", mimeTypeStr, this.id, this.bitrate);
87
+ }
88
+ this.isSupported = isSupported;
75
89
  }
76
- this.isSupported = isSupported;
77
90
  }
78
91
  else {
79
92
  this.isSupported = true; // TODO for other types
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Converts SCTE 214 supplemental codec string into RFC4281 codec string
3
+ *
4
+ * The returned value is a codec string respecting RFC6381
5
+ *
6
+ * SCTE 214 defines supplemental codecs as a whitespace-separated multiple list of
7
+ * codec strings
8
+ *
9
+ * RFC6381 defines codecs as a comma-separated list of codec strings.
10
+ *
11
+ * This two syntax differs and this parser is used to convert SCTE214
12
+ * to be compliant with what MSE APIs expect
13
+ *
14
+ * @param {string} val - The codec string to parse
15
+ * @returns { Array.<string | undefined | null>}
16
+ */
17
+ export declare function convertSupplementalCodecsToRFC6381(val: string): string;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.convertSupplementalCodecsToRFC6381 = void 0;
4
+ var is_non_empty_string_1 = require("../../../../utils/is_non_empty_string");
5
+ var supplementalCodecSeparator = /[, ]+/g;
6
+ /**
7
+ * Converts SCTE 214 supplemental codec string into RFC4281 codec string
8
+ *
9
+ * The returned value is a codec string respecting RFC6381
10
+ *
11
+ * SCTE 214 defines supplemental codecs as a whitespace-separated multiple list of
12
+ * codec strings
13
+ *
14
+ * RFC6381 defines codecs as a comma-separated list of codec strings.
15
+ *
16
+ * This two syntax differs and this parser is used to convert SCTE214
17
+ * to be compliant with what MSE APIs expect
18
+ *
19
+ * @param {string} val - The codec string to parse
20
+ * @returns { Array.<string | undefined | null>}
21
+ */
22
+ function convertSupplementalCodecsToRFC6381(val) {
23
+ if ((0, is_non_empty_string_1.default)(val)) {
24
+ return val
25
+ .trim()
26
+ .replace(supplementalCodecSeparator, ", ");
27
+ }
28
+ return "";
29
+ }
30
+ exports.convertSupplementalCodecsToRFC6381 = convertSupplementalCodecsToRFC6381;
@@ -67,6 +67,11 @@ function flattenOverlappingPeriods(parsedPeriods) {
67
67
  // `lastFlattenedPeriod` has now a negative or `0` duration.
68
68
  // Remove it, consider the next Period in its place, and re-start the loop.
69
69
  flattenedPeriods.pop();
70
+ if (flattenedPeriods.length === 0) {
71
+ // There's no remaining Period to compare to `parsedPeriod`
72
+ break;
73
+ }
74
+ // Take the previous Period as reference and compare it now to `parsedPeriod`
70
75
  lastFlattenedPeriod = flattenedPeriods[flattenedPeriods.length - 1];
71
76
  }
72
77
  }
@@ -54,6 +54,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
54
54
  var log_1 = require("../../../../log");
55
55
  var array_find_1 = require("../../../../utils/array_find");
56
56
  var object_assign_1 = require("../../../../utils/object_assign");
57
+ var convert_supplemental_codecs_1 = require("./convert_supplemental_codecs");
57
58
  var get_hdr_information_1 = require("./get_hdr_information");
58
59
  var parse_representation_index_1 = require("./parse_representation_index");
59
60
  var resolve_base_urls_1 = require("./resolve_base_urls");
@@ -120,19 +121,19 @@ function parseRepresentations(representationsIR, adaptation, context) {
120
121
  var parsedRepresentations = [];
121
122
  var _loop_1 = function (representation) {
122
123
  // Compute Representation ID
123
- var representationID = representation.attributes.id != null ?
124
+ var representationID = representation.attributes.id !== undefined ?
124
125
  representation.attributes.id :
125
126
  (String(representation.attributes.bitrate) +
126
- (representation.attributes.height != null ?
127
+ (representation.attributes.height !== undefined ?
127
128
  ("-".concat(representation.attributes.height)) :
128
129
  "") +
129
- (representation.attributes.width != null ?
130
+ (representation.attributes.width !== undefined ?
130
131
  ("-".concat(representation.attributes.width)) :
131
132
  "") +
132
- (representation.attributes.mimeType != null ?
133
+ (representation.attributes.mimeType !== undefined ?
133
134
  ("-".concat(representation.attributes.mimeType)) :
134
135
  "") +
135
- (representation.attributes.codecs != null ?
136
+ (representation.attributes.codecs !== undefined ?
136
137
  ("-".concat(representation.attributes.codecs)) :
137
138
  ""));
138
139
  // Avoid duplicate IDs
@@ -150,7 +151,7 @@ function parseRepresentations(representationsIR, adaptation, context) {
150
151
  var representationIndex = (0, parse_representation_index_1.default)(representation, reprIndexCtxt);
151
152
  // Find bitrate
152
153
  var representationBitrate = void 0;
153
- if (representation.attributes.bitrate == null) {
154
+ if (representation.attributes.bitrate === undefined) {
154
155
  log_1.default.warn("DASH: No usable bitrate found in the Representation.");
155
156
  representationBitrate = 0;
156
157
  }
@@ -177,45 +178,56 @@ function parseRepresentations(representationsIR, adaptation, context) {
177
178
  }
178
179
  // Add optional attributes
179
180
  var codecs = void 0;
180
- if (representation.attributes.codecs != null) {
181
+ if (representation.attributes.codecs !== undefined) {
181
182
  codecs = representation.attributes.codecs;
182
183
  }
183
- else if (adaptation.attributes.codecs != null) {
184
+ else if (adaptation.attributes.codecs !== undefined) {
184
185
  codecs = adaptation.attributes.codecs;
185
186
  }
186
- if (codecs != null) {
187
+ if (codecs !== undefined) {
187
188
  codecs = codecs === "mp4a.40.02" ? "mp4a.40.2" : codecs;
188
189
  parsedRepresentation.codecs = codecs;
189
190
  }
190
- if (representation.attributes.frameRate != null) {
191
+ var supplementalCodecs = void 0;
192
+ if (representation.attributes.supplementalCodecs !== undefined) {
193
+ supplementalCodecs = representation.attributes.supplementalCodecs;
194
+ }
195
+ else if (adaptation.attributes.supplementalCodecs !== undefined) {
196
+ supplementalCodecs = adaptation.attributes.supplementalCodecs;
197
+ }
198
+ if (supplementalCodecs !== undefined) {
199
+ parsedRepresentation.supplementalCodecs =
200
+ (0, convert_supplemental_codecs_1.convertSupplementalCodecsToRFC6381)(supplementalCodecs);
201
+ }
202
+ if (representation.attributes.frameRate !== undefined) {
191
203
  parsedRepresentation.frameRate =
192
204
  representation.attributes.frameRate;
193
205
  }
194
- else if (adaptation.attributes.frameRate != null) {
206
+ else if (adaptation.attributes.frameRate !== undefined) {
195
207
  parsedRepresentation.frameRate =
196
208
  adaptation.attributes.frameRate;
197
209
  }
198
- if (representation.attributes.height != null) {
210
+ if (representation.attributes.height !== undefined) {
199
211
  parsedRepresentation.height =
200
212
  representation.attributes.height;
201
213
  }
202
- else if (adaptation.attributes.height != null) {
214
+ else if (adaptation.attributes.height !== undefined) {
203
215
  parsedRepresentation.height =
204
216
  adaptation.attributes.height;
205
217
  }
206
- if (representation.attributes.mimeType != null) {
218
+ if (representation.attributes.mimeType !== undefined) {
207
219
  parsedRepresentation.mimeType =
208
220
  representation.attributes.mimeType;
209
221
  }
210
- else if (adaptation.attributes.mimeType != null) {
222
+ else if (adaptation.attributes.mimeType !== undefined) {
211
223
  parsedRepresentation.mimeType =
212
224
  adaptation.attributes.mimeType;
213
225
  }
214
- if (representation.attributes.width != null) {
226
+ if (representation.attributes.width !== undefined) {
215
227
  parsedRepresentation.width =
216
228
  representation.attributes.width;
217
229
  }
218
- else if (adaptation.attributes.width != null) {
230
+ else if (adaptation.attributes.width !== undefined) {
219
231
  parsedRepresentation.width =
220
232
  adaptation.attributes.width;
221
233
  }
@@ -259,6 +259,9 @@ function parseAdaptationSetAttributes(root) {
259
259
  case "codecs":
260
260
  parsedAdaptation.codecs = attribute.value;
261
261
  break;
262
+ case "scte214:supplementalCodecs":
263
+ parsedAdaptation.supplementalCodecs = attribute.value;
264
+ break;
262
265
  case "codingDependency":
263
266
  parseValue(attribute.value, { asKey: "codingDependency",
264
267
  parser: utils_1.parseBoolean,
@@ -168,6 +168,9 @@ function parseRepresentationAttributes(representationElement) {
168
168
  parser: utils_1.parseMPDInteger,
169
169
  dashName: "qualityRanking" });
170
170
  break;
171
+ case "scte214:supplementalCodecs":
172
+ attributes.supplementalCodecs = attr.value;
173
+ break;
171
174
  case "segmentProfiles":
172
175
  attributes.segmentProfiles = attr.value;
173
176
  break;
@@ -217,6 +217,7 @@ export interface IAdaptationSetAttributes {
217
217
  segmentAlignment?: number | boolean;
218
218
  segmentProfiles?: string;
219
219
  subsegmentAlignment?: number | boolean;
220
+ supplementalCodecs?: string;
220
221
  width?: number;
221
222
  availabilityTimeComplete?: boolean;
222
223
  availabilityTimeOffset?: number;
@@ -249,6 +250,7 @@ export interface IRepresentationAttributes {
249
250
  profiles?: string;
250
251
  qualityRanking?: number;
251
252
  segmentProfiles?: string;
253
+ supplementalCodecs?: string;
252
254
  width?: number;
253
255
  availabilityTimeComplete?: boolean;
254
256
  availabilityTimeOffset?: number;
@@ -226,6 +226,10 @@ function generateAdaptationSetAttrParser(adaptationAttrs, linearMemory) {
226
226
  adaptationAttrs.codecs =
227
227
  (0, utils_1.parseString)(textDecoder, linearMemory.buffer, ptr, len);
228
228
  break;
229
+ case 77 /* AttributeName.SupplementalCodecs */:
230
+ adaptationAttrs.supplementalCodecs =
231
+ (0, utils_1.parseString)(textDecoder, linearMemory.buffer, ptr, len);
232
+ break;
229
233
  case 2 /* AttributeName.Profiles */:
230
234
  adaptationAttrs.profiles =
231
235
  (0, utils_1.parseString)(textDecoder, linearMemory.buffer, ptr, len);
@@ -126,6 +126,10 @@ function generateRepresentationAttrParser(representationAttrs, linearMemory) {
126
126
  representationAttrs.codecs =
127
127
  (0, utils_1.parseString)(textDecoder, linearMemory.buffer, ptr, len);
128
128
  break;
129
+ case 77 /* AttributeName.SupplementalCodecs */:
130
+ representationAttrs.supplementalCodecs =
131
+ (0, utils_1.parseString)(textDecoder, linearMemory.buffer, ptr, len);
132
+ break;
129
133
  case 5 /* AttributeName.CodingDependency */:
130
134
  representationAttrs.codingDependency =
131
135
  new DataView(linearMemory.buffer).getUint8(0) === 0;
@@ -140,5 +140,6 @@ export declare const enum AttributeName {
140
140
  QueryBeforeStart = 73,
141
141
  ProxyServerUrl = 74,
142
142
  DefaultServiceLocation = 75,
143
- EndNumber = 76
143
+ EndNumber = 76,
144
+ SupplementalCodecs = 77
144
145
  }
@@ -154,6 +154,7 @@ export interface IParsedRepresentation {
154
154
  hdrInfo?: IHDRInformation | undefined;
155
155
  /** `true` if audio has Dolby Atmos. */
156
156
  isSpatialAudio?: boolean | undefined;
157
+ supplementalCodecs?: string | undefined;
157
158
  }
158
159
  /** Every possible types an Adaptation can have. */
159
160
  export type IParsedAdaptationType = "audio" | "video" | "text";
@@ -0,0 +1,2 @@
1
+ declare const _default: typeof queueMicrotask;
2
+ export default _default;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = typeof queueMicrotask === "function" ?
4
+ queueMicrotask :
5
+ function queueMicrotaskPonyfill(cb) {
6
+ Promise.resolve().then(cb, function () { return cb(); });
7
+ };