rx-player 3.30.1-dev.2023032800 → 3.31.0-dev.2023052200

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 (96) hide show
  1. package/CHANGELOG.md +14 -2
  2. package/CONTRIBUTING.md +48 -168
  3. package/FILES.md +40 -92
  4. package/VERSION +1 -1
  5. package/dist/_esm5.processed/compat/browser_detection.d.ts +3 -1
  6. package/dist/_esm5.processed/compat/browser_detection.js +7 -2
  7. package/dist/_esm5.processed/compat/has_issues_with_high_media_source_duration.d.ts +21 -0
  8. package/dist/_esm5.processed/compat/has_issues_with_high_media_source_duration.js +26 -0
  9. package/dist/_esm5.processed/core/adaptive/adaptive_representation_selector.js +1 -2
  10. package/dist/_esm5.processed/core/adaptive/buffer_based_chooser.d.ts +18 -1
  11. package/dist/_esm5.processed/core/adaptive/buffer_based_chooser.js +105 -24
  12. package/dist/_esm5.processed/core/adaptive/guess_based_chooser.js +6 -6
  13. package/dist/_esm5.processed/core/adaptive/utils/representation_score_calculator.d.ts +19 -1
  14. package/dist/_esm5.processed/core/adaptive/utils/representation_score_calculator.js +1 -1
  15. package/dist/_esm5.processed/core/api/debug/render.js +1 -1
  16. package/dist/_esm5.processed/core/api/public_api.js +2 -2
  17. package/dist/_esm5.processed/core/api/tracks_management/media_element_track_choice_manager.js +10 -1
  18. package/dist/_esm5.processed/core/api/tracks_management/track_choice_manager.js +20 -117
  19. package/dist/_esm5.processed/core/init/media_source_content_initializer.js +28 -3
  20. package/dist/_esm5.processed/core/init/utils/media_source_duration_updater.d.ts +2 -2
  21. package/dist/_esm5.processed/core/init/utils/media_source_duration_updater.js +29 -18
  22. package/dist/_esm5.processed/core/segment_buffers/index.d.ts +2 -2
  23. package/dist/_esm5.processed/core/stream/adaptation/utils/create_representation_estimator.js +1 -1
  24. package/dist/_esm5.processed/core/stream/period/period_stream.js +1 -1
  25. package/dist/_esm5.processed/core/stream/representation/utils/append_segment_to_buffer.d.ts +4 -2
  26. package/dist/_esm5.processed/core/stream/representation/utils/append_segment_to_buffer.js +2 -2
  27. package/dist/_esm5.processed/core/stream/representation/utils/push_init_segment.js +6 -2
  28. package/dist/_esm5.processed/errors/index.d.ts +2 -2
  29. package/dist/_esm5.processed/errors/media_error.d.ts +23 -1
  30. package/dist/_esm5.processed/errors/media_error.js +18 -5
  31. package/dist/_esm5.processed/manifest/adaptation.d.ts +17 -2
  32. package/dist/_esm5.processed/manifest/adaptation.js +67 -1
  33. package/dist/_esm5.processed/manifest/manifest.d.ts +1 -1
  34. package/dist/_esm5.processed/manifest/manifest.js +3 -3
  35. package/dist/_esm5.processed/manifest/period.js +1 -1
  36. package/dist/_esm5.processed/manifest/representation.d.ts +11 -1
  37. package/dist/_esm5.processed/manifest/representation.js +16 -0
  38. package/dist/_esm5.processed/parsers/manifest/dash/js-parser/parse_from_document.d.ts +1 -1
  39. package/dist/_esm5.processed/parsers/manifest/dash/js-parser/parse_from_document.js +1 -1
  40. package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/dash-wasm-parser.js +1 -0
  41. package/dist/_esm5.processed/public_types.d.ts +6 -5
  42. package/dist/_esm5.processed/transports/smooth/isobmff/create_boxes.d.ts +4 -6
  43. package/dist/_esm5.processed/transports/smooth/isobmff/create_boxes.js +4 -6
  44. package/dist/rx-player.js +3086 -3024
  45. package/dist/rx-player.min.js +1 -1
  46. package/package.json +25 -26
  47. package/sonar-project.properties +1 -1
  48. package/src/compat/browser_detection.ts +7 -1
  49. package/src/compat/has_issues_with_high_media_source_duration.ts +27 -0
  50. package/src/core/adaptive/__tests__/buffer_based_chooser.test.ts +147 -48
  51. package/src/core/adaptive/adaptive_representation_selector.ts +1 -2
  52. package/src/core/adaptive/buffer_based_chooser.ts +143 -25
  53. package/src/core/adaptive/guess_based_chooser.ts +9 -8
  54. package/src/core/adaptive/utils/representation_score_calculator.ts +22 -2
  55. package/src/core/api/debug/render.ts +1 -1
  56. package/src/core/api/public_api.ts +2 -2
  57. package/src/core/api/tracks_management/media_element_track_choice_manager.ts +17 -8
  58. package/src/core/api/tracks_management/track_choice_manager.ts +20 -132
  59. package/src/core/init/media_source_content_initializer.ts +32 -4
  60. package/src/core/init/utils/media_source_duration_updater.ts +31 -19
  61. package/src/core/segment_buffers/index.ts +2 -0
  62. package/src/core/stream/adaptation/utils/create_representation_estimator.ts +2 -1
  63. package/src/core/stream/period/period_stream.ts +2 -1
  64. package/src/core/stream/representation/utils/append_segment_to_buffer.ts +8 -3
  65. package/src/core/stream/representation/utils/push_init_segment.ts +7 -1
  66. package/src/errors/__tests__/media_error.test.ts +6 -6
  67. package/src/errors/index.ts +4 -1
  68. package/src/errors/media_error.ts +67 -1
  69. package/src/manifest/__tests__/period.test.ts +90 -45
  70. package/src/manifest/adaptation.ts +77 -2
  71. package/src/manifest/manifest.ts +5 -3
  72. package/src/manifest/period.ts +2 -1
  73. package/src/manifest/representation.ts +23 -1
  74. package/src/parsers/manifest/dash/js-parser/parse_from_document.ts +1 -1
  75. package/src/parsers/manifest/dash/wasm-parser/ts/dash-wasm-parser.ts +1 -0
  76. package/src/parsers/texttracks/ttml/parse_ttml.ts +1 -1
  77. package/src/public_types.ts +8 -3
  78. package/src/transports/smooth/isobmff/create_boxes.ts +4 -6
  79. package/src/typings/globals.d.ts +21 -21
  80. package/scripts/doc-generator/construct_table_of_contents.js +0 -76
  81. package/scripts/doc-generator/convert_MD_to_HMTL.js +0 -26
  82. package/scripts/doc-generator/create_documentation.js +0 -331
  83. package/scripts/doc-generator/create_documentation_page.js +0 -209
  84. package/scripts/doc-generator/create_page.js +0 -210
  85. package/scripts/doc-generator/generate_header_html.js +0 -147
  86. package/scripts/doc-generator/generate_page_html.js +0 -115
  87. package/scripts/doc-generator/generate_page_list_html.js +0 -92
  88. package/scripts/doc-generator/generate_sidebar_html.js +0 -85
  89. package/scripts/doc-generator/get_search_data_for_content.js +0 -137
  90. package/scripts/doc-generator/index.js +0 -34
  91. package/scripts/doc-generator/parse_doc_configs.js +0 -327
  92. package/scripts/doc-generator/scripts/lunr.js +0 -10
  93. package/scripts/doc-generator/scripts/script.js +0 -451
  94. package/scripts/doc-generator/styles/code.css +0 -99
  95. package/scripts/doc-generator/styles/style.css +0 -835
  96. package/scripts/doc-generator/utils.js +0 -74
