rx-player 3.28.1-dev.2022083000 → 3.29.0-dev.2022090500

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 (139) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/VERSION +1 -1
  3. package/dist/_esm5.processed/compat/event_listeners.d.ts +18 -2
  4. package/dist/_esm5.processed/compat/event_listeners.js +64 -2
  5. package/dist/_esm5.processed/compat/on_height_width_change.d.ts +5 -4
  6. package/dist/_esm5.processed/compat/on_height_width_change.js +43 -34
  7. package/dist/_esm5.processed/core/api/playback_observer.d.ts +12 -2
  8. package/dist/_esm5.processed/core/api/playback_observer.js +27 -12
  9. package/dist/_esm5.processed/core/api/public_api.js +14 -14
  10. package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.d.ts +7 -0
  11. package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.js +10 -2
  12. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.d.ts +8 -1
  13. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.js +10 -4
  14. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher_creator.d.ts +7 -0
  15. package/dist/_esm5.processed/core/init/initialize_directfile.js +1 -1
  16. package/dist/_esm5.processed/core/init/load_on_media_source.js +1 -1
  17. package/dist/_esm5.processed/core/init/stall_avoider.d.ts +4 -2
  18. package/dist/_esm5.processed/core/init/stall_avoider.js +32 -26
  19. package/dist/_esm5.processed/core/segment_buffers/garbage_collector.d.ts +12 -6
  20. package/dist/_esm5.processed/core/segment_buffers/garbage_collector.js +142 -78
  21. package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.d.ts +18 -16
  22. package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +53 -41
  23. package/dist/_esm5.processed/core/segment_buffers/implementations/image/image_segment_buffer.d.ts +6 -5
  24. package/dist/_esm5.processed/core/segment_buffers/implementations/image/image_segment_buffer.js +37 -39
  25. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.d.ts +23 -22
  26. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +84 -72
  27. package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.d.ts +6 -12
  28. package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.js +33 -43
  29. package/dist/_esm5.processed/core/segment_buffers/implementations/types.d.ts +12 -9
  30. package/dist/_esm5.processed/core/segment_buffers/segment_buffers_store.d.ts +7 -6
  31. package/dist/_esm5.processed/core/segment_buffers/segment_buffers_store.js +17 -10
  32. package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +20 -9
  33. package/dist/_esm5.processed/core/stream/period/period_stream.js +25 -14
  34. package/dist/_esm5.processed/core/stream/representation/append_segment_to_buffer.d.ts +4 -7
  35. package/dist/_esm5.processed/core/stream/representation/append_segment_to_buffer.js +80 -23
  36. package/dist/_esm5.processed/core/stream/representation/force_garbage_collection.d.ts +5 -4
  37. package/dist/_esm5.processed/core/stream/representation/force_garbage_collection.js +78 -26
  38. package/dist/_esm5.processed/core/stream/representation/get_buffer_status.js +7 -3
  39. package/dist/_esm5.processed/core/stream/representation/push_init_segment.js +7 -1
  40. package/dist/_esm5.processed/core/stream/representation/push_media_segment.js +7 -1
  41. package/dist/_esm5.processed/core/stream/representation/representation_stream.js +15 -8
  42. package/dist/_esm5.processed/default_config.js +1 -1
  43. package/dist/_esm5.processed/errors/custom_loader_error.d.ts +3 -2
  44. package/dist/_esm5.processed/errors/custom_loader_error.js +3 -2
  45. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/get_initialized_source_buffer.js +5 -2
  46. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/push_data.js +5 -2
  47. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/remove_buffer_around_time.js +9 -2
  48. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/thumbnail_loader.js +3 -1
  49. package/dist/_esm5.processed/experimental/tools/createMetaplaylist/get_duration_from_manifest.js +4 -3
  50. package/dist/_esm5.processed/public_types.d.ts +22 -3
  51. package/dist/_esm5.processed/transports/dash/add_segment_integrity_checks_to_loader.js +2 -2
  52. package/dist/_esm5.processed/transports/dash/image_pipelines.d.ts +3 -2
  53. package/dist/_esm5.processed/transports/dash/image_pipelines.js +3 -1
  54. package/dist/_esm5.processed/transports/dash/init_segment_loader.d.ts +3 -2
  55. package/dist/_esm5.processed/transports/dash/init_segment_loader.js +12 -6
  56. package/dist/_esm5.processed/transports/dash/low_latency_segment_loader.d.ts +3 -2
  57. package/dist/_esm5.processed/transports/dash/low_latency_segment_loader.js +3 -2
  58. package/dist/_esm5.processed/transports/dash/manifest_parser.js +6 -2
  59. package/dist/_esm5.processed/transports/dash/segment_loader.d.ts +3 -2
  60. package/dist/_esm5.processed/transports/dash/segment_loader.js +12 -9
  61. package/dist/_esm5.processed/transports/dash/text_loader.js +6 -3
  62. package/dist/_esm5.processed/transports/local/pipelines.d.ts +2 -2
  63. package/dist/_esm5.processed/transports/local/pipelines.js +6 -6
  64. package/dist/_esm5.processed/transports/local/segment_loader.d.ts +3 -2
  65. package/dist/_esm5.processed/transports/local/segment_loader.js +4 -3
  66. package/dist/_esm5.processed/transports/metaplaylist/manifest_loader.d.ts +2 -2
  67. package/dist/_esm5.processed/transports/metaplaylist/manifest_loader.js +5 -2
  68. package/dist/_esm5.processed/transports/metaplaylist/pipelines.js +15 -10
  69. package/dist/_esm5.processed/transports/smooth/pipelines.d.ts +1 -1
  70. package/dist/_esm5.processed/transports/smooth/pipelines.js +18 -14
  71. package/dist/_esm5.processed/transports/smooth/segment_loader.d.ts +2 -2
  72. package/dist/_esm5.processed/transports/smooth/segment_loader.js +8 -6
  73. package/dist/_esm5.processed/transports/types.d.ts +25 -2
  74. package/dist/_esm5.processed/transports/utils/call_custom_manifest_loader.d.ts +2 -2
  75. package/dist/_esm5.processed/transports/utils/call_custom_manifest_loader.js +3 -3
  76. package/dist/_esm5.processed/transports/utils/generate_manifest_loader.d.ts +2 -2
  77. package/dist/_esm5.processed/transports/utils/generate_manifest_loader.js +9 -6
  78. package/dist/_esm5.processed/utils/request/fetch.js +7 -8
  79. package/dist/_esm5.processed/utils/request/xhr.d.ts +1 -1
  80. package/dist/_esm5.processed/utils/request/xhr.js +28 -14
  81. package/dist/_esm5.processed/utils/task_canceller.d.ts +1 -2
  82. package/dist/_esm5.processed/utils/task_canceller.js +1 -2
  83. package/dist/mpd-parser.wasm +0 -0
  84. package/dist/rx-player.js +1116 -695
  85. package/dist/rx-player.min.js +1 -1
  86. package/package.json +7 -7
  87. package/sonar-project.properties +1 -1
  88. package/src/compat/event_listeners.ts +86 -1
  89. package/src/compat/on_height_width_change.ts +48 -49
  90. package/src/core/api/playback_observer.ts +34 -14
  91. package/src/core/api/public_api.ts +23 -18
  92. package/src/core/fetchers/manifest/manifest_fetcher.ts +20 -2
  93. package/src/core/fetchers/segment/segment_fetcher.ts +23 -3
  94. package/src/core/fetchers/segment/segment_fetcher_creator.ts +7 -0
  95. package/src/core/init/initialize_directfile.ts +1 -1
  96. package/src/core/init/load_on_media_source.ts +1 -0
  97. package/src/core/init/stall_avoider.ts +40 -26
  98. package/src/core/segment_buffers/garbage_collector.ts +55 -47
  99. package/src/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.ts +92 -70
  100. package/src/core/segment_buffers/implementations/image/image_segment_buffer.ts +37 -42
  101. package/src/core/segment_buffers/implementations/text/html/html_text_segment_buffer.ts +103 -105
  102. package/src/core/segment_buffers/implementations/text/native/native_text_segment_buffer.ts +35 -46
  103. package/src/core/segment_buffers/implementations/types.ts +22 -9
  104. package/src/core/segment_buffers/segment_buffers_store.ts +23 -14
  105. package/src/core/stream/orchestrator/stream_orchestrator.ts +31 -12
  106. package/src/core/stream/period/period_stream.ts +31 -18
  107. package/src/core/stream/representation/append_segment_to_buffer.ts +27 -42
  108. package/src/core/stream/representation/force_garbage_collection.ts +28 -32
  109. package/src/core/stream/representation/get_buffer_status.ts +7 -3
  110. package/src/core/stream/representation/push_init_segment.ts +12 -6
  111. package/src/core/stream/representation/push_media_segment.ts +12 -6
  112. package/src/core/stream/representation/representation_stream.ts +11 -5
  113. package/src/default_config.ts +17 -17
  114. package/src/errors/custom_loader_error.ts +3 -2
  115. package/src/experimental/tools/VideoThumbnailLoader/get_initialized_source_buffer.ts +7 -2
  116. package/src/experimental/tools/VideoThumbnailLoader/push_data.ts +6 -2
  117. package/src/experimental/tools/VideoThumbnailLoader/remove_buffer_around_time.ts +10 -2
  118. package/src/experimental/tools/VideoThumbnailLoader/thumbnail_loader.ts +3 -1
  119. package/src/experimental/tools/createMetaplaylist/get_duration_from_manifest.ts +4 -3
  120. package/src/public_types.ts +28 -4
  121. package/src/transports/dash/add_segment_integrity_checks_to_loader.ts +2 -2
  122. package/src/transports/dash/image_pipelines.ts +4 -0
  123. package/src/transports/dash/init_segment_loader.ts +8 -0
  124. package/src/transports/dash/low_latency_segment_loader.ts +4 -0
  125. package/src/transports/dash/manifest_parser.ts +4 -0
  126. package/src/transports/dash/segment_loader.ts +21 -5
  127. package/src/transports/dash/text_loader.ts +7 -2
  128. package/src/transports/local/pipelines.ts +7 -5
  129. package/src/transports/local/segment_loader.ts +4 -2
  130. package/src/transports/metaplaylist/manifest_loader.ts +9 -2
  131. package/src/transports/metaplaylist/pipelines.ts +16 -6
  132. package/src/transports/smooth/pipelines.ts +17 -9
  133. package/src/transports/smooth/segment_loader.ts +8 -0
  134. package/src/transports/types.ts +27 -0
  135. package/src/transports/utils/call_custom_manifest_loader.ts +8 -2
  136. package/src/transports/utils/generate_manifest_loader.ts +18 -5
  137. package/src/utils/request/fetch.ts +7 -8
  138. package/src/utils/request/xhr.ts +31 -15
  139. package/src/utils/task_canceller.ts +1 -2
