rx-player 3.27.0-dev.2022032100 → 3.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/CHANGELOG.md +5 -2
  2. package/VERSION +1 -1
  3. package/dist/_esm5.processed/compat/eme/custom_media_keys/old_webkit_media_keys.js +15 -11
  4. package/dist/_esm5.processed/compat/eme/custom_media_keys/webkit_media_keys.js +22 -6
  5. package/dist/_esm5.processed/compat/eme/generate_key_request.d.ts +4 -6
  6. package/dist/_esm5.processed/compat/eme/generate_key_request.js +4 -6
  7. package/dist/_esm5.processed/compat/get_start_date.d.ts +30 -0
  8. package/dist/_esm5.processed/compat/get_start_date.js +44 -0
  9. package/dist/_esm5.processed/compat/index.d.ts +2 -1
  10. package/dist/_esm5.processed/compat/index.js +2 -1
  11. package/dist/_esm5.processed/config.d.ts +1 -5
  12. package/dist/_esm5.processed/core/api/public_api.js +25 -25
  13. package/dist/_esm5.processed/core/decrypt/content_decryptor.js +11 -3
  14. package/dist/_esm5.processed/core/decrypt/create_or_load_session.js +1 -1
  15. package/dist/_esm5.processed/core/decrypt/create_session.d.ts +3 -1
  16. package/dist/_esm5.processed/core/decrypt/create_session.js +15 -5
  17. package/dist/_esm5.processed/core/decrypt/utils/loaded_sessions_store.d.ts +94 -1
  18. package/dist/_esm5.processed/core/decrypt/utils/loaded_sessions_store.js +237 -96
  19. package/dist/_esm5.processed/core/segment_buffers/garbage_collector.js +4 -1
  20. package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +2 -1
  21. package/dist/_esm5.processed/core/stream/period/period_stream.js +9 -3
  22. package/dist/_esm5.processed/core/stream/representation/append_segment_to_buffer.js +4 -3
  23. package/dist/_esm5.processed/core/stream/representation/force_garbage_collection.js +3 -2
  24. package/dist/_esm5.processed/core/stream/representation/get_buffer_status.d.ts +2 -2
  25. package/dist/_esm5.processed/core/stream/representation/get_buffer_status.js +9 -3
  26. package/dist/_esm5.processed/core/stream/representation/get_needed_segments.d.ts +11 -1
  27. package/dist/_esm5.processed/core/stream/representation/get_needed_segments.js +27 -45
  28. package/dist/_esm5.processed/core/stream/representation/representation_stream.js +6 -4
  29. package/dist/_esm5.processed/default_config.d.ts +2 -35
  30. package/dist/_esm5.processed/default_config.js +2 -35
  31. package/dist/_esm5.processed/transports/dash/add_segment_integrity_checks_to_loader.js +39 -38
  32. package/dist/_esm5.processed/utils/reference.js +0 -2
  33. package/dist/_esm5.processed/utils/task_canceller.d.ts +8 -1
  34. package/dist/_esm5.processed/utils/task_canceller.js +9 -1
  35. package/dist/rx-player.js +927 -587
  36. package/dist/rx-player.min.js +1 -1
  37. package/package.json +1 -1
  38. package/sonar-project.properties +1 -1
  39. package/src/compat/eme/custom_media_keys/old_webkit_media_keys.ts +16 -12
  40. package/src/compat/eme/custom_media_keys/webkit_media_keys.ts +21 -8
  41. package/src/compat/eme/generate_key_request.ts +4 -6
  42. package/src/compat/get_start_date.ts +48 -0
  43. package/src/compat/index.ts +2 -0
  44. package/src/core/api/public_api.ts +23 -27
  45. package/src/core/decrypt/content_decryptor.ts +15 -4
  46. package/src/core/decrypt/create_or_load_session.ts +4 -1
  47. package/src/core/decrypt/create_session.ts +23 -9
  48. package/src/core/decrypt/utils/loaded_sessions_store.ts +254 -102
  49. package/src/core/segment_buffers/garbage_collector.ts +4 -0
  50. package/src/core/stream/orchestrator/stream_orchestrator.ts +2 -1
  51. package/src/core/stream/period/period_stream.ts +9 -4
  52. package/src/core/stream/representation/append_segment_to_buffer.ts +17 -13
  53. package/src/core/stream/representation/force_garbage_collection.ts +4 -1
  54. package/src/core/stream/representation/get_buffer_status.ts +21 -13
  55. package/src/core/stream/representation/get_needed_segments.ts +40 -55
  56. package/src/core/stream/representation/representation_stream.ts +6 -4
  57. package/src/default_config.ts +20 -57
  58. package/src/transports/dash/add_segment_integrity_checks_to_loader.ts +41 -44
  59. package/src/utils/reference.ts +0 -2
  60. package/src/utils/task_canceller.ts +16 -1