@@ -379,7 +379,32 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
379
379
  function handleStreamOrchestratorCallbacks() {
380
380
  return {
381
381
  needsBufferFlush: function () {
382
- return playbackObserver.setCurrentTime(mediaElement.currentTime + 0.001);
382
+ var seekedTime = mediaElement.currentTime + 0.001;
383
+ playbackObserver.setCurrentTime(seekedTime);
384
+ // Seek again once data begins to be buffered.
385
+ // This is sadly necessary on some browsers to avoid decoding
386
+ // issues after a flush.
387
+ //
388
+ // NOTE: there's in theory a potential race condition in the following
389
+ // logic as the callback could be called when media data is still
390
+ // being removed by the browser - which is an asynchronous process.
391
+ // The following condition checking for buffered data could thus lead
392
+ // to a false positive where we're actually checking previous data.
393
+ // For now, such scenario is avoided by setting the
394
+ // `includeLastObservation` option to `false` and calling
395
+ // `needsBufferFlush` once MSE media removal operations have been
396
+ // explicitely validated by the browser, but that's a complex and easy
397
+ // to break system.
398
+ playbackObserver.listen(function (obs, stopListening) {
399
+ if (
400
+ // Data is buffered around the current position
401
+ obs.currentRange !== null ||
402
+ // Or, for whatever reason, playback is already advancing
403
+ obs.position > seekedTime + 0.1) {
404
+ stopListening();
405
+ playbackObserver.setCurrentTime(obs.position + 0.001);
406
+ }
407
+ }, { includeLastObservation: false, clearSignal: cancelSignal });
383
408
  },
384
409
  streamStatusUpdate: function (value) {
385
410
  // Announce discontinuities if found
@@ -518,7 +543,7 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
518
543
  _this.trigger("activePeriodChanged", { period: period });
519
544
  });
520
545
  contentTimeBoundariesObserver.addEventListener("durationUpdate", function (newDuration) {
521
- mediaSourceDurationUpdater.updateDuration(newDuration.duration, !newDuration.isEnd);
546
+ mediaSourceDurationUpdater.updateDuration(newDuration.duration, newDuration.isEnd);
522
547
  });
523
548
  contentTimeBoundariesObserver.addEventListener("endOfStream", function () {
524
549
  if (endOfStreamCanceller === null) {
@@ -536,7 +561,7 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
536
561
  }
537
562
  });
538
563
  var currentDuration = contentTimeBoundariesObserver.getCurrentDuration();
539
- mediaSourceDurationUpdater.updateDuration(currentDuration.duration, !currentDuration.isEnd);
564
+ mediaSourceDurationUpdater.updateDuration(currentDuration.duration, currentDuration.isEnd);
540
565
  return contentTimeBoundariesObserver;
541
566
  };