package/CHANGELOG.md CHANGED
@@ -1,9 +1,19 @@
1
1
  # Changelog
2
2
 
3
- ## v3.28.1-dev.2022083000 (2022-08-30)
3
+ ## v3.29.0-dev.2022090500 (2022-09-05)
4
+
5
+ ### Features
6
+
7
+ - add `networkConfig.segmentRequestTimeout` and `networkConfig.manifestRequestTimeout` options to loadVideo to configure the timeout of respectively segment and manifest requests [#1156]
8
+ - add `timeout` property to the first argument communicated to a `segmentLoader` (from `loadVideo`'s `transportOptions`) [#1156]
9
+ - add `timeout` property to a new third argument communicated to a `manifestLoader` (from `loadVideo`'s `transportOptions`) [#1156]
4
10
 
5
11
  ### Bug fixes
6
12
 
13
+ - Compat/Directfile: Fix an issue with LG TV when playing multiple directfile contents with the `stopAtEnd` player option set to `true` [#1154]
14
+ - Compat: To work around an issue on LG TVs, also specify a request timeout manually through a `setTimeout` call when XMLHttpRequests are created for Manifest and segment requests [#1152]
15
+ - Compat: Fix issue with Samsung TVs where starting playback on a discontinuity could lead to infinite rebuffering [#1140]
16
+ - Better handle valid reverse playback use cases by not skipping gaps when the playback rate has been set to `0` or a negative value [#1138]
7
17
  - DRM: When using persistent licenses, create new MediaKeySession when `load` resolves with `false`, instead of relying the same, to fix issues with such persistent sessions [#1139]
8
18
 
9
19
  ### Other improvements
package/VERSION CHANGED
@@ -1 +1 @@
1
- 3.28.1-dev.2022083000
1
+ 3.29.0-dev.2022090500
@@ -42,7 +42,8 @@ export interface IPictureInPictureEvent {
42
42
  }
43
43
  /**
44
44
  * Emit when video enters and leaves Picture-In-Picture mode.
45
- * @param {HTMLMediaElement} mediaElement
45
+ * @param {HTMLMediaElement} elt
46
+ * @param {Object} stopListening
46
47
  * @returns {Observable}
47
48
  */
48
49
  declare function getPictureOnPictureStateRef(elt: HTMLMediaElement, stopListening: CancellationSignal): IReadOnlySharedReference<IPictureInPictureEvent>;
@@ -151,6 +152,21 @@ declare const onKeyError$: (element: IEventTargetLike) => Observable<Event>;
151
152
  * @returns {Observable}
152
153
  */
153
154
  declare const onKeyStatusesChange$: (element: IEventTargetLike) => Observable<Event>;
155
+ /**
156
+ * @param {HTMLMediaElement} mediaElement
157
+ * @returns {Observable}
158
+ */
159
+ declare const onSeeking: (element: IEventTargetLike, listener: (event?: unknown) => void, cancelSignal: CancellationSignal) => void;
160
+ /**
161
+ * @param {HTMLMediaElement} mediaElement
162
+ * @returns {Observable}
163
+ */
164
+ declare const onSeeked: (element: IEventTargetLike, listener: (event?: unknown) => void, cancelSignal: CancellationSignal) => void;
165
+ /**
166
+ * @param {HTMLMediaElement} mediaElement
167
+ * @returns {Observable}
168
+ */
169
+ declare const onEnded: (element: IEventTargetLike, listener: (event?: unknown) => void, cancelSignal: CancellationSignal) => void;
154
170
  /**
155
171
  * Utilitary function allowing to add an event listener and remove it
156
172
  * automatically once the given `CancellationSignal` emits.
@@ -162,4 +178,4 @@ declare const onKeyStatusesChange$: (element: IEventTargetLike) => Observable<Ev
162
178
  * emits
163
179
  */
164
180
  declare function addEventListener(elt: IEventEmitterLike, evt: string, listener: (x?: unknown) => void, stopListening: CancellationSignal): void;
165
- export { addEventListener, getPageActivityRef, getPictureOnPictureStateRef, getVideoVisibilityRef, getVideoWidthRef, onEncrypted$, onEnded$, onFullscreenChange$, onKeyAdded$, onKeyError$, onKeyMessage$, onKeyStatusesChange$, onLoadedMetadata$, onRemoveSourceBuffers$, onSeeked$, onSeeking$, onSourceClose$, onSourceEnded$, onSourceOpen$, onTextTrackChanges$, onTimeUpdate$, onUpdate$, };
181
+ export { addEventListener, getPageActivityRef, getPictureOnPictureStateRef, getVideoVisibilityRef, getVideoWidthRef, onEncrypted$, onEnded, onEnded$, onFullscreenChange$, onKeyAdded$, onKeyError$, onKeyMessage$, onKeyStatusesChange$, onLoadedMetadata$, onRemoveSourceBuffers$, onSeeked, onSeeked$, onSeeking, onSeeking$, onSourceClose$, onSourceEnded$, onSourceOpen$, onTextTrackChanges$, onTimeUpdate$, onUpdate$, };
@@ -70,6 +70,52 @@ function eventPrefixed(eventNames, prefixes) {
70
70
  .map(function (p) { return p + name; }));
71
71
  }, []);
72
72
  }
73
+ /**
74
+ * Returns a function allowing to add event listeners for particular event(s)
75
+ * optionally automatically adding browser prefixes if needed.
76
+ * @param {Array.<string>} eventNames - The event(s) to listen to. If multiple
77
+ * events are set, the event listener will be triggered when any of them emits.
78
+ * @returns {Function} - Returns function allowing to easily add a callback to
79
+ * be triggered when that event is emitted on a given event target.
80
+ */
81
+ function createCompatibleEventListener(eventNames) {
82
+ var mem;
83
+ var prefixedEvents = eventPrefixed(eventNames);
84
+ return function (element, listener, cancelSignal) {
85
+ if (cancelSignal.isCancelled) {
86
+ return;
87
+ }
88
+ // if the element is a HTMLElement we can detect
89
+ // the supported event, and memoize it in `mem`
90
+ if (element instanceof HTMLElement) {
91
+ if (typeof mem === "undefined") {
92
+ mem = findSupportedEvent(element, prefixedEvents);
93
+ }
94
+ if (isNonEmptyString(mem)) {
95
+ element.addEventListener(mem, listener);
96
+ cancelSignal.register(function () {
97
+ if (mem !== undefined) {
98
+ element.removeEventListener(mem, listener);
99
+ }
100
+ });
101
+ }
102
+ else {
103
+ if (0 /* __ENVIRONMENT__.CURRENT_ENV */ === 1 /* __ENVIRONMENT__.DEV */) {
104
+ log.warn("compat: element ".concat(element.tagName) +
105
+ " does not support any of these events: " +
106
+ prefixedEvents.join(", "));
107
+ }
108
+ return;
109
+ }
110
+ }
111
+ prefixedEvents.forEach(function (eventName) {
112
+ element.addEventListener(eventName, listener);
113
+ cancelSignal.register(function () {
114
+ element.removeEventListener(eventName, listener);
115
+ });
116
+ });
117
+ };
118
+ }
73
119
  /**
74
120
  * @param {Array.<string>} eventNames
75
121
  * @param {Array.<string>|undefined} prefixes
@@ -186,7 +232,8 @@ function getVideoWidthFromPIPWindow(mediaElement, pipWindow) {
186
232
  }
187
233
  /**
188
234
  * Emit when video enters and leaves Picture-In-Picture mode.
189
- * @param {HTMLMediaElement} mediaElement
235
+ * @param {HTMLMediaElement} elt
236
+ * @param {Object} stopListening
190
237
  * @returns {Observable}
191
238
  */
192
239
  function getPictureOnPictureStateRef(elt, stopListening) {
@@ -397,6 +444,21 @@ var onKeyError$ = compatibleListener(["keyerror", "error"]);
397
444
  * @returns {Observable}
398
445
  */
399
446
  var onKeyStatusesChange$ = compatibleListener(["keystatuseschange"]);
447
+ /**
448
+ * @param {HTMLMediaElement} mediaElement
449
+ * @returns {Observable}
450
+ */
451
+ var onSeeking = createCompatibleEventListener(["seeking"]);
452
+ /**
453
+ * @param {HTMLMediaElement} mediaElement
454
+ * @returns {Observable}
455
+ */
456
+ var onSeeked = createCompatibleEventListener(["seeked"]);
457
+ /**
458
+ * @param {HTMLMediaElement} mediaElement
459
+ * @returns {Observable}
460
+ */
461
+ var onEnded = createCompatibleEventListener(["ended"]);
400
462
  /**
401
463
  * Utilitary function allowing to add an event listener and remove it
402
464
  * automatically once the given `CancellationSignal` emits.
@@ -413,4 +475,4 @@ function addEventListener(elt, evt, listener, stopListening) {
413
475
  elt.removeEventListener(evt, listener);
414
476
  });
415
477
  }
416
- export { addEventListener, getPageActivityRef, getPictureOnPictureStateRef, getVideoVisibilityRef, getVideoWidthRef, onEncrypted$, onEnded$, onFullscreenChange$, onKeyAdded$, onKeyError$, onKeyMessage$, onKeyStatusesChange$, onLoadedMetadata$, onRemoveSourceBuffers$, onSeeked$, onSeeking$, onSourceClose$, onSourceEnded$, onSourceOpen$, onTextTrackChanges$, onTimeUpdate$, onUpdate$, };
478
+ export { addEventListener, getPageActivityRef, getPictureOnPictureStateRef, getVideoVisibilityRef, getVideoWidthRef, onEncrypted$, onEnded, onEnded$, onFullscreenChange$, onKeyAdded$, onKeyError$, onKeyMessage$, onKeyStatusesChange$, onLoadedMetadata$, onRemoveSourceBuffers$, onSeeked, onSeeked$, onSeeking, onSeeking$, onSourceClose$, onSourceEnded$, onSourceOpen$, onTextTrackChanges$, onTimeUpdate$, onUpdate$, };
@@ -13,14 +13,15 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { Observable } from "rxjs";
16
+ import { IReadOnlySharedReference } from "../utils/reference";
17
+ import { CancellationSignal } from "../utils/task_canceller";
17
18
  export interface IResolution {
18
19
  width: number;
19
20
  height: number;
20
21
  }
21
22
  /**
22
- * Emit the current height and width of the given `element` on subscribtion
23
- * and each time it changes.
23
+ * Emit the current height and width of the given `element` each time it
24
+ * changes.
24
25
  *
25
26
  * On some browsers, we might not be able to rely on a native API to know when
26
27
  * it changes, the `interval` argument allow us to provide us an inverval in
@@ -29,4 +30,4 @@ export interface IResolution {
29
30
  * @param {number} interval
30
31
  * @returns {Observable}
31
32
  */
32
- export default function onHeightWidthChange(element: HTMLElement, interval: number): Observable<IResolution>;
33
+ export default function onHeightWidthChange(element: HTMLElement, interval: number, cancellationSignal: CancellationSignal): IReadOnlySharedReference<IResolution>;
@@ -13,8 +13,8 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { defer as observableDefer, distinctUntilChanged, interval as observableInterval, map, Observable, startWith, } from "rxjs";
17
16
  import log from "../log";
17
+ import createSharedReference from "../utils/reference";
18
18
  import isNode from "./is_node";
19
19
  /* eslint-disable @typescript-eslint/no-unsafe-member-access */
20
20
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
@@ -23,8 +23,8 @@ var _ResizeObserver = isNode ? undefined :
23
23
  /* eslint-enable @typescript-eslint/no-unsafe-member-access */
24
24
  /* eslint-enable @typescript-eslint/no-unsafe-assignment */
25
25
  /**
26
- * Emit the current height and width of the given `element` on subscribtion
27
- * and each time it changes.
26
+ * Emit the current height and width of the given `element` each time it
27
+ * changes.
28
28
  *
29
29
  * On some browsers, we might not be able to rely on a native API to know when
30
30
  * it changes, the `interval` argument allow us to provide us an inverval in
@@ -33,36 +33,45 @@ var _ResizeObserver = isNode ? undefined :
33
33
  * @param {number} interval
34
34
  * @returns {Observable}
35
35
  */
36
- export default function onHeightWidthChange(element, interval) {
37
- return observableDefer(function () {
38
- if (_ResizeObserver !== undefined) {
39
- var lastHeight_1 = -1;
40
- var lastWidth_1 = -1;
41
- return new Observable(function (obs) {
42
- var resizeObserver = new _ResizeObserver(function (entries) {
43
- if (entries.length === 0) {
44
- log.error("Compat: Resized but no observed element.");
45
- return;
46
- }
47
- var entry = entries[0];
48
- var _a = entry.contentRect, height = _a.height, width = _a.width;
49
- if (height !== lastHeight_1 || width !== lastWidth_1) {
50
- lastHeight_1 = height;
51
- lastWidth_1 = width;
52
- obs.next({ height: height, width: width });
53
- }
54
- });
55
- resizeObserver.observe(element);
56
- return function () {
57
- resizeObserver.disconnect();
58
- };
59
- });
60
- }
61
- return observableInterval(interval).pipe(startWith(null), map(function () {
62
- var _a = element.getBoundingClientRect(), height = _a.height, width = _a.width;
63
- return { height: height, width: width };
64
- }), distinctUntilChanged(function (o, n) {
65
- return o.height === n.height && o.width === n.width;
66
- }));
36
+ export default function onHeightWidthChange(element, interval, cancellationSignal) {
37
+ var _a = element.getBoundingClientRect(), initHeight = _a.height, initWidth = _a.width;
38
+ var ref = createSharedReference({
39
+ height: initHeight,
40
+ width: initWidth,
67
41
  });
42
+ var lastHeight = initHeight;
43
+ var lastWidth = initWidth;
44
+ if (_ResizeObserver !== undefined) {
45
+ var resizeObserver_1 = new _ResizeObserver(function (entries) {
46
+ if (entries.length === 0) {
47
+ log.error("Compat: Resized but no observed element.");
48
+ return;
49
+ }
50
+ var entry = entries[0];
51
+ var _a = entry.contentRect, height = _a.height, width = _a.width;
52
+ if (height !== lastHeight || width !== lastWidth) {
53
+ lastHeight = height;
54
+ lastWidth = width;
55
+ ref.setValue({ height: height, width: width });
56
+ }
57
+ });
58
+ resizeObserver_1.observe(element);
59
+ cancellationSignal.register(function () {
60
+ resizeObserver_1.disconnect();
61
+ });
62
+ }
63
+ else {
64
+ var intervalId_1 = setInterval(function () {
65
+ var _a = element.getBoundingClientRect(), height = _a.height, width = _a.width;
66
+ if (height !== lastHeight || width !== lastWidth) {
67
+ lastHeight = height;
68
+ lastWidth = width;
69
+ ref.setValue({ height: height, width: width });
70
+ }
71
+ }, interval);
72
+ cancellationSignal.register(function () {
73
+ clearInterval(intervalId_1);
74
+ });
75
+ }
76
+ return ref;
68
77
  }
@@ -54,7 +54,7 @@ export default class PlaybackObserver {
54
54
  * This allows us to correctly characterize seeking events: if the counter is
55
55
  * superior to `0`, it is probably due to an internal "seek".
56
56
  */
57
- private _internalSeekingEventsIncomingCounter;
57
+ private _internalSeeksIncoming;
58
58
  /**
59
59
  * Stores the last playback observation produced by the `PlaybackObserver`.:
60
60
  */
@@ -92,6 +92,11 @@ export default class PlaybackObserver {
92
92
  * @returns {number}
93
93
  */
94
94
  getCurrentTime(): number;
95
+ /**
96
+ * Returns the current playback rate advertised by the `HTMLMediaElement`.
97
+ * @returns {number}
98
+ */
99
+ getPlaybackRate(): number;
95
100
  /**
96
101
  * Returns the current `paused` status advertised by the `HTMLMediaElement`.
97
102
  *
@@ -272,7 +277,7 @@ export interface IPlaybackObservation extends IMediaInfos {
272
277
  * If `true`, an "internal seek" (a seeking operation triggered by the
273
278
  * RxPlayer code) is currently pending.
274
279
  */
275
- internalSeeking: boolean;
280
+ pendingInternalSeek: number | null;
276
281
  }
277
282
  /**
278
283
  * Interface providing a generic and read-only version of a `PlaybackObserver`.
@@ -289,6 +294,11 @@ export interface IPlaybackObservation extends IMediaInfos {
289
294
  export interface IReadOnlyPlaybackObserver<TObservationType> {
290
295
  /** Get the current playing position, in seconds. */
291
296
  getCurrentTime(): number;
297
+ /**
298
+ * Returns the current playback rate advertised by the `HTMLMediaElement`.
299
+ * @returns {number}
300
+ */
301
+ getPlaybackRate(): number;
292
302
  /** Get the HTMLMediaElement's current `readyState`. */
293
303
  getReadyState(): number;
294
304
  /**
@@ -58,7 +58,7 @@ var PlaybackObserver = /** @class */ (function () {
58
58
  * @param {Object} options
59
59
  */
60
60
  function PlaybackObserver(mediaElement, options) {
61
- this._internalSeekingEventsIncomingCounter = 0;
61
+ this._internalSeeksIncoming = [];
62
62
  this._mediaElement = mediaElement;
63
63
  this._withMediaSource = options.withMediaSource;
64
64
  this._lowLatencyMode = options.lowLatencyMode;
@@ -86,6 +86,13 @@ var PlaybackObserver = /** @class */ (function () {
86
86
  PlaybackObserver.prototype.getCurrentTime = function () {
87
87
  return this._mediaElement.currentTime;
88
88
  };
89
+ /**
90
+ * Returns the current playback rate advertised by the `HTMLMediaElement`.
91
+ * @returns {number}
92
+ */
93
+ PlaybackObserver.prototype.getPlaybackRate = function () {
94
+ return this._mediaElement.playbackRate;
95
+ };
89
96
  /**
90
97
  * Returns the current `paused` status advertised by the `HTMLMediaElement`.
91
98
  *
@@ -107,7 +114,7 @@ var PlaybackObserver = /** @class */ (function () {
107
114
  * @param {number} time
108
115
  */
109
116
  PlaybackObserver.prototype.setCurrentTime = function (time) {
110
- this._internalSeekingEventsIncomingCounter += 1;
117
+ this._internalSeeksIncoming.push(time);
111
118
  this._mediaElement.currentTime = time;
112
119
  };
113
120
  /**
@@ -180,24 +187,29 @@ var PlaybackObserver = /** @class */ (function () {
180
187
  var _a = config.getCurrent(), SAMPLING_INTERVAL_MEDIASOURCE = _a.SAMPLING_INTERVAL_MEDIASOURCE, SAMPLING_INTERVAL_LOW_LATENCY = _a.SAMPLING_INTERVAL_LOW_LATENCY, SAMPLING_INTERVAL_NO_MEDIASOURCE = _a.SAMPLING_INTERVAL_NO_MEDIASOURCE;
181
188
  var getCurrentObservation = function (event) {
182
189
  var tmpEvt = event;
183
- if (tmpEvt === "seeking" && _this._internalSeekingEventsIncomingCounter > 0) {
190
+ var startedInternalSeekTime;
191
+ if (tmpEvt === "seeking" && _this._internalSeeksIncoming.length > 0) {
184
192
  tmpEvt = "internal-seeking";
185
- _this._internalSeekingEventsIncomingCounter -= 1;
193
+ startedInternalSeekTime = _this._internalSeeksIncoming.shift();
186
194
  }
187
195
  var _lastObservation = lastObservation !== null && lastObservation !== void 0 ? lastObservation : _this._generateInitialObservation();
188
196
  var mediaTimings = getMediaInfos(_this._mediaElement, tmpEvt);
189
- var internalSeeking = mediaTimings.seeking &&
190
- // We've just received the event for internally seeking
191
- (tmpEvt === "internal-seeking" ||
192
- // or We're still waiting on the previous internal-seek
193
- (_lastObservation.internalSeeking && tmpEvt !== "seeking"));
197
+ var pendingInternalSeek = null;
198
+ if (mediaTimings.seeking) {
199
+ if (typeof startedInternalSeekTime === "number") {
200
+ pendingInternalSeek = startedInternalSeekTime;
201
+ }
202
+ else if (_lastObservation.pendingInternalSeek !== null && event !== "seeking") {
203
+ pendingInternalSeek = _lastObservation.pendingInternalSeek;
204
+ }
205
+ }
194
206
  var rebufferingStatus = getRebufferingStatus(_lastObservation, mediaTimings, { lowLatencyMode: _this._lowLatencyMode,
195
207
  withMediaSource: _this._withMediaSource });
196
208
  var freezingStatus = getFreezingStatus(_lastObservation, mediaTimings);
197
209
  var timings = objectAssign({}, { rebuffering: rebufferingStatus,
198
- freezing: freezingStatus, internalSeeking: internalSeeking }, mediaTimings);
210
+ freezing: freezingStatus, pendingInternalSeek: pendingInternalSeek }, mediaTimings);
199
211
  if (log.hasLevel("DEBUG")) {
200
- log.debug("API: current media element state tick", "event", timings.event, "position", timings.position, "seeking", timings.seeking, "internalSeeking", timings.internalSeeking, "rebuffering", timings.rebuffering !== null, "freezing", timings.freezing !== null, "ended", timings.ended, "paused", timings.paused, "playbackRate", timings.playbackRate, "readyState", timings.readyState);
212
+ log.debug("API: current media element state tick", "event", timings.event, "position", timings.position, "seeking", timings.seeking, "internalSeek", timings.pendingInternalSeek, "rebuffering", timings.rebuffering !== null, "freezing", timings.freezing !== null, "ended", timings.ended, "paused", timings.paused, "playbackRate", timings.playbackRate, "readyState", timings.readyState);
201
213
  }
202
214
  return timings;
203
215
  };
@@ -242,7 +254,7 @@ var PlaybackObserver = /** @class */ (function () {
242
254
  PlaybackObserver.prototype._generateInitialObservation = function () {
243
255
  return objectAssign(getMediaInfos(this._mediaElement, "init"), { rebuffering: null,
244
256
  freezing: null,
245
- internalSeeking: false });
257
+ pendingInternalSeek: null });
246
258
  };
247
259
  return PlaybackObserver;
248
260
  }());
@@ -504,6 +516,9 @@ function generateReadOnlyObserver(src, transform, cancellationSignal) {
504
516
  getReadyState: function () {
505
517
  return src.getReadyState();
506
518
  },
519
+ getPlaybackRate: function () {
520
+ return src.getPlaybackRate();
521
+ },
507
522
  getIsPaused: function () {
508
523
  return src.getIsPaused();
509
524
  },
@@ -88,7 +88,7 @@ var Player = /** @class */ (function (_super) {
88
88
  // Workaround to support Firefox autoplay on FF 42.
89
89
  // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1194624
90
90
  videoElement.preload = "auto";
91
- _this.version = /* PLAYER_VERSION */ "3.28.1-dev.2022083000";
91
+ _this.version = /* PLAYER_VERSION */ "3.29.0-dev.2022090500";
92
92
  _this.log = log;
93
93
  _this.state = "STOPPED";
94
94
  _this.videoElement = videoElement;
@@ -373,13 +373,15 @@ var Player = /** @class */ (function (_super) {
373
373
  throw new Error("transport \"".concat(transport, "\" not supported"));
374
374
  }
375
375
  var transportPipelines = transportFn(transportOptions);
376
- var offlineRetry = networkConfig.offlineRetry, segmentRetry = networkConfig.segmentRetry, manifestRetry = networkConfig.manifestRetry;
376
+ var offlineRetry = networkConfig.offlineRetry, segmentRetry = networkConfig.segmentRetry, manifestRetry = networkConfig.manifestRetry, manifestRequestTimeout = networkConfig.manifestRequestTimeout, segmentRequestTimeout = networkConfig.segmentRequestTimeout;
377
377
  /** Interface used to load and refresh the Manifest. */
378
378
  var manifestFetcher = new ManifestFetcher(url, transportPipelines, { lowLatencyMode: lowLatencyMode, maxRetryRegular: manifestRetry,
379
- maxRetryOffline: offlineRetry });
379
+ maxRetryOffline: offlineRetry,
380
+ requestTimeout: manifestRequestTimeout });
380
381
  /** Interface used to download segments. */
381
382
  var segmentFetcherCreator = new SegmentFetcherCreator(transportPipelines, { lowLatencyMode: lowLatencyMode, maxRetryOffline: offlineRetry,
382
- maxRetryRegular: segmentRetry });
383
+ maxRetryRegular: segmentRetry,
384
+ requestTimeout: segmentRequestTimeout });
383
385
  /** Observable emitting the initial Manifest */
384
386
  var manifest$ = void 0;
385
387
  if (initialManifest instanceof Manifest) {
@@ -587,15 +589,13 @@ var Player = /** @class */ (function (_super) {
587
589
  // Handle state updates
588
590
  playerState$
589
591
  .pipe(takeUntil(stoppedContent$))
590
- .subscribe(function (x) { return _this._priv_setPlayerState(x); });
591
- var endedEvent$ = observation$.pipe(filter(function (o) {
592
- return o.event === "ended";
593
- }));
594
- (this._priv_stopAtEnd ? endedEvent$ :
595
- EMPTY)
596
- .pipe(takeUntil(stoppedContent$))
597
- .subscribe(function () {
598
- currentContentCanceller.cancel();
592
+ .subscribe(function (newState) {
593
+ _this._priv_setPlayerState(newState);
594
+ // Previous call could have performed all kind of side-effects, thus,
595
+ // we re-check the current state associated to the RxPlayer
596
+ if (_this.state === "ENDED" && _this._priv_stopAtEnd) {
597
+ currentContentCanceller.cancel();
598
+ }
599
599
  });
600
600
  // Link playback events to the corresponding callbacks
601
601
  playback$.subscribe({
@@ -2295,5 +2295,5 @@ var Player = /** @class */ (function (_super) {
2295
2295
  };
2296
2296
  return Player;
2297
2297
  }(EventEmitter));
2298
- Player.version = /* PLAYER_VERSION */ "3.28.1-dev.2022083000";
2298
+ Player.version = /* PLAYER_VERSION */ "3.29.0-dev.2022090500";
2299
2299
  export default Player;
@@ -74,6 +74,13 @@ export interface IManifestFetcherSettings {
74
74
  maxRetryRegular: number | undefined;
75
75
  /** Maximum number of time a request be retried when the user is offline. */
76
76
  maxRetryOffline: number | undefined;
77
+ /**
78
+ * Timeout after which request are aborted and, depending on other options,
79
+ * retried.
80
+ * To set to `-1` for no timeout.
81
+ * `undefined` will lead to a default, large, timeout being used.
82
+ */
83
+ requestTimeout: number | undefined;
77
84
  }
78
85
  /**
79
86
  * Class allowing to facilitate the task of loading and parsing a Manifest.
@@ -54,6 +54,7 @@ import config from "../../../config";
54
54
  import { formatError } from "../../../errors";
55
55
  import log from "../../../log";
56
56
  import assert from "../../../utils/assert";
57
+ import isNullOrUndefined from "../../../utils/is_null_or_undefined";
57
58
  import TaskCanceller from "../../../utils/task_canceller";
58
59
  import errorSelector from "../utils/error_selector";
59
60
  import { tryRequestPromiseWithBackoff, } from "../utils/try_urls_with_backoff";
@@ -106,6 +107,7 @@ var ManifestFetcher = /** @class */ (function () {
106
107
  ManifestFetcher.prototype.fetch = function (url) {
107
108
  var _this = this;
108
109
  return new Observable(function (obs) {
110
+ var settings = _this._settings;
109
111
  var pipelines = _this._pipelines;
110
112
  var requestUrl = url !== null && url !== void 0 ? url : _this._manifestUrl;
111
113
  /** `true` if the loading pipeline is already completely executed. */
@@ -160,12 +162,18 @@ var ManifestFetcher = /** @class */ (function () {
160
162
  * Call the loader part of the pipeline, retrying if it fails according
161
163
  * to the current settings.
162
164
  * Returns the Promise of the last attempt.
163
- * @param {string | undefined} resolverUrl
165
+ * @param {string | undefined} manifestUrl
164
166
  * @returns {Promise}
165
167
  */
166
168
  function callLoaderWithRetries(manifestUrl) {
167
169
  var loadManifest = pipelines.loadManifest;
168
- var callLoader = function () { return loadManifest(manifestUrl, canceller.signal); };
170
+ var requestTimeout = isNullOrUndefined(settings.requestTimeout) ?
171
+ config.getCurrent().DEFAULT_REQUEST_TIMEOUT :
172
+ settings.requestTimeout;
173
+ if (requestTimeout < 0) {
174
+ requestTimeout = undefined;
175
+ }
176
+ var callLoader = function () { return loadManifest(manifestUrl, { timeout: requestTimeout }, canceller.signal); };
169
177
  return tryRequestPromiseWithBackoff(callLoader, backoffSettings, canceller.signal);
170
178
  }
171
179
  });
@@ -123,14 +123,21 @@ export interface ISegmentFetcherOptions {
123
123
  * currently offline.
124
124
  */
125
125
  maxRetryOffline: number;
126
+ /**
127
+ * Timeout after which request are aborted and, depending on other options,
128
+ * retried.
129
+ * To set to `-1` for no timeout.
130
+ */
131
+ requestTimeout: number;
126
132
  }
127
133
  /**
128
134
  * @param {string} bufferType
129
135
  * @param {Object}
130
136
  * @returns {Object}
131
137
  */
132
- export declare function getSegmentFetcherOptions(bufferType: string, { maxRetryRegular, maxRetryOffline, lowLatencyMode }: {
138
+ export declare function getSegmentFetcherOptions(bufferType: string, { maxRetryRegular, maxRetryOffline, lowLatencyMode, requestTimeout }: {
133
139
  maxRetryRegular?: number | undefined;
134
140
  maxRetryOffline?: number | undefined;
141
+ requestTimeout?: number | undefined;
135
142
  lowLatencyMode: boolean;
136
143
  }): ISegmentFetcherOptions;
@@ -40,6 +40,10 @@ var generateRequestID = idGenerator();
40
40
  * @returns {Function}
41
41
  */
42
42
  export default function createSegmentFetcher(bufferType, pipeline, callbacks, options) {
43
+ var requestOptions = {
44
+ timeout: options.requestTimeout < 0 ? undefined :
45
+ options.requestTimeout,
46
+ };
43
47
  /**
44
48
  * Cache audio and video initialization segments.
45
49
  * This allows to avoid doing too many requests for what are usually very
@@ -203,7 +207,7 @@ export default function createSegmentFetcher(bufferType, pipeline, callbacks, op
203
207
  * @returns {Promise}
204
208
  */
205
209
  function callLoaderWithUrl(url, cancellationSignal) {
206
- return loadSegment(url, content, cancellationSignal, loaderCallbacks);
210
+ return loadSegment(url, content, requestOptions, cancellationSignal, loaderCallbacks);
207
211
  }
208
212
  /**
209
213
  * Generate function allowing to parse a loaded segment.
@@ -272,13 +276,15 @@ export default function createSegmentFetcher(bufferType, pipeline, callbacks, op
272
276
  * @returns {Object}
273
277
  */
274
278
  export function getSegmentFetcherOptions(bufferType, _a) {
275
- var maxRetryRegular = _a.maxRetryRegular, maxRetryOffline = _a.maxRetryOffline, lowLatencyMode = _a.lowLatencyMode;
276
- var _b = config.getCurrent(), DEFAULT_MAX_REQUESTS_RETRY_ON_ERROR = _b.DEFAULT_MAX_REQUESTS_RETRY_ON_ERROR, DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE = _b.DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE, INITIAL_BACKOFF_DELAY_BASE = _b.INITIAL_BACKOFF_DELAY_BASE, MAX_BACKOFF_DELAY_BASE = _b.MAX_BACKOFF_DELAY_BASE;
279
+ var maxRetryRegular = _a.maxRetryRegular, maxRetryOffline = _a.maxRetryOffline, lowLatencyMode = _a.lowLatencyMode, requestTimeout = _a.requestTimeout;
280
+ var _b = config.getCurrent(), DEFAULT_MAX_REQUESTS_RETRY_ON_ERROR = _b.DEFAULT_MAX_REQUESTS_RETRY_ON_ERROR, DEFAULT_REQUEST_TIMEOUT = _b.DEFAULT_REQUEST_TIMEOUT, DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE = _b.DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE, INITIAL_BACKOFF_DELAY_BASE = _b.INITIAL_BACKOFF_DELAY_BASE, MAX_BACKOFF_DELAY_BASE = _b.MAX_BACKOFF_DELAY_BASE;
277
281
  return { maxRetryRegular: bufferType === "image" ? 0 :
278
282
  maxRetryRegular !== null && maxRetryRegular !== void 0 ? maxRetryRegular : DEFAULT_MAX_REQUESTS_RETRY_ON_ERROR,
279
283
  maxRetryOffline: maxRetryOffline !== null && maxRetryOffline !== void 0 ? maxRetryOffline : DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE,
280
284
  baseDelay: lowLatencyMode ? INITIAL_BACKOFF_DELAY_BASE.LOW_LATENCY :
281
285
  INITIAL_BACKOFF_DELAY_BASE.REGULAR,
282
286
  maxDelay: lowLatencyMode ? MAX_BACKOFF_DELAY_BASE.LOW_LATENCY :
283
- MAX_BACKOFF_DELAY_BASE.REGULAR };
287
+ MAX_BACKOFF_DELAY_BASE.REGULAR,
288
+ requestTimeout: isNullOrUndefined(requestTimeout) ? DEFAULT_REQUEST_TIMEOUT :
289
+ requestTimeout };
284
290
  }
@@ -91,4 +91,11 @@ export interface ISegmentFetcherCreatorBackoffOptions {
91
91
  maxRetryRegular: number | undefined;
92
92
  /** Maximum number of time a request be retried when the user is offline. */
93
93
  maxRetryOffline: number | undefined;
94
+ /**
95
+ * Timeout after which request are aborted and, depending on other options,
96
+ * retried.
97
+ * To set to `-1` for no timeout.
98
+ * `undefined` will lead to a default, large, timeout being used.
99
+ */
100
+ requestTimeout: number | undefined;
94
101
  }
@@ -108,7 +108,7 @@ export default function initializeDirectfileContent(_a) {
108
108
  * Observable trying to avoid various stalling situations, emitting "stalled"
109
109
  * events when it cannot, as well as "unstalled" events when it get out of one.
110
110
  */
111
- var stallAvoider$ = StallAvoider(playbackObserver, null, EMPTY, EMPTY);
111
+ var stallAvoider$ = StallAvoider(playbackObserver, null, speed, EMPTY, EMPTY);
112
112
  /**
113
113
  * Emit a "loaded" events once the initial play has been performed and the
114
114
  * media can begin playback.
@@ -106,7 +106,7 @@ export default function createMediaSourceLoader(_a) {
106
106
  * Observable trying to avoid various stalling situations, emitting "stalled"
107
107
  * events when it cannot, as well as "unstalled" events when it get out of one.
108
108
  */
109
- var stallAvoider$ = StallAvoider(playbackObserver, manifest, lockedStream$, discontinuityUpdate$);
109
+ var stallAvoider$ = StallAvoider(playbackObserver, manifest, speed, lockedStream$, discontinuityUpdate$);
110
110
  /**
111
111
  * Emit a "loaded" events once the initial play has been performed and the
112
112
  * media can begin playback.
@@ -15,6 +15,7 @@
15
15
  */
16
16
  import { Observable } from "rxjs";
17
17
  import Manifest, { Period } from "../../manifest";
18
+ import { IReadOnlySharedReference } from "../../utils/reference";
18
19
  import { PlaybackObserver } from "../api";
19
20
  import { IBufferType } from "../segment_buffers";
20
21
  import { IStalledEvent, IUnstalledEvent, IWarningEvent } from "./types";
@@ -67,9 +68,10 @@ export interface IDiscontinuityTimeInfo {
67
68
  * encountered and exited.
68
69
  * @param {object} playbackObserver - emit the current playback conditions.
69
70
  * @param {Object} manifest - The Manifest of the currently-played content.
71
+ * @param {Object} speed - The last speed set by the user
72
+ * @param {Observable} lockedStream$
70
73
  * @param {Observable} discontinuityUpdate$ - Observable emitting encountered
71
74
  * discontinuities for loaded Period and buffer types.
72
- * @param {Function} setCurrentTime
73
75
  * @returns {Observable}
74
76
  */
75
- export default function StallAvoider(playbackObserver: PlaybackObserver, manifest: Manifest | null, lockedStream$: Observable<ILockedStreamEvent>, discontinuityUpdate$: Observable<IDiscontinuityEvent>): Observable<IStalledEvent | IUnstalledEvent | IWarningEvent>;
77
+ export default function StallAvoider(playbackObserver: PlaybackObserver, manifest: Manifest | null, speed: IReadOnlySharedReference<number>, lockedStream$: Observable<ILockedStreamEvent>, discontinuityUpdate$: Observable<IDiscontinuityEvent>): Observable<IStalledEvent | IUnstalledEvent | IWarningEvent>;