@@ -55,8 +55,8 @@ export default function getBufferStatus(content, wantedStartPosition, playbackOb
55
55
  /** Callback allowing to retrieve a segment's history in the buffer. */
56
56
  var getBufferedHistory = segmentBuffer.getSegmentHistory.bind(segmentBuffer);
57
57
  /** List of segments we will need to download. */
58
- var _b = getNeededSegments({ content: content, bufferedSegments: bufferedSegments, currentPlaybackTime: currentPlaybackTime, fastSwitchThreshold: fastSwitchThreshold, getBufferedHistory: getBufferedHistory, neededRange: neededRange, segmentsBeingPushed: segmentsBeingPushed, maxBufferSize: maxBufferSize }), neededSegments = _b.neededSegments, isBufferFull = _b.isBufferFull;
59
- var prioritizedNeededSegments = neededSegments.map(function (segment) { return ({
58
+ var _b = getNeededSegments({ content: content, bufferedSegments: bufferedSegments, currentPlaybackTime: currentPlaybackTime, fastSwitchThreshold: fastSwitchThreshold, getBufferedHistory: getBufferedHistory, neededRange: neededRange, segmentsBeingPushed: segmentsBeingPushed, maxBufferSize: maxBufferSize }), segmentsToLoad = _b.segmentsToLoad, segmentsOnHold = _b.segmentsOnHold, isBufferFull = _b.isBufferFull;
59
+ var prioritizedNeededSegments = segmentsToLoad.map(function (segment) { return ({
60
60
  priority: getSegmentPriority(segment.time, wantedStartPosition),
61
61
  segment: segment,
62
62
  }); });
@@ -68,7 +68,8 @@ export default function getBufferStatus(content, wantedStartPosition, playbackOb
68
68
  var lastPosition = representation.index.getLastPosition();
69
69
  if (!representation.index.isInitialized() ||
70
70
  period.end === undefined ||
71
- prioritizedNeededSegments.length > 0) {
71
+ prioritizedNeededSegments.length > 0 ||
72
+ segmentsOnHold.length > 0) {
72
73
  hasFinishedLoading = false;
73
74
  }
74
75
  else {
@@ -112,6 +113,11 @@ export default function getBufferStatus(content, wantedStartPosition, playbackOb
112
113
  if (segmentsBeingPushed.length > 0) {
113
114
  nextSegmentStart = Math.min.apply(Math, segmentsBeingPushed.map(function (info) { return info.segment.time; }));
114
115
  }
116
+ if (segmentsOnHold.length > 0) {
117
+ nextSegmentStart = nextSegmentStart !== null ?
118
+ Math.min(nextSegmentStart, segmentsOnHold[0].time) :
119
+ segmentsOnHold[0].time;
120
+ }
115
121
  if (prioritizedNeededSegments.length > 0) {
116
122
  nextSegmentStart = nextSegmentStart !== null ?
117
123
  Math.min(nextSegmentStart, prioritizedNeededSegments[0].segment.time) :
@@ -65,7 +65,17 @@ export interface IGetNeededSegmentsArguments {
65
65
  getBufferedHistory: (context: IChunkContext) => IBufferedHistoryEntry[];
66
66
  }
67
67
  interface INeededSegments {
68
- neededSegments: ISegment[];
68
+ /** Segments that should be loaded right now, by chronological order. */
69
+ segmentsToLoad: ISegment[];
70
+ /**
71
+ * Segments that should be loaded, but not right now, due to some other
72
+ * constraints, such as memory limitations.
73
+ */
74
+ segmentsOnHold: ISegment[];
75
+ /**
76
+ * If `true` the buffer is currently full according to the given limits.
77
+ * Memory should be freed if possible, for example by cleaning the buffers.
78
+ */
69
79
  isBufferFull: boolean;
70
80
  }
71
81
  /**
@@ -32,8 +32,6 @@ export default function getNeededSegments(_a) {
32
32
  var bufferedSegments = _a.bufferedSegments, content = _a.content, currentPlaybackTime = _a.currentPlaybackTime, fastSwitchThreshold = _a.fastSwitchThreshold, getBufferedHistory = _a.getBufferedHistory, neededRange = _a.neededRange, segmentsBeingPushed = _a.segmentsBeingPushed, maxBufferSize = _a.maxBufferSize;
33
33
  var representation = content.representation;
34
34
  var availableBufferSize = getAvailableBufferSize(bufferedSegments, segmentsBeingPushed, maxBufferSize);
35
- // Current buffer length in seconds
36
- var bufferLength = getBufferLength(bufferedSegments, segmentsBeingPushed);
37
35
  var availableSegmentsForRange = representation.index
38
36
  .getSegments(neededRange.start, neededRange.end - neededRange.start);
39
37
  // Remove from `bufferedSegments` any segments we would prefer to replace:
@@ -63,15 +61,16 @@ export default function getNeededSegments(_a) {
63
61
  }
64
62
  return true;
65
63
  });
66
- var _b = config.getCurrent(), MINIMUM_SEGMENT_SIZE = _b.MINIMUM_SEGMENT_SIZE, MIN_BUFFER_LENGTH = _b.MIN_BUFFER_LENGTH, MIN_BUFFER_DISTANCE_BEFORE_CLEAN_UP = _b.MIN_BUFFER_DISTANCE_BEFORE_CLEAN_UP;
67
- var isMemorySaturated = false;
64
+ var _b = config.getCurrent(), MINIMUM_SEGMENT_SIZE = _b.MINIMUM_SEGMENT_SIZE, MIN_BUFFER_AHEAD = _b.MIN_BUFFER_AHEAD;
65
+ var shouldStopLoadingSegments = false;
68
66
  /**
69
67
  * Epsilon compensating for rounding errors when comparing the start and end
70
68
  * time of multiple segments.
71
69
  */
72
70
  var ROUNDING_ERROR = Math.min(1 / 60, MINIMUM_SEGMENT_SIZE);
73
71
  var isBufferFull = false;
74
- var neededSegments = availableSegmentsForRange.filter(function (segment) {
72
+ var segmentsOnHold = [];
73
+ var segmentsToLoad = availableSegmentsForRange.filter(function (segment) {
75
74
  var contentObject = objectAssign({ segment: segment }, content);
76
75
  // First, check that the segment is not already being pushed
77
76
  if (segmentsBeingPushed.length > 0) {
@@ -85,17 +84,8 @@ export default function getNeededSegments(_a) {
85
84
  if (segment.isInit) {
86
85
  return true; // never skip initialization segments
87
86
  }
88
- if (isMemorySaturated) {
89
- // If we are so saturated in memory
90
- // That we cannot download atleast till
91
- // NeededRange.Start ( current position ) + a CONST
92
- // Then the buffer is full
93
- if (time < neededRange.start + MIN_BUFFER_DISTANCE_BEFORE_CLEAN_UP) {
94
- isBufferFull = true;
95
- }
96
- }
97
- if (isMemorySaturated &&
98
- bufferLength > MIN_BUFFER_LENGTH) {
87
+ if (shouldStopLoadingSegments) {
88
+ segmentsOnHold.push(segment);
99
89
  return false;
100
90
  }
101
91
  if (segment.complete && duration < MINIMUM_SEGMENT_SIZE) {
@@ -138,27 +128,34 @@ export default function getNeededSegments(_a) {
138
128
  }
139
129
  }
140
130
  }
131
+ var estimatedSegmentSize = (duration * content.representation.bitrate) / 8000;
132
+ if (availableBufferSize - estimatedSegmentSize < 0) {
133
+ isBufferFull = true;
134
+ if (time > neededRange.start + MIN_BUFFER_AHEAD) {
135
+ shouldStopLoadingSegments = true;
136
+ segmentsOnHold.push(segment);
137
+ return false;
138
+ }
139
+ }
141
140
  // check if there is an hole in place of the segment currently
142
141
  for (var i = 0; i < segmentsToKeep.length; i++) {
143
142
  var completeSeg = segmentsToKeep[i];
144
- if (completeSeg.end > time) {
145
- // `true` if `completeSeg` starts too far after `time`
146
- return completeSeg.start > time + ROUNDING_ERROR ||
147
- // `true` if `completeSeg` ends too soon before `end`
148
- getLastContiguousSegment(segmentsToKeep, i).end < end - ROUNDING_ERROR;
143
+ // For the first already-loaded segment, take the first one ending after
144
+ // this one' s start
145
+ if ((completeSeg.end + ROUNDING_ERROR) > time) {
146
+ var shouldLoad = completeSeg.start > time + ROUNDING_ERROR ||
147
+ getLastContiguousSegment(segmentsToKeep, i).end <
148
+ end - ROUNDING_ERROR;
149
+ if (shouldLoad) {
150
+ availableBufferSize -= estimatedSegmentSize;
151
+ }
152
+ return shouldLoad;
149
153
  }
150
154
  }
151
- var estimatedSegmentSize = (duration * content.representation.bitrate) / 8000;
152
- if (availableBufferSize - estimatedSegmentSize < 0 &&
153
- bufferLength > MIN_BUFFER_LENGTH) {
154
- isMemorySaturated = true;
155
- return false;
156
- }
157
155
  availableBufferSize -= estimatedSegmentSize;
158
- bufferLength += duration;
159
156
  return true;
160
157
  });
161
- return { neededSegments: neededSegments, isBufferFull: isBufferFull };
158
+ return { segmentsToLoad: segmentsToLoad, segmentsOnHold: segmentsOnHold, isBufferFull: isBufferFull };
162
159
  }
163
160
  /**
164
161
  * Compute the estimated available buffer size in memory in kilobytes
@@ -178,28 +175,13 @@ function getAvailableBufferSize(bufferedSegments, segmentsBeingPushed, maxVideoB
178
175
  }, 0);
179
176
  return bufferedSegments.reduce(function (size, chunk) {
180
177
  if (chunk.chunkSize !== undefined) {
181
- return size - (chunk.chunkSize / 8000);
178
+ return size - (chunk.chunkSize / 1000);
182
179
  }
183
180
  else {
184
181
  return size;
185
182
  }
186
183
  }, availableBufferSize);
187
184
  }
188
- /**
189
- * Compute the length of the buffer in seconds
190
- * @param bufferedSegments
191
- * @param segmentsBeingPushed
192
- * @returns bufferLength in seconds
193
- */
194
- function getBufferLength(bufferedSegments, segmentsBeingPushed) {
195
- var bufferLength = bufferedSegments.reduce(function (length, segment) {
196
- return length + (segment.end - segment.start);
197
- }, 0);
198
- var bufferBeingPushed = segmentsBeingPushed.reduce(function (length, segment) {
199
- return length + segment.segment.duration;
200
- }, 0);
201
- return bufferLength + bufferBeingPushed;
202
- }
203
185
  /**
204
186
  * From the given array of buffered chunks (`bufferedSegments`) returns the last
205
187
  * buffered chunk contiguous with the one at the `startIndex` index given.
@@ -166,10 +166,12 @@ export default function RepresentationStream(_a) {
166
166
  var UPTO_CURRENT_POSITION_CLEANUP = config.getCurrent().UPTO_CURRENT_POSITION_CLEANUP;
167
167
  if (status.isBufferFull) {
168
168
  var gcedPosition = Math.max(0, wantedStartPosition - UPTO_CURRENT_POSITION_CLEANUP);
169
- bufferRemoval = segmentBuffer
170
- .removeBuffer(0, gcedPosition)
171
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
172
- .pipe(ignoreElements());
169
+ if (gcedPosition > 0) {
170
+ bufferRemoval = segmentBuffer
171
+ .removeBuffer(0, gcedPosition)
172
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
173
+ .pipe(ignoreElements());
174
+ }
173
175
  }
174
176
  return status.shouldRefreshManifest ?
175
177
  observableConcat(observableOf(EVENTS.needsManifestRefresh()), bufferStatusEvt, bufferRemoval) :
@@ -934,33 +934,6 @@ declare const DEFAULT_CONFIG: {
934
934
  * This wasn't battle-tested however.
935
935
  */
936
936
  EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION: number;
937
- /**
938
- * Attempts to closing a MediaKeySession can fail, most likely because the
939
- * MediaKeySession was not initialized yet.
940
- * When we consider that we're in one of these case, we will retry to close it.
941
- *
942
- * To avoid going into an infinite loop of retry, this number indicates a
943
- * maximum number of attemps we're going to make (`0` meaning no retry at all,
944
- * `1` only one retry and so on).
945
- */
946
- EME_SESSION_CLOSING_MAX_RETRY: number;
947
- /**
948
- * When closing a MediaKeySession failed due to the reasons explained for the
949
- * `EME_SESSION_CLOSING_MAX_RETRY` config property, we may (among other
950
- * triggers) choose to wait a delay raising exponentially at each retry before
951
- * that new attempt.
952
- * This value indicates the initial value for this delay, in milliseconds.
953
- */
954
- EME_SESSION_CLOSING_INITIAL_DELAY: number;
955
- /**
956
- * When closing a MediaKeySession failed due to the reasons explained for the
957
- * `EME_SESSION_CLOSING_MAX_RETRY` config property, we may (among other
958
- * triggers) choose to wait a delay raising exponentially at each retry before
959
- * that new attempt.
960
- * This value indicates the maximum possible value for this delay, in
961
- * milliseconds.
962
- */
963
- EME_SESSION_CLOSING_MAX_DELAY: number;
964
937
  /**
965
938
  * After loading a persistent MediaKeySession, the RxPlayer needs to ensure
966
939
  * that its keys still allow to decrypt a content.
@@ -1092,17 +1065,11 @@ declare const DEFAULT_CONFIG: {
1092
1065
  * there can be in that history.
1093
1066
  */
1094
1067
  BUFFERED_HISTORY_MAXIMUM_ENTRIES: number;
1095
- /**
1096
- * Minimum buffer (in seconds) we should have, regardless of memory
1097
- * constraints
1098
- */
1099
- MIN_BUFFER_LENGTH: number;
1100
1068
  /**
1101
1069
  * Minimum buffer in seconds ahead relative to current time
1102
- * we should be able to download
1103
- * Before trying to agressively free up memory
1070
+ * we should be able to download, even in cases of saturated memory.
1104
1071
  */
1105
- MIN_BUFFER_DISTANCE_BEFORE_CLEAN_UP: number;
1072
+ MIN_BUFFER_AHEAD: number;
1106
1073
  /**
1107
1074
  * Distance in seconds behind the current position
1108
1075
  * the player will free up to in the case we agressively free up memory
@@ -978,33 +978,6 @@ var DEFAULT_CONFIG = {
978
978
  * This wasn't battle-tested however.
979
979
  */
980
980
  EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION: 1000,
981
- /**
982
- * Attempts to closing a MediaKeySession can fail, most likely because the
983
- * MediaKeySession was not initialized yet.
984
- * When we consider that we're in one of these case, we will retry to close it.
985
- *
986
- * To avoid going into an infinite loop of retry, this number indicates a
987
- * maximum number of attemps we're going to make (`0` meaning no retry at all,
988
- * `1` only one retry and so on).
989
- */
990
- EME_SESSION_CLOSING_MAX_RETRY: 5,
991
- /**
992
- * When closing a MediaKeySession failed due to the reasons explained for the
993
- * `EME_SESSION_CLOSING_MAX_RETRY` config property, we may (among other
994
- * triggers) choose to wait a delay raising exponentially at each retry before
995
- * that new attempt.
996
- * This value indicates the initial value for this delay, in milliseconds.
997
- */
998
- EME_SESSION_CLOSING_INITIAL_DELAY: 100,
999
- /**
1000
- * When closing a MediaKeySession failed due to the reasons explained for the
1001
- * `EME_SESSION_CLOSING_MAX_RETRY` config property, we may (among other
1002
- * triggers) choose to wait a delay raising exponentially at each retry before
1003
- * that new attempt.
1004
- * This value indicates the maximum possible value for this delay, in
1005
- * milliseconds.
1006
- */
1007
- EME_SESSION_CLOSING_MAX_DELAY: 1000,
1008
981
  /**
1009
982
  * After loading a persistent MediaKeySession, the RxPlayer needs to ensure
1010
983
  * that its keys still allow to decrypt a content.
@@ -1124,17 +1097,11 @@ var DEFAULT_CONFIG = {
1124
1097
  * there can be in that history.
1125
1098
  */
1126
1099
  BUFFERED_HISTORY_MAXIMUM_ENTRIES: 200,
1127
- /**
1128
- * Minimum buffer (in seconds) we should have, regardless of memory
1129
- * constraints
1130
- */
1131
- MIN_BUFFER_LENGTH: 5,
1132
1100
  /**
1133
1101
  * Minimum buffer in seconds ahead relative to current time
1134
- * we should be able to download
1135
- * Before trying to agressively free up memory
1102
+ * we should be able to download, even in cases of saturated memory.
1136
1103
  */
1137
- MIN_BUFFER_DISTANCE_BEFORE_CLEAN_UP: 10,
1104
+ MIN_BUFFER_AHEAD: 5,
1138
1105
  /**
1139
1106
  * Distance in seconds behind the current position
1140
1107
  * the player will free up to in the case we agressively free up memory
@@ -36,53 +36,54 @@ import inferSegmentContainer from "../utils/infer_segment_container";
36
36
  */
37
37
  export default function addSegmentIntegrityChecks(segmentLoader) {
38
38
  return function (url, content, initialCancelSignal, callbacks) {
39
- return new Promise(function (res, rej) {
40
- var canceller = new TaskCanceller();
41
- var unregisterCancelLstnr = initialCancelSignal
42
- .register(function onCheckCancellation(err) {
43
- canceller.cancel();
44
- rej(err);
45
- });
46
- /**
47
- * If the data's seems to be corrupted, cancel the loading task and reject
48
- * with an `INTEGRITY_ERROR` error.
49
- * @param {*} data
50
- */
51
- function cancelAndRejectOnBadIntegrity(data) {
52
- if (!(data instanceof Array) && !(data instanceof Uint8Array) ||
53
- inferSegmentContainer(content.adaptation.type, content.representation) !== "mp4") {
54
- return;
55
- }
56
- try {
57
- checkISOBMFFIntegrity(new Uint8Array(data), content.segment.isInit);
58
- }
59
- catch (err) {
60
- unregisterCancelLstnr();
61
- canceller.cancel();
62
- rej(err);
63
- }
64
- }
65
- segmentLoader(url, content, canceller.signal, __assign(__assign({}, callbacks), { onNewChunk: function (data) {
66
- cancelAndRejectOnBadIntegrity(data);
67
- if (!canceller.isUsed) {
39
+ return new Promise(function (resolve, reject) {
40
+ var requestCanceller = new TaskCanceller({ cancelOn: initialCancelSignal });
41
+ // Reject the `CancellationError` when `requestCanceller`'s signal emits
42
+ // `stopRejectingOnCancel` here is a function allowing to stop this mechanism
43
+ var stopRejectingOnCancel = requestCanceller.signal.register(reject);
44
+ segmentLoader(url, content, requestCanceller.signal, __assign(__assign({}, callbacks), { onNewChunk: function (data) {
45
+ try {
46
+ trowOnIntegrityError(data);
68
47
  callbacks.onNewChunk(data);
69
48
  }
49
+ catch (err) {
50
+ // Do not reject with a `CancellationError` after cancelling the request
51
+ stopRejectingOnCancel();
52
+ // Cancel the request
53
+ requestCanceller.cancel();
54
+ // Reject with thrown error
55
+ reject(err);
56
+ }
70
57
  } })).then(function (info) {
71
- if (canceller.isUsed) {
58
+ if (requestCanceller.isUsed) {
72
59
  return;
73
60
  }
74
- unregisterCancelLstnr();
61
+ stopRejectingOnCancel();
75
62
  if (info.resultType === "segment-loaded") {
76
- cancelAndRejectOnBadIntegrity(info.resultData.responseData);
63
+ try {
64
+ trowOnIntegrityError(info.resultData.responseData);
65
+ }
66
+ catch (err) {
67
+ reject(err);
68
+ return;
69
+ }
77
70
  }
78
- res(info);
71
+ resolve(info);
79
72
  }, function (error) {
80
- // The segmentLoader's cancellations cases are all handled here
81
- if (!TaskCanceller.isCancellationError(error)) {
82
- unregisterCancelLstnr();
83
- rej(error);
84
- }
73
+ stopRejectingOnCancel();
74
+ reject(error);
85
75
  });
86
76
  });
77
+ /**
78
+ * If the data's seems to be corrupted, throws an `INTEGRITY_ERROR` error.
79
+ * @param {*} data
80
+ */
81
+ function trowOnIntegrityError(data) {
82
+ if (!(data instanceof ArrayBuffer) && !(data instanceof Uint8Array) ||
83
+ inferSegmentContainer(content.adaptation.type, content.representation) !== "mp4") {
84
+ return;
85
+ }
86
+ checkISOBMFFIntegrity(new Uint8Array(data), content.segment.isInit);
87
+ }
87
88
  };
88
89
  }
@@ -14,7 +14,6 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { Observable, } from "rxjs";
17
- import log from "../log";
18
17
  /**
19
18
  * Create an `ISharedReference` object encapsulating the mutable `initialValue`
20
19
  * value of type T.
@@ -61,7 +60,6 @@ export function createSharedReference(initialValue) {
61
60
  throw new Error("Finished shared references cannot be updated");
62
61
  }
63
62
  else {
64
- log.error("Finished shared references cannot be updated");
65
63
  return;
66
64
  }
67
65
  }
@@ -131,8 +131,15 @@ export default class TaskCanceller {
131
131
  * Creates a new `TaskCanceller`, with its own `CancellationSignal` created
132
132
  * as its `signal` provide.
133
133
  * You can then pass this property to async task you wish to be cancellable.
134
+ * @param {Object|undefined} options
134
135
  */
135
- constructor();
136
+ constructor(options?: {
137
+ /**
138
+ * If set the TaskCanceller created here will automatically be triggered
139
+ * when that signal emits.
140
+ */
141
+ cancelOn?: CancellationSignal | undefined;
142
+ } | undefined);
136
143
  /**
137
144
  * "Trigger" the `TaskCanceller`, notify through its associated
138
145
  * `CancellationSignal` (its `signal` property) that a task should be aborted.
@@ -132,12 +132,20 @@ var TaskCanceller = /** @class */ (function () {
132
132
  * Creates a new `TaskCanceller`, with its own `CancellationSignal` created
133
133
  * as its `signal` provide.
134
134
  * You can then pass this property to async task you wish to be cancellable.
135
+ * @param {Object|undefined} options
135
136
  */
136
- function TaskCanceller() {
137
+ function TaskCanceller(options) {
138
+ var _this = this;
137
139
  var _a = createCancellationFunctions(), trigger = _a[0], register = _a[1];
138
140
  this.isUsed = false;
139
141
  this._trigger = trigger;
140
142
  this.signal = new CancellationSignal(register);
143
+ if ((options === null || options === void 0 ? void 0 : options.cancelOn) !== undefined) {
144
+ var unregisterParent = options.cancelOn.register(function () {
145
+ _this.cancel();
146
+ });
147
+ this.signal.register(unregisterParent);
148
+ }
141
149
  }
142
150
  /**
143
151
  * "Trigger" the `TaskCanceller`, notify through its associated