542
567
  /**
@@ -42,7 +42,7 @@ export default class MediaSourceDurationUpdater {
42
42
  * which `duration` attribute should be set on the `MediaSource` associated
43
43
  *
44
44
  * @param {number} newDuration
45
- * @param {boolean} addTimeMargin - If set to `true`, the current content is
45
+ * @param {boolean} isRealEndKnown - If set to `false`, the current content is
46
46
  * a dynamic content (it might evolve in the future) and the `newDuration`
47
47
  * communicated might be greater still. In effect the
48
48
  * `MediaSourceDurationUpdater` will actually set a much higher value to the
@@ -50,7 +50,7 @@ export default class MediaSourceDurationUpdater {
50
50
  * side-effects of having a too low duration (such as the impossibility to
51
51
  * seek over that value).
52
52
  */
53
- updateDuration(newDuration: number, addTimeMargin: boolean): void;
53
+ updateDuration(newDuration: number, isRealEndKnown: boolean): void;
54
54
  /**
55
55
  * Abort the last duration-setting operation and free its resources.
56
56
  */
@@ -14,6 +14,8 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { onSourceOpen, onSourceEnded, onSourceClose, } from "../../../compat/event_listeners";
17
+ /* eslint-disable-next-line max-len */
18
+ import hasIssuesWithHighMediaSourceDuration from "../../../compat/has_issues_with_high_media_source_duration";
17
19
  import log from "../../../log";
18
20
  import createSharedReference from "../../../utils/reference";
19
21
  import TaskCanceller from "../../../utils/task_canceller";
@@ -42,7 +44,7 @@ var MediaSourceDurationUpdater = /** @class */ (function () {
42
44
  * which `duration` attribute should be set on the `MediaSource` associated
43
45
  *
44
46
  * @param {number} newDuration
45
- * @param {boolean} addTimeMargin - If set to `true`, the current content is
47
+ * @param {boolean} isRealEndKnown - If set to `false`, the current content is
46
48
  * a dynamic content (it might evolve in the future) and the `newDuration`
47
49
  * communicated might be greater still. In effect the
48
50
  * `MediaSourceDurationUpdater` will actually set a much higher value to the
@@ -50,7 +52,7 @@ var MediaSourceDurationUpdater = /** @class */ (function () {
50
52
  * side-effects of having a too low duration (such as the impossibility to
51
53
  * seek over that value).
52
54
  */
53
- MediaSourceDurationUpdater.prototype.updateDuration = function (newDuration, addTimeMargin) {
55
+ MediaSourceDurationUpdater.prototype.updateDuration = function (newDuration, isRealEndKnown) {
54
56
  if (this._currentMediaSourceDurationUpdateCanceller !== null) {
55
57
  this._currentMediaSourceDurationUpdateCanceller.cancel();
56
58
  }
@@ -81,7 +83,7 @@ var MediaSourceDurationUpdater = /** @class */ (function () {
81
83
  if (areUpdating) {
82
84
  return;
83
85
  }
84
- recursivelyForceDurationUpdate(mediaSource, newDuration, addTimeMargin, sourceBuffersUpdatingCanceller.signal);
86
+ recursivelyForceDurationUpdate(mediaSource, newDuration, isRealEndKnown, sourceBuffersUpdatingCanceller.signal);
85
87
  }, { clearSignal: msOpenStatusCanceller.signal, emitCurrentValue: true });
86
88
  }
87
89
  };
@@ -107,20 +109,15 @@ export default MediaSourceDurationUpdater;
107
109
  *
108
110
  * @param {MediaSource} mediaSource
109
111
  * @param {number} duration
110
- * @param {boolean} addTimeMargin
112
+ * @param {boolean} isRealEndKnown
111
113
  * @returns {string}
112
114
  */
113
- function setMediaSourceDuration(mediaSource, duration, addTimeMargin) {
115
+ function setMediaSourceDuration(mediaSource, duration, isRealEndKnown) {
114
116
  var newDuration = duration;
115
- if (addTimeMargin) {
116
- // Some targets poorly support setting a very high number for durations.
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.
123
- newDuration = Math.max(Math.pow(2, 32), newDuration + YEAR_IN_SECONDS);
117
+ if (!isRealEndKnown) {
118
+ newDuration = hasIssuesWithHighMediaSourceDuration() ?
119
+ Infinity :
120
+ getMaximumLiveSeekablePosition(duration);
124
121
  }
125
122
  var maxBufferedEnd = 0;
126
123
  for (var i = 0; i < mediaSource.sourceBuffers.length; i++) {
@@ -153,6 +150,9 @@ function setMediaSourceDuration(mediaSource, duration, addTimeMargin) {
153
150
  try {
154
151
  log.info("Init: Updating duration", newDuration);
155
152
  mediaSource.duration = newDuration;
153
+ if (mediaSource.readyState === "open" && !isFinite(newDuration)) {
154
+ mediaSource.setLiveSeekableRange(0, getMaximumLiveSeekablePosition(duration));
155
+ }
156
156
  }
157
157
  catch (err) {
158
158
  log.warn("Duration Updater: Can't update duration on the MediaSource.", err instanceof Error ? err : "");
@@ -234,19 +234,30 @@ function createMediaSourceOpenReference(mediaSource, cancelSignal) {
234
234
  *
235
235
  * @param {MediaSource} mediaSource
236
236
  * @param {number} duration
237
- * @param {boolean} addTimeMargin
237
+ * @param {boolean} isRealEndKnown
238
238
  * @param {Object} cancelSignal
239
239
  */
240
- function recursivelyForceDurationUpdate(mediaSource, duration, addTimeMargin, cancelSignal) {
241
- var res = setMediaSourceDuration(mediaSource, duration, addTimeMargin);
240
+ function recursivelyForceDurationUpdate(mediaSource, duration, isRealEndKnown, cancelSignal) {
241
+ var res = setMediaSourceDuration(mediaSource, duration, isRealEndKnown);
242
242
  if (res === "success" /* MediaSourceDurationUpdateStatus.Success */) {
243
243
  return;
244
244
  }
245
245
  var timeoutId = setTimeout(function () {
246
246
  unregisterClear();
247
- recursivelyForceDurationUpdate(mediaSource, duration, addTimeMargin, cancelSignal);
247
+ recursivelyForceDurationUpdate(mediaSource, duration, isRealEndKnown, cancelSignal);
248
248
  }, 2000);
249
249
  var unregisterClear = cancelSignal.register(function () {
250
250
  clearTimeout(timeoutId);
251
251
  });
252
252
  }
253
+ function getMaximumLiveSeekablePosition(contentLastPosition) {
254
+ // Some targets poorly support setting a very high number for seekable
255
+ // ranges.
256
+ // Yet, in contents whose end is not yet known (e.g. live contents), we
257
+ // would prefer setting a value as high as possible to still be able to
258
+ // seek anywhere we want to (even ahead of the Manifest if we want to).
259
+ // As such, we put it at a safe default value of 2^32 excepted when the
260
+ // maximum position is already relatively close to that value, where we
261
+ // authorize exceptionally going over it.
262
+ return Math.max(Math.pow(2, 32), contentLastPosition + YEAR_IN_SECONDS);
263
+ }
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import BufferGarbageCollector from "./garbage_collector";
17
17
  import { IBufferType, IEndOfSegmentInfos, IEndOfSegmentOperation, IPushChunkInfos, IPushedChunkData, IPushOperation, IRemoveOperation, ISBOperation, SegmentBuffer, SegmentBufferOperation } from "./implementations";
18
- import { IBufferedChunk, IChunkContext } from "./inventory";
18
+ import { IBufferedChunk, IChunkContext, IInsertedChunkInfos } from "./inventory";
19
19
  import SegmentBuffersStore, { ISegmentBufferOptions, ITextTrackSegmentBufferOptions } from "./segment_buffers_store";
20
20
  export default SegmentBuffersStore;
21
- export { BufferGarbageCollector, ISegmentBufferOptions, ITextTrackSegmentBufferOptions, SegmentBuffer, IBufferType, IBufferedChunk, IChunkContext, IPushChunkInfos, IPushedChunkData, IEndOfSegmentInfos, SegmentBufferOperation, ISBOperation, IEndOfSegmentOperation, IPushOperation, IRemoveOperation, };
21
+ export { BufferGarbageCollector, ISegmentBufferOptions, ITextTrackSegmentBufferOptions, SegmentBuffer, IBufferType, IBufferedChunk, IChunkContext, IInsertedChunkInfos, IPushChunkInfos, IPushedChunkData, IEndOfSegmentInfos, SegmentBufferOperation, ISBOperation, IEndOfSegmentOperation, IPushOperation, IRemoveOperation, };
@@ -46,7 +46,7 @@ export default function getRepresentationEstimate(content, representationEstimat
46
46
  var newRepr = adaptation.getPlayableRepresentations();
47
47
  if (newRepr.length === 0) {
48
48
  var noRepErr = new MediaError("NO_PLAYABLE_REPRESENTATION", "No Representation in the chosen " +
49
- adaptation.type + " Adaptation can be played");
49
+ adaptation.type + " Adaptation can be played", { adaptation: adaptation });
50
50
  cleanUp();
51
51
  onFatalError(noRepErr);
52
52
  return;
@@ -329,7 +329,7 @@ function getFirstDeclaredMimeType(adaptation) {
329
329
  var representations = adaptation.getPlayableRepresentations();
330
330
  if (representations.length === 0) {
331
331
  var noRepErr = new MediaError("NO_PLAYABLE_REPRESENTATION", "No Representation in the chosen " +
332
- adaptation.type + " Adaptation can be played");
332
+ adaptation.type + " Adaptation can be played", { adaptation: adaptation });
333
333
  throw noRepErr;
334
334
  }
335
335
  return representations[0].getMimeTypeString();
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import { CancellationSignal } from "../../../../utils/task_canceller";
17
17
  import { IReadOnlyPlaybackObserver } from "../../../api";
18
- import { IPushChunkInfos, SegmentBuffer } from "../../../segment_buffers";
18
+ import { IInsertedChunkInfos, IPushChunkInfos, SegmentBuffer } from "../../../segment_buffers";
19
19
  import { IRepresentationStreamPlaybackObservation } from "../types";
20
20
  /**
21
21
  * Append a segment to the given segmentBuffer.
@@ -27,4 +27,6 @@ import { IRepresentationStreamPlaybackObservation } from "../types";
27
27
  * @param {Object} cancellationSignal
28
28
  * @returns {Promise}
29
29
  */
30
- export default function appendSegmentToBuffer<T>(playbackObserver: IReadOnlyPlaybackObserver<IRepresentationStreamPlaybackObservation>, segmentBuffer: SegmentBuffer, dataInfos: IPushChunkInfos<T>, cancellationSignal: CancellationSignal): Promise<void>;
30
+ export default function appendSegmentToBuffer<T>(playbackObserver: IReadOnlyPlaybackObserver<IRepresentationStreamPlaybackObservation>, segmentBuffer: SegmentBuffer, dataInfos: IPushChunkInfos<T> & {
31
+ inventoryInfos: IInsertedChunkInfos;
32
+ }, cancellationSignal: CancellationSignal): Promise<void>;
@@ -87,7 +87,7 @@ export default function appendSegmentToBuffer(playbackObserver, segmentBuffer, d
87
87
  reason = appendError_1 instanceof Error ?
88
88
  appendError_1.toString() :
89
89
  "An unknown error happened when pushing content";
90
- throw new MediaError("BUFFER_APPEND_ERROR", reason);
90
+ throw new MediaError("BUFFER_APPEND_ERROR", reason, { adaptation: dataInfos.inventoryInfos.adaptation });
91
91
  }
92
92
  position = playbackObserver.getReference().getValue().position;
93
93
  currentPos = (_a = position.pending) !== null && _a !== void 0 ? _a : position.last;
@@ -105,7 +105,7 @@ export default function appendSegmentToBuffer(playbackObserver, segmentBuffer, d
105
105
  err2_1 = _b.sent();
106
106
  reason = err2_1 instanceof Error ? err2_1.toString() :
107
107
  "Could not clean the buffer";
108
- throw new MediaError("BUFFER_FULL_ERROR", reason);
108
+ throw new MediaError("BUFFER_FULL_ERROR", reason, { adaptation: dataInfos.inventoryInfos.adaptation });
109
109
  case 7: return [3 /*break*/, 8];
110
110
  case 8: return [2 /*return*/];
111
111
  }
@@ -49,6 +49,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
49
49
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
50
50
  }
51
51
  };
52
+ import objectAssign from "../../../../utils/object_assign";
52
53
  import appendSegmentToBuffer from "./append_segment_to_buffer";
53
54
  /**
54
55
  * Push the initialization segment to the SegmentBuffer.
@@ -59,7 +60,7 @@ import appendSegmentToBuffer from "./append_segment_to_buffer";
59
60
  export default function pushInitSegment(_a, cancelSignal) {
60
61
  var playbackObserver = _a.playbackObserver, content = _a.content, segment = _a.segment, segmentData = _a.segmentData, segmentBuffer = _a.segmentBuffer;
61
62
  return __awaiter(this, void 0, void 0, function () {
62
- var codec, data, buffered;
63
+ var codec, data, inventoryInfos, buffered;
63
64
  return __generator(this, function (_b) {
64
65
  switch (_b.label) {
65
66
  case 0:
@@ -74,7 +75,10 @@ export default function pushInitSegment(_a, cancelSignal) {
74
75
  chunk: null,
75
76
  timestampOffset: 0,
76
77
  appendWindow: [undefined, undefined], codec: codec };
77
- return [4 /*yield*/, appendSegmentToBuffer(playbackObserver, segmentBuffer, { data: data, inventoryInfos: null }, cancelSignal)];
78
+ inventoryInfos = objectAssign({ segment: segment, chunkSize: undefined,
79
+ start: 0,
80
+ end: 0 }, content);
81
+ return [4 /*yield*/, appendSegmentToBuffer(playbackObserver, segmentBuffer, { data: data, inventoryInfos: inventoryInfos }, cancelSignal)];
78
82
  case 1:
79
83
  _b.sent();
80
84
  buffered = segmentBuffer.getBufferedRanges();
@@ -19,8 +19,8 @@ import EncryptedMediaError from "./encrypted_media_error";
19
19
  import { ErrorCodes, ErrorTypes, IErrorCode, IErrorType, NetworkErrorTypes } from "./error_codes";
20
20
  import formatError from "./format_error";
21
21
  import isKnownError from "./is_known_error";
22
- import MediaError from "./media_error";
22
+ import MediaError, { IMediaErrorTrackContext } from "./media_error";
23
23
  import NetworkError from "./network_error";
24
24
  import OtherError from "./other_error";
25
25
  import RequestError from "./request_error";
26
- export { AssertionError, CustomLoaderError, EncryptedMediaError, ErrorCodes, ErrorTypes, IErrorCode, IErrorType, formatError, MediaError as MediaError, NetworkError, OtherError, RequestError, NetworkErrorTypes, isKnownError, };
26
+ export { AssertionError, CustomLoaderError, EncryptedMediaError, ErrorCodes, ErrorTypes, IErrorCode, IErrorType, IMediaErrorTrackContext, formatError, MediaError as MediaError, NetworkError, OtherError, RequestError, NetworkErrorTypes, isKnownError, };
@@ -13,7 +13,23 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
+ import { Adaptation } from "../manifest";
17
+ import { IAudioTrack, ITextTrack, IVideoTrack } from "../public_types";
16
18
  import { IMediaErrorCode } from "./error_codes";
19
+ interface IAudioTrackMediaErrorContext {
20
+ type: "audio";
21
+ track: IAudioTrack;
22
+ }
23
+ interface IVideoTrackMediaErrorContext {
24
+ type: "video";
25
+ track: IVideoTrack;
26
+ }
27
+ interface ITextTrackMediaErrorContext {
28
+ type: "text";
29
+ track: ITextTrack;
30
+ }
31
+ export type IMediaErrorTrackContext = IAudioTrackMediaErrorContext | IVideoTrackMediaErrorContext | ITextTrackMediaErrorContext;
32
+ type ICodeWithAdaptationType = "BUFFER_APPEND_ERROR" | "BUFFER_FULL_ERROR" | "NO_PLAYABLE_REPRESENTATION" | "MANIFEST_INCOMPATIBLE_CODECS_ERROR";
17
33
  /**
18
34
  * Error linked to the media Playback.
19
35
  *
@@ -25,10 +41,16 @@ export default class MediaError extends Error {
25
41
  readonly type: "MEDIA_ERROR";
26
42
  readonly message: string;
27
43
  readonly code: IMediaErrorCode;
44
+ readonly trackInfo: IMediaErrorTrackContext | undefined;
28
45
  fatal: boolean;
29
46
  /**
30
47
  * @param {string} code
31
48
  * @param {string} reason
49
+ * @param {Object|undefined} [context]
32
50
  */
33
- constructor(code: IMediaErrorCode, reason: string);
51
+ constructor(code: ICodeWithAdaptationType, reason: string, context: {
52
+ adaptation: Adaptation;
53
+ });
54
+ constructor(code: Exclude<IMediaErrorCode, ICodeWithAdaptationType>, reason: string);
34
55
  }
56
+ export {};
@@ -38,11 +38,7 @@ import errorMessage from "./error_message";
38
38
  */
39
39
  var MediaError = /** @class */ (function (_super) {
40
40
  __extends(MediaError, _super);
41
- /**
42
- * @param {string} code
43
- * @param {string} reason
44
- */
45
- function MediaError(code, reason) {
41
+ function MediaError(code, reason, context) {
46
42
  var _this = _super.call(this) || this;
47
43
  // @see https://stackoverflow.com/questions/41102060/typescript-extending-error-class
48
44
  Object.setPrototypeOf(_this, MediaError.prototype);
@@ -51,6 +47,23 @@ var MediaError = /** @class */ (function (_super) {
51
47
  _this.code = code;
52
48
  _this.message = errorMessage(_this.name, _this.code, reason);
53
49
  _this.fatal = false;
50
+ var adaptation = context === null || context === void 0 ? void 0 : context.adaptation;
51
+ if (adaptation !== undefined) {
52
+ switch (adaptation.type) {
53
+ case "audio":
54
+ _this.trackInfo = { type: "audio",
55
+ track: adaptation.toAudioTrack() };
56
+ break;
57
+ case "video":
58
+ _this.trackInfo = { type: "video",
59
+ track: adaptation.toVideoTrack() };
60
+ break;
61
+ case "text":
62
+ _this.trackInfo = { type: "text",
63
+ track: adaptation.toTextTrack() };
64
+ break;
65
+ }
66
+ }
54
67
  return _this;
55
68
  }
56
69
  return MediaError;
@@ -14,14 +14,14 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { IParsedAdaptation } from "../parsers/manifest";
17
- import { IRepresentationFilter } from "../public_types";
17
+ import { IAudioTrack, IRepresentationFilter, ITextTrack, IVideoTrack } from "../public_types";
18
18
  import Representation from "./representation";
19
19
  import { IAdaptationType } from "./types";
20
20
  /** List in an array every possible value for the Adaptation's `type` property. */
21
21
  export declare const SUPPORTED_ADAPTATIONS_TYPE: IAdaptationType[];
22
22
  /**
23
23
  * Normalized Adaptation structure.
24
- * An Adaptation describes a single `Track`. For example a specific audio
24
+ * An `Adaptation` describes a single `Track`. For example a specific audio
25
25
  * track (in a given language) or a specific video track.
26
26
  * It istelf can be represented in different qualities, which we call here
27
27
  * `Representation`.
@@ -97,4 +97,19 @@ export default class Adaptation {
97
97
  * @returns {Object|undefined}
98
98
  */
99
99
  getRepresentation(wantedId: number | string): Representation | undefined;
100
+ /**
101
+ * Format an `Adaptation`, generally of type `"audio"`, as an `IAudioTrack`.
102
+ * @returns {Object}
103
+ */
104
+ toAudioTrack(): IAudioTrack;
105
+ /**
106
+ * Format an `Adaptation`, generally of type `"audio"`, as an `IAudioTrack`.
107
+ * @returns {Object}
108
+ */
109
+ toTextTrack(): ITextTrack;
110
+ /**
111
+ * Format an `Adaptation`, generally of type `"video"`, as an `IAudioTrack`.
112
+ * @returns {Object}
113
+ */
114
+ toVideoTrack(): IVideoTrack;
100
115
  }
@@ -26,7 +26,7 @@ export var SUPPORTED_ADAPTATIONS_TYPE = ["audio",
26
26
  "image"];
27
27
  /**
28
28
  * Normalized Adaptation structure.
29
- * An Adaptation describes a single `Track`. For example a specific audio
29
+ * An `Adaptation` describes a single `Track`. For example a specific audio
30
30
  * track (in a given language) or a specific video track.
31
31
  * It istelf can be represented in different qualities, which we call here
32
32
  * `Representation`.
@@ -137,6 +137,72 @@ var Adaptation = /** @class */ (function () {
137
137
  return wantedId === id;
138
138
  });
139
139
  };
140
+ /**
141
+ * Format an `Adaptation`, generally of type `"audio"`, as an `IAudioTrack`.
142
+ * @returns {Object}
143
+ */
144
+ Adaptation.prototype.toAudioTrack = function () {
145
+ var _a, _b;
146
+ var formatted = {
147
+ language: (_a = this.language) !== null && _a !== void 0 ? _a : "",
148
+ normalized: (_b = this.normalizedLanguage) !== null && _b !== void 0 ? _b : "",
149
+ audioDescription: this.isAudioDescription === true,
150
+ id: this.id,
151
+ representations: this.representations.map(function (r) { return r.toAudioRepresentation(); }),
152
+ label: this.label,
153
+ };
154
+ if (this.isDub === true) {
155
+ formatted.dub = true;
156
+ }
157
+ return formatted;
158
+ };
159
+ /**
160
+ * Format an `Adaptation`, generally of type `"audio"`, as an `IAudioTrack`.
161
+ * @returns {Object}
162
+ */
163
+ Adaptation.prototype.toTextTrack = function () {
164
+ var _a, _b;
165
+ return {
166
+ language: (_a = this.language) !== null && _a !== void 0 ? _a : "",
167
+ normalized: (_b = this.normalizedLanguage) !== null && _b !== void 0 ? _b : "",
168
+ closedCaption: this.isClosedCaption === true,
169
+ id: this.id,
170
+ label: this.label,
171
+ forced: this.isForcedSubtitles,
172
+ };
173
+ };
174
+ /**
175
+ * Format an `Adaptation`, generally of type `"video"`, as an `IAudioTrack`.
176
+ * @returns {Object}
177
+ */
178
+ Adaptation.prototype.toVideoTrack = function () {
179
+ var trickModeTracks = this.trickModeTracks !== undefined ?
180
+ this.trickModeTracks.map(function (trickModeAdaptation) {
181
+ var representations = trickModeAdaptation.representations
182
+ .map(function (r) { return r.toVideoRepresentation(); });
183
+ var trickMode = { id: trickModeAdaptation.id, representations: representations, isTrickModeTrack: true };
184
+ if (trickModeAdaptation.isSignInterpreted === true) {
185
+ trickMode.signInterpreted = true;
186
+ }
187
+ return trickMode;
188
+ }) :
189
+ undefined;
190
+ var videoTrack = {
191
+ id: this.id,
192
+ representations: this.representations.map(function (r) { return r.toVideoRepresentation(); }),
193
+ label: this.label,
194
+ };
195
+ if (this.isSignInterpreted === true) {
196
+ videoTrack.signInterpreted = true;
197
+ }
198
+ if (this.isTrickModeTrack === true) {
199
+ videoTrack.isTrickModeTrack = true;
200
+ }
201
+ if (trickModeTracks !== undefined) {
202
+ videoTrack.trickModeTracks = trickModeTracks;
203
+ }
204
+ return videoTrack;
205
+ };
140
206
  return Adaptation;
141
207
  }());
142
208
  export default Adaptation;
@@ -310,7 +310,7 @@ export default class Manifest extends EventEmitter<IManifestEvents> {
310
310
  private _addSupplementaryTextAdaptations;
311
311
  /**
312
312
  * @param {Object} newManifest
313
- * @param {number} type
313
+ * @param {number} updateType
314
314
  */
315
315
  private _performUpdate;
316
316
  }
@@ -340,7 +340,7 @@ var Manifest = /** @class */ (function (_super) {
340
340
  })
341
341
  }] }, { isManuallyAdded: true });
342
342
  if (newAdaptation.representations.length > 0 && !newAdaptation.isSupported) {
343
- var error = new MediaError("MANIFEST_INCOMPATIBLE_CODECS_ERROR", "An Adaptation contains only incompatible codecs.");
343
+ var error = new MediaError("MANIFEST_INCOMPATIBLE_CODECS_ERROR", "An Adaptation contains only incompatible codecs.", { adaptation: newAdaptation });
344
344
  _this.contentWarnings.push(error);
345
345
  }
346
346
  return newAdaptation;
@@ -392,7 +392,7 @@ var Manifest = /** @class */ (function (_super) {
392
392
  })
393
393
  }] }, { isManuallyAdded: true });
394
394
  if (newAdaptation.representations.length > 0 && !newAdaptation.isSupported) {
395
- var error = new MediaError("MANIFEST_INCOMPATIBLE_CODECS_ERROR", "An Adaptation contains only incompatible codecs.");
395
+ var error = new MediaError("MANIFEST_INCOMPATIBLE_CODECS_ERROR", "An Adaptation contains only incompatible codecs.", { adaptation: newAdaptation });
396
396
  _this.contentWarnings.push(error);
397
397
  }
398
398
  return newAdaptation;
@@ -407,7 +407,7 @@ var Manifest = /** @class */ (function (_super) {
407
407
  };
408
408
  /**
409
409
  * @param {Object} newManifest
410
- * @param {number} type
410
+ * @param {number} updateType
411
411
  */
412
412
  Manifest.prototype._performUpdate = function (newManifest, updateType) {
413
413
  this.availabilityStartTime = newManifest.availabilityStartTime;
@@ -42,7 +42,7 @@ var Period = /** @class */ (function () {
42
42
  .map(function (adaptation) {
43
43
  var newAdaptation = new Adaptation(adaptation, { representationFilter: representationFilter });
44
44
  if (newAdaptation.representations.length > 0 && !newAdaptation.isSupported) {
45
- var error = new MediaError("MANIFEST_INCOMPATIBLE_CODECS_ERROR", "An Adaptation contains only incompatible codecs.");
45
+ var error = new MediaError("MANIFEST_INCOMPATIBLE_CODECS_ERROR", "An Adaptation contains only incompatible codecs.", { adaptation: newAdaptation });
46
46
  _this.contentWarnings.push(error);
47
47
  }
48
48
  return newAdaptation;
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { ICdnMetadata, IContentProtections, IParsedRepresentation } from "../parsers/manifest";
17
- import { IHDRInformation } from "../public_types";
17
+ import { IAudioRepresentation, IHDRInformation, IVideoRepresentation } from "../public_types";
18
18
  import { IRepresentationIndex } from "./representation_index";
19
19
  import { IAdaptationType } from "./types";
20
20
  /**
@@ -166,6 +166,16 @@ declare class Representation {
166
166
  systemId: string;
167
167
  data: Uint8Array;
168
168
  }>): boolean;
169
+ /**
170
+ * Format Representation as an `IAudioRepresentation`.
171
+ * @returns {Object}
172
+ */
173
+ toAudioRepresentation(): IAudioRepresentation;
174
+ /**
175
+ * Format Representation as an `IVideoRepresentation`.
176
+ * @returns {Object}
177
+ */
178
+ toVideoRepresentation(): IVideoRepresentation;
169
179
  }
170
180
  /** Protection data as returned by a Representation. */
171
181
  export interface IRepresentationProtectionData {
@@ -225,6 +225,22 @@ var Representation = /** @class */ (function () {
225
225
  values: data });
226
226
  return true;
227
227
  };
228
+ /**
229
+ * Format Representation as an `IAudioRepresentation`.
230
+ * @returns {Object}
231
+ */
232
+ Representation.prototype.toAudioRepresentation = function () {
233
+ var _a = this, id = _a.id, bitrate = _a.bitrate, codec = _a.codec;
234
+ return { id: id, bitrate: bitrate, codec: codec };
235
+ };
236
+ /**
237
+ * Format Representation as an `IVideoRepresentation`.
238
+ * @returns {Object}
239
+ */
240
+ Representation.prototype.toVideoRepresentation = function () {
241
+ var _a = this, id = _a.id, bitrate = _a.bitrate, frameRate = _a.frameRate, width = _a.width, height = _a.height, codec = _a.codec, hdrInfo = _a.hdrInfo;
242
+ return { id: id, bitrate: bitrate, frameRate: frameRate, width: width, height: height, codec: codec, hdrInfo: hdrInfo };
243
+ };
228
244
  return Representation;
229
245
  }());
230
246
  export default Representation;
@@ -17,7 +17,7 @@ import { IMPDParserArguments } from "../common";
17
17
  import { IDashParserResponse } from "../parsers_types";
18
18
  /**
19
19
  * Parse MPD through the JS parser, on a `Document` instance.
20
- * @param {Document} manifest - Original manifest as returned by the server
20
+ * @param {Document} document - Original manifest as returned by the server
21
21
  * @param {Object} args - Various parsing options and information.
22
22
  * @returns {Object} - Response returned by the DASH-JS parser.
23
23
  */
@@ -20,7 +20,7 @@ import { createMPDIntermediateRepresentation, } from "./node_parsers/MPD";
20
20
  import { createPeriodIntermediateRepresentation, } from "./node_parsers/Period";
21
21
  /**
22
22
  * Parse MPD through the JS parser, on a `Document` instance.
23
- * @param {Document} manifest - Original manifest as returned by the server
23
+ * @param {Document} document - Original manifest as returned by the server
24
24
  * @param {Object} args - Various parsing options and information.
25
25
  * @returns {Object} - Response returned by the DASH-JS parser.
26
26
  */
@@ -230,6 +230,7 @@ var DashWasmParser = /** @class */ (function () {
230
230
  "Unknown error";
231
231
  log.warn("DW: Could not create DASH-WASM parser:", message);
232
232
  _this.status = "failure";
233
+ throw err;
233
234
  });
234
235
  return [2 /*return*/, this._initProm];
235
236
